Change username in ASP.NET Membership Provider

Found a great article here about the process of changing the username with the ASP.NET Membership Provider.

Here is a summary of the process that I found best useful which is one of the comments:

1. Make sure New UserName is Unique

2. Update the aspnet_Users table directly

3. Execute to following code to change the username/cookie/identity without leaving the webpage…

‘ Obtains the name of the FormsAuthentication Cookie, uses that name to request the Cookie and Decrypts the Cookies information into a AuthTicket

Dim AuthTicket As FormsAuthenticationTicket = FormsAuthentication.Decrypt(HttpContext.Current.Request.Cookies(FormsAuthentication.FormsCookieName).Value)

‘ Instantiates a new user identity authenticated using forms authentication based on the FormsAuthenticationTicket.

‘ The FormsAuthenticationTicket has been created using the exact same parameters of the user with the Old Username except the Old Username has been updated with the New Username.

Dim NewFormsIdentity As New FormsIdentity(New FormsAuthenticationTicket(AuthTicket.Version, NewUsername, AuthTicket.IssueDate, AuthTicket.Expiration, AuthTicket.IsPersistent, AuthTicket.UserData))

‘ Parse out the AuthTicket’s UserData into a string array of Roles

Dim Roles As String() = AuthTicket.UserData.Split(“|”.ToCharArray)

‘ Creates a new user that has the NewFormsIdentity and belongs to the array of Roles, if any, that was stored in the FormsAuthenticationTicket

Dim NewGenericPrincipal As New System.Security.Principal.GenericPrincipal(NewFormsIdentity, Roles)

‘ Sets the security information for the current HTTP request to the new user. The Username has now been changed (i.e. HttpContext.Current.User.Identity.Name = NewUsername, prior to this step is was the OldUsername)

HttpContext.Current.User = NewGenericPrincipal

‘ Removes the forms-authentication ticket from the browser

FormsAuthentication.SignOut()

‘ Cancels the current session

HttpContext.Current.Session.Abandon()

‘ Creates an authentication ticket for the supplied New Username and adds it to the cookies collection of the response or the URL

FormsAuthentication.SetAuthCookie(HttpContext.Current.User.Identity.Name, AuthTicket.IsPersistent)

4. Response.Redirect back to the same page if needed.

References:

http://omaralzabir.com/how_to_change_user_name_in_asp_net_2_0_membership_provider/

A way around page refreshes/back button problems with a simple concept

The problem:

You have a form in which the user fills out and clicks a “submit” button that validates their input, does some processing and output’s some results. The problem being the application needs to cater for page refreshes, back buttons and the case of the page being submitted more than once (latency/slow internet connection).

The Solution:

Possible solutions can be (this assumes not using Ajax as a solution), once the user clicks the submit button the server validates the user’s input and has processed the information. Store a unique id in session and redirect to a “complete” page. If the user clicks the back button and resubmits the page, you can build logic to check if a unique id exists in session and if it does, redirect to the complete page without having to re-process the information.

If the user is on the complete page and refreshes the page, because its on a page which has used a GET, there is no processing done and hence no duplication of data.

References:

http://en.wikipedia.org/wiki/Post/Redirect/Get

http://stackoverflow.com/questions/665399/how-do-i-stop-the-back-and-refresh-buttons-from-resubmitting-my-form

DateTime.ToString()

Here is a link that is useful as a reference for DateTime.ToString patterns

References:

http://www.geekzilla.co.uk/View00FF7904-B510-468C-A2C8-F859AA20581F.htm

A CMS that integrates into ASP.NET MVC

Here is a open source CMS called N2 that provides a CMS framework to build web applications on using the ASP.NET MVC Model.   Its a very basic CMS, but it provides all the core functionality including Pages, Articles and a .NET Permissions Model (it also has some add ons and allows developers to contribute their own add ons).   They have lots of documentation and useful examples on how to work the CMS with MVC.   Very cool stuff!

References:

http://n2cms.com

Using the HttpWebRequest class

In this particular scenario I had to initiate a request from another website in code and track its response to be modified and rendered back to the user.

I had a series of LinkButton html controls on the web form that consume one event.

<asp:LinkButton id=”link1” runat=”server” onClick=”genericEvent”></asp:LinkButton>

When the user clicks on a particular button, ASP.Net invoked the genericEvent event

Protected void genericEvent(object sender, EventArgs e)
{
LinkButton thisLink = (LinkButton)sender;
}

I have a Dictionary object that holds the ID of the LinkButton and a URL value

Dictionary<String,String> Dict = new Dictionary<String,String>();
Dict.Add(“ID”,http://www.google.co.nz);

I created a helper method that initates the HttpWebRequest class to return a response based on the Dictionary ID and URL chosen from the user using the LinkButton.ID property.

Private void GetResponse(String ID)
{
HttpWebRequest newRequest = (HttpWebRequest)WebRequest.Create(DicLinks[ID]);
WebResponse newResponse = newRequest.GetResponse();
newResponse.Close();
}

Protected void genericEvent(object sender, EventArgs e)
{
LinkButton thisLink = (LinkButton)sender;
GetResponse(thisLink.ID);
}

This proved very useful in the scenario of getting various types of information from different sources that can be manipulated and rendered into one view for the user.

References:

http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.aspx

Using ASP.NET MVC on IIS6 or below

When you are building a web applicatio using the ASP.NET MVC framework on IIS7, it URL routing works smoothly and without any dramas.   But when it comes to IIS6 you have to make a comprimse especially if you are developing web apps within a shared hosting envoirnment.   I found the easist way is to change the URL routing table within the Global.asax file.

Origional file:

1
public class GlobalApplication : System.Web.HttpApplication
1
 {
1
 public static void RegisterRoutes(RouteCollection routes)           {                routes.IgnoreRoute("{resource}.axd/{*pathInfo}");                routes.MapRoute(                     "Default",// Route name                     "{controller}/{action}/{id}",// URL with parameters                     new { controller = "Home", action = "Index", id = "" }                           // Parameter defaults                );
1
 }
1
 protected void Application_Start()
1
 {
1
 RegisterRoutes(RouteTable.Routes);
1
 }
1
 }

Change to the following:

1
public class GlobalApplication : System.Web.HttpApplication
1
 {
1
 public static void RegisterRoutes(RouteCollection routes)           {                routes.IgnoreRoute("{resource}.axd/{*pathInfo}");                routes.MapRoute(                     "Default",// Route name                     "{controller}.aspx/{action}/{id}",// URL with parameters                     new { controller = "Home", action = "Index", id = "" }                           // Parameter defaults                );
1
 }
1
 protected void Application_Start()
1
 {
1
 RegisterRoutes(RouteTable.Routes);
1
 }
1
 }

Just add the .aspx extension so that it registers through the .NET Framework.

ALSO remember to do a Response.Redirect in the default.aspx page so that the first page will be your default URL routing page, otherwise you will receive a HttpException “The incoming request does not match any route.”.

W3C Validation and ASP.NET ViewState

The problem

I came across a very interesting point about validating XHTML pages using W3C XHTML Strict and ViewState.   By default ASP.NET ViewState adds a number of hidden fields to handle the postback of ASP.NET pages, control state and control event validation.  See example below.

<input type=”hidden” name=”__VIEWSTATE” id=”__VIEWSTATE” value=””  />

When validating web pages using the XHTML strict option, you will find that the above line is invalid:

value of attribute “ID” invalid: “_” cannot start a name .
…type=”hidden” name=”__VIEWSTATE” id=”__VIEWSTATE” value=”/wEPDwUJOTkzNjk4NjQ4

This becomes a major issue when you have clients who expect their product to be compliant with todays web standards.

The solution

Step 1 - I created a FilterModule that inherits the IHttpModule interface which will be the basis of renaming the __VIEWSTATE to VIEWSTATE.

using System;
using System.Web;

namespace Company.Utilities
{
public class IdFilterModule : IHttpModule
{
public void Dispose()
{
}
public void Init(HttpApplication app)
{
app.ReleaseRequestState += new EventHandler(InstallResponseFilter);
}
private void InstallResponseFilter(object sender, EventArgs e)
{
HttpResponse response = HttpContext.Current.Response;

if (response.ContentType == “text/html”)
{
response.Filter = new IdFilter(response.Filter);
}
}
}
}

The above code creates a event handler called InstallResponseFilter that gets fired when the ReleaseRequestState event is raised.   The ReleaseRequestState event saves all the current state data.

Step 2 - I then create a class inheriting from the Stream class that takes the current state data and does a simple search and replace on the key ViewState identifiers and adjusts the output to be what we decide is valid XHTML.

public class IdFilter : Stream
{
Stream responseStream;
StringBuilder responseHtml;
long position;

public IdFilter(Stream inputStream)
{
responseStream = inputStream;
responseHtml = new StringBuilder();
}

public override bool CanRead
{
get
{
return true;
}
}
public override bool CanSeek
{
get
{
return true;
}
}
public override bool CanWrite
{
get
{
return true;
}
}
public override void Close()
{
responseStream.Close();
}
public override void Flush()
{
responseStream.Flush();
}
public override long Length
{
get
{
return 0;
}
}
public override long Position
{
get
{
return position;
}
set
{
position = value;
}
}
public override long Seek(long offset, SeekOrigin origin)
{
return responseStream.Seek(offset, origin);
}
public override void SetLength(long length)
{
responseStream.SetLength(length);
}
public override int Read(byte[] buffer, int offset, int count)
{
return responseStream.Read(buffer, offset, count);
}
public override void Write(byte[] buffer, int offset, int count)
{
string strBuffer = System.Text.UTF8Encoding.UTF8.GetString(buffer, offset, count);

Regex eof = new Regex(“</html>”, RegexOptions.IgnoreCase);

if (!eof.IsMatch(strBuffer))
{
responseHtml.Append(strBuffer);
}
else
{
responseHtml.Append(strBuffer);

string finalHtml = responseHtml.ToString();

finalHtml = finalHtml.Replace(“id=\”__VIEWSTATE\””, “id=\”VIEWSTATE\””);
finalHtml = finalHtml.Replace(“id=\”__EVENTARGUMENT\””, “id=\”\”EVENTARGUMENT”);
finalHtml = finalHtml.Replace(“id=\”\”__EVENTTARGET”, “id=\”\”EVENTTARGET”);
finalHtml = finalHtml.Replace(”  />”, “>”);
finalHtml = finalHtml.Replace(” />”, “>”);
finalHtml = finalHtml.Replace(“/>”, “>”);

byte[] data = System.Text.UTF8Encoding.UTF8.GetBytes(finalHtml);

responseStream.Write(data, 0, data.Length);
}
}
}

The new IdFilterModule gets registered is the web.config file under httpModules.

References:

http://forum.umbraco.org/yaf_postst5965_W3C-Validation-ASPNET-ViewState-and-HTML-401.aspx

http://msdn.microsoft.com/en-us/library/system.web.httpapplication.releaserequeststate.aspx

Creating a generic list of anonymous types

Scenerio

I have a simple HTML form on a ASP.NET Web page. This form is to post a number of values including several elements that are compulsory to perform several actions on the server. As we know, when we post values to ASP.NET these are available for Request.Form. All we know is the key and value in the NameValueCollection object. I want to be able to check if several values are present and if they are not, return the respective element meta-description rather than the original name.

For Example If we post a name field called formName, we want to return “You must enter data into the fields: Form Name”.

Solution

I used a generic list of a anonymous type. My anonymous type has a Name and a Value property.

var nameValueInstance = new { Name=”formName”,Value=”Form Name”}

I created a list factory that pases in a array of generic type interfaces and returns a generic list of the generic type interface.

private static List<T> MakeList<T>(params T[] items)

{

List<T> newList = new List<T>(items);

return newList;

}

I was then able to do the following to create a generic list of anonymous types:

var fields = MakeList(new { Name = “price”, Value = “Price” }, new { Name = “productname”, Value = “Product Name” });

From here I was able to interate through the list and validate the Form elements and return the nessessary output.

References:

http://kirillosenkov.blogspot.com/2008/01/how-to-create-generic-list-of-anonymous.html

ASP.NET Server Controls using XML/XSL

Scenario

I have developed a framework that allows me to have multiple XSL templates transformed onto an ASP.NET web form. This works well without any ASP.Net server controls on the XSL templates. The question I wanted answered is how to have ASP.NET server controls on a XSL template so that I can dynamically create controls from XML files.

Solution

I found a great article from John Chapman (see below) that explains this in detail.By applying xmlns:asp=”remove” to the element, this tells the parser to apply the format to each server control. i.e. .All is needed now is to do the transformation, remove the namespace from the outputted code and parse the controls to the web form. This also means that event handlers need to be dynamically added if the control is being dynamically created!

Its worth checking out the article below for a better explanation!

References:

John Chapman – Creating Dynamic ASP.Net Server Controls Using XML
http://www.dnzone.com/showDetail.asp?TypeId=2&NewsId=151&LinkFile=page3.htm