Moving ASP.NET roles/membership from Test/Local to Production

ASP.NET roles/membership providers are incredibly simple and convenient, but if you move you site straight to a production environment (SQL Server, etc.), it's probably not going to work without a couple changes

Believe it or not, I had never needed to use ASP.NET roles in any large production environment.  But recently at work, that changed.  Everything was working great on my local machine, couldn't be smoother, but then I moved everything to our web server with a SQL 2005 backend... no worky.

 

When you enable roles in ASP.NET within VS/VWD it automatically makes an MDF that resides in your App_Data folder.  And most likely, your machine is not running full-fledged SQL, just Express.  Which is just fine, but when you migrate to the production environment, even if you bring the MDF with you and place it in your App_Data file, your roles will not work.

 

What VS is forgetting to tell you is that your membership provider is using an 'invisible' ConnectionString called 'LocalSqlServer' and that that connectionString uses SQL Express and Windows credentials to access it.  Which is why, in most cases, that that connectionString will not work in your production setting.  What you need to do is two things:

 

  1. Move your MDF to you production SQL Server instance
  2. Make sure your role provider references that instance by changing the connection string

 

This is very easy to do, and here is how you do it:

Move your MDF to your Production SQL

  1. Copy your ASPNETDB.mdf file from your App_Code folder to Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Data on your SQL machine
  2. Open SQL Server Management Studio and connect to your database
  3. Right click on the 'Databases' folder in the navigation pane, click 'Attach...'
  4. Click the 'Add...' button and navigate to your ASPNETDB.mdf on that machine, click 'OK'
  5. Click 'OK'
  6. You now have it attached and ready to use, I recommend renaming it as the name will be very long (I renamed it simply ASPNETDB.mdf - I'm creative)

Make sure your program references the new database location

  1. Go into your web.config file for your program, locate the connectionStrings section
  2. Add the following 2 lines:
    <remove name="LocalSqlServer"/>
    <add name="LocalSqlServer" connectionString="CONNECTION_STRING_TO_MEMBERSHIP_DB" providerName="System.Data.SqlClient"/>
  3. Upload and you should be all set

The important thing here is that you cleared out the 'invisible' connectionString that .Net uses and replaces it with one that is going to run off of your newly implemented database.

The non-generic type 'System.Collections.IEnumerable' cannot be used with type arguments

This is an error that was driving me crazy while I was trying to get a recursive LINQ call to work; the fix is ridiculously simple and just an oversight

 First you have to understand that IEnumberable has both generic and not-generic usage.  That was my problem.  In my code, I included the using System.Collections; namespace and in my code I was doing the following:

 IEnumerable <test_order> orders = db.getOrdersByCustomer(1);

Where test_order was type produced with a Linq to Sql Class and getOrdersByCustomer was a Stored Procedure. 


I kept getting the error:

The non-generic type 'System.Collections.IEnumerable' cannot be used with type arguments 


Which basically told me my problem, but I was too blind to see it at first.  Since I was just calling the System.Collections.IEnumerable, and not the System.Collections.Generic.IEnumerable, I was not allowing the use of generics; hence the error.  Simple add the following to you code and you will not have this error any longer: 

using System.Collections.Generic;

Ternary operators simplified

For a while there, I would see mystical things happening in some code I viewed, and I had no idea what was happening - turn out the bla?bla:bla does mean something, and it is useful and simple

These?are:called ternary operators, and they can be very useful, especially when you want to clean up your code.  A lot of people say that they are hard to read, but I think that is merely because they do not understand how simple they really are. I will show you just how simple they are; here is a statement using a ternary operator:

 

[code:c#]

a ? b : c ;

[/code]

 

And all this means in simple terms is:

 

[code:c#]

if a is true, then b is the value of the statement, else c is the value of the statement

[/code]

 

or if you prefer code:

 

[code:c#]

if(a)
  return b;
else
  return c;

[/code]

 

That really is it, it is that simple. Ternary operators can save a lot of space, and more important (to me) they can easily be used inline, cutting out chunks of code completely.  Take a look at the following for an example:

[code:c#]

string s1 = "party";
string s2 = "crom";
string s3 = "arnold";
bool b1 = true;
bool b2 = false;
string s4, s5;

//All of this code:
if (b2)
  s4 = s1;
else
  s4 = s2;

if (b1)
  s5 = s1;
else
  s5 = s2;

//can be replaced by this
s4 = b2 ? s1 : s2;
s5 = b1 ? s1 : s2;

//plus you can easily use it inline
Response.Write("inline = " + (b2 ? s2 : s3).ToString());

[/code]


You can make them much deeper and more complicated and then they may begin to get difficult to read, but for a lot of everyday tasks, ternary operators are great and space saving!

 

Intro to Lambda Operators

There has been a lot of buzz about lambda operators, so I decided to check them out; turns out they are pretty useful

Not necessarily epic in thier abilities, but lambdas can be a nice way to clean up code and make your programming better in general (if you use them right).  For a quick show of what they can do, compare this function

public int f1(int x, int y, int z)
{
  return (x + y) * z;
}
to this:
Func f2<int, int, int, int> = (x, y, z) => (x + y) * z;
They do basically the same thing, but the second one is much cleaner. It might seem a bit hard to read, but it isn't if you break it down. Think of it like this:
Function with 4 integers (3 in, 1 out) named f2 equals what you get with the inputs x, y and z which go to (x + y) * z
The key here is the 'go to' meaning those variables go into the following function, which in turn, returns to f2... if that makes sense. This is not just a new way to do functions, you can also use lambdas inline which is where they really shine. There is an awesome post here: http://blogs.msdn.com/.../lambda-lambda-lambda.aspx that shows how to use this in an inline generic list sort which chops 5 lines of code down to just 1... that ay not seem like a lot, but it can relly add up.

This is a very basic intro to Lambda Operators and they can do much more, this is just to get your gears turning.
More info: http://msdn2.microsoft.com/.../bb397687.aspx

Automatically open folders/drives in explorer view

A very simple, yet incredibly useful way to use explorer view by default... why isn't this an option you can simply check?

Not development in any way, but I thought I would share because it helped me so much!  This has bothered me for years, explorer view is about 10x more handy than the standard way XP opens folders.  But there was no way to make it default.  Of course I could right click and choose 'Explore' but that's just too much extra work.  There is a simple way to make this default behavior.

 

open Regedit (start->run regedit) and find

HKEY_CLASSES_ROOT\Folder\shell\open\ddeexec
and modify the value from
[ViewFolder("%l", %I, %S]
to read
[explorefolder("%l", %I, %S]
and you are all set.

'Auto-tabbing' to next TextBox with asp.net and Javascript

If you have a form that limits characters entered into a textfield, using this simple approach you can automatically jump to the next control, making it easy for your user

Say you have a zip code field that takes in 5 numbers, next you have a state dropdown.  Your user should be able to type in the 5 digit zip code, then boom, the focus is automatically shifts to the dropdown.  It is very simple to implement.  It just requires the following JS function:

 

function next(currentControl, maxLength, nextControl)
   {
    if(document.getElementById(currentControl).value.length >= maxLength)
    document.getElementById(nextControl).focus();
  }

 

and then just call this from a textbox in html:

<input id="Text1" onkeyup="next('Text1', '5', 'Text2')" type="text" />

Or if you are using an asp.net TextBox control:

txt1.Attributes.Add("onkeyup", "next('txt1','5','txt2')");

it's just that easy... here is an example using both asp.net and just html:



Simplified ASP.Net User Role Management Interface

Messing around with .net roles recently and I came up with a completely portable, simple user management tool

As most of my stuff is, this is not a revolution in coding, but it is useful.  This is a simple page that allows you to add and delete members from whatever roles you have defined for your asp.net project on your live project, no need for the Web Management tool (you still have to manage roles with it though).  The file is completely independant of any other code, so you don't need to do anything to get it to work, just stick in the same directory as your application and use it - customize it if you please.



Open Source Web Design

Just what you would think, a resource for open source web design...

This is a great resource for when you need a quick template, or just a bump in the old creativity/idea department.



Automated Sharepoint Backups including daily folders and trash collection

SAMS came up with a great SharePoint backup automation tool with their SPSiteBackup.wsf windows script file - it is good, but needed a couple things... so I added them...

The SAMS backup utility is really pretty great.  It runs backups on all of your site collections on a given site as well as as logging the results and emailing the logs to users.  This is very useful, but it is lacking a few features that I felt it needed.

 

First of all, the backup utility put all of the backup files into one directory.  When you have a lot of sites, not to mention if you are backing up MySites, this can become a massive chunk of data.  If you are running this script on any recurring basis, it just turns into a non-decipherable mess of hundreds and hundreds of files, no organization whatosever.  I made a change here that will automatically make folders (named by date) and place the backups in the properly dated folder.

 

Second, there is no garbage collection.  If I ran the script every day, I would eventually choke out all of my storage and be stuck with 100s of GBs of backups.  I could just go in and delete them manually, but no one wants to do that (so 90s).  What if I forget, or go on vacation, or leave Tongue out - so, I made a garbage collection method run within the script as well.

 

All you need to do is place the script file directly on your C: drive, customize the batch file (explanation provided within the .bat file) and schedule it to run (or run it manually) and you are running maintenance-free automatic backups on your SharePoint server/farm.

 

 

 

 

Ok, if you feel ok on your own now, stop reading - if not, read on for a step-by-step tutorial on how to schedule the automated backups on your server...

 

Get the backup script files ready  

  1. Copy the 2 files from the .zip file to the machine you want to run backups on directly to the C: drive
  2. Open spBackup.bat in a text editor, you will see the following:
    cscript c:\spBackupScript.wsf
    /virt:"http://your_sp_site"
    /path:"path_for_backups"
    /smtpserver:"YOUR_SMTP_SERVER"
    /reportto:"send_reports_to@this_email.address"
    /holdfor:"number_of_days_before_backups_are_deleted(integer)"
  3. Change the input variables to what you need them to be (self-explanatory) for that server instance.

 

Now that is set up, you need to schedule the job.

  1. Click Start->Programs->Accessories->System Tools->Scheduled Tasks
  2. Double-click Add Scheduled Task, choose Next
  3. Click Browse... and browse to the .bat file you just edited (C:/spBackup.bat)
  4. Name the task and choose how often to perform the task click Next
  5. Choose the start time click Next
  6. Enter your password click Next
  7. Click Finish

 

It's just that easy, you are now making and cleaning up backups automatically.  Here it is one more time:

 

 

Automated_SP_Backup.zip (3.60 kb)