Resource Files In ASP.Net MVC

Scott Allen has a great post explaining how resource files work in ASP.Net MVC project using Visual Studio. Technically speaking, this also applies to ASP.Net Web Form.

Basically, there are these problems:

  • Placing resource files in App_GlobalResources folder will break unit tests.
  • Intellisense has trouble recognizing syntax in the Views.
  • App_LocalResources seems to have similar behavior.

The solution is ostensibly simple. Just put resource files in a separate folder, name it anything you want. This will:

  • Embed the resource files in library when the project is compiled.
  • The generated class is internal by default. This is can be changed if you need to share the class publicly.

To change generated class to public, change ‘Custom Tool’ property of the resource file to ‘PublicResXFileCodeGenerator’ instead of ‘ResXCodeFileGenerator’.

Differences Between Session.Clear and Session.Abandon?


  • Doesn’t trigger Session_End in Global.asax.
  • Doesn’t change Session ID.
  • Will remove all keys and objects in stored in the session.


  • Trigger Session_End event Global.asax.
  • Session ID will be disposed, a new one will be assigned.
  • Will remove all keys and objects in stored in the session.

Session State Modes

  • InProc
    Default. Store session in memory of the web server.
  • StateServer
    Store session in ASP.NET state service. Preserved when the web application is restarted. Available across web farm.
  • SQLServer
    Store in a database. Preserved when the web application is restarted. Available across web farm.
  • Custom
    Specify custom storage provider.
  • Off
    Disable session.

More reading on: Session-State Modes

WCF Client Config Template with Identity Delegation (WSTrust)

A minimal config for a client (for example, ASP.NET MVC application, ASP.NET Web Form application, or another WCF service application), that is a relying party to WIF (or any STS), to consume a WCF service (SOAP) using Identity Delegation (with WSTrust protocol). Identity Delegation allows the client to call WCF service and pass in the claims as if it’s being called by the user of the client. Compare Identity Delegation to Trusted Subsystem.

This config is auto-generated with “Add Service Reference” wizard from WCF service config in WCF Config Template for Identity Delegation with WIF.

This config DOES NOT include setting integrating the client with WIF. For example of this, see WIF 3.5 Relying Party Config Template.

Note that:
http://localhost:11000 is the Secure Token Service (STS) URL.
http://localhost:58829 is service’s endpoint address.

<?xml version="1.0" encoding="utf-8" ?>
                <binding name="WS2007FederationHttpBinding_IService">
                            <issuer address="http://localhost:11000/Issue.svc" binding="ws2007HttpBinding"
                                    <dns value="IdentityTKStsCert" />
                            <issuerMetadata address="http://localhost:11000/Issue.svc/mex" />
                                <trust:SecondaryParameters xmlns:trust="">
                                    <trust:KeyType xmlns:trust=""></trust:KeyType>
                                    <trust:KeySize xmlns:trust="">256</trust:KeySize>
                                    <trust:KeyWrapAlgorithm xmlns:trust=""></trust:KeyWrapAlgorithm>
                                    <trust:EncryptWith xmlns:trust=""></trust:EncryptWith>
                                    <trust:SignWith xmlns:trust=""></trust:SignWith>
                                    <trust:CanonicalizationAlgorithm xmlns:trust=""></trust:CanonicalizationAlgorithm>
                                    <trust:EncryptionAlgorithm xmlns:trust=""></trust:EncryptionAlgorithm>
                <binding name="http://localhost:11000/Issue.svc">
                        <message clientCredentialType="Certificate" negotiateServiceCredential="false" />
            <endpoint address="http://localhost:58829/Service.svc" binding="ws2007FederationHttpBinding"
                contract="ServiceReference.IService" name="WS2007FederationHttpBinding_IService">
                    <certificate encodedValue="AwAAAAEAAAAUAAAAQKHSYiv" />

To create ChannelFactory and pass in the secured token from the client:

// Get the token
WSTrustChannelFactory trustChannelFactory = new WSTrustChannelFactory( stsBinding, stsAddress );
WSTrustChannel channel = (WSTrustChannel) trustChannelFactory.CreateChannel();
RequestSecurityToken rst = new RequestSecurityToken(RequestTypes.Issue);
rst.AppliesTo = new EndpointAddress(serviceAddress);
RequestSecurityTokenResponse rstr = null;
SecurityToken token = channel.Issue(rst, out rstr);

// Use the token, pass in to WCF service
IHelloService serviceChannel = channelFactory.CreateChannelWithIssuedToken<IHelloService>( token ); serviceChannel.Hello(“Hi!”);

Additional resource: MSDN WSTrustChannelFactory and WSTrustChannel

WIF 3.5 Relying Party Config Template

This applies to Windows Identity Foundation 3.5 with assumption that relying party is any ASP.NET web application (MVC or Web Form).

For WIF 4.5, use Identity and Access Tool extension for Visual Studio.


<?xml version="1.0" encoding="utf-8"?>
    <!--For WIF 3.5-->
    <section name="microsoft.identityModel" type="Microsoft.IdentityModel.Configuration.MicrosoftIdentityModelSection, Microsoft.IdentityModel, Version=, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />

  <!--For WIF 3.5-->
  <location path="FederationMetadata">
        <allow users="*" />

    <compilation debug="true" targetFramework="4.0">

      <!--For WIF 3.5-->
        <add assembly="Microsoft.IdentityModel, Version=, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />


    <!--For WIF 3.5-->
    <authentication mode="None" />
    <!--The setting below will set whole site to require authentication. If some pages are accessible by public, comment out the 'auhtorization' attribute.-->
      <deny users="?" />
    <!--<authentication mode="Forms">
    <forms loginUrl="~/Account/Login" timeout="2880" />

    <!--For WIF 3.5-->
    <httpRuntime requestValidationType="Acme.Common.Security.WsFederationRequestValidator"/>
    <!--Alternatively, you can also use the following 'httpRuntime' setting. However, this setting post possible security threat on .aspx files with its .Net 2.0 request validation-->
    <!--<httpRuntime requestValidationMode="2.0"/>-->

    <modules runAllManagedModulesForAllRequests="true">

      <!--For WIF 3.5-->
      <remove name="FormsAuthentication"/>
      <add name="WSFederationAuthenticationModule" type="Microsoft.IdentityModel.Web.WSFederationAuthenticationModule, Microsoft.IdentityModel, Version=, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
      <add name="SessionAuthenticationModule" type="Microsoft.IdentityModel.Web.SessionAuthenticationModule, Microsoft.IdentityModel, Version=, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />


  <!--For WIF 3.5-->
    <service saveBootstrapTokens="true">
        <!--Relying party's URL-->
        <add value="http://localhost:55487/" />
        'issuer' is STS URL
        'realm' is Relying party's URL
          <wsFederation passiveRedirectEnabled="true" issuer="http://localhost:10000/" realm="http://localhost:55487/" requireHttps="false" />
          <cookieHandler requireSsl="false" />
        <!--Change 'findValue' attribute with STS certificate thumb print. You can find this by using Microsoft Management Console and view the certificate's Intended Purpose proerpties.-->
        <certificateReference x509FindType="FindByThumbprint" findValue="40A1D97AD786AADFBDAC80A38858AD8001E094547369B" storeLocation="LocalMachine" storeName="My" />
      <issuerNameRegistry type="Microsoft.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, Microsoft.IdentityModel, Version=, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
          <!--Change 'findValue' attribute with STS certificate thumb print. You can find this by using Microsoft Management Console and view the certificate's Intended Purpose proerpties.-->
          <add thumbprint="40A1D97AD786AADFBDAC80A38858AD8001E094547369B" name="CN=AcmeStsCertificate" />
      <!--Specify class you will be using for transforming the claims-->
      <claimsAuthenticationManager type="Acme.Common.Security.ClaimsTransformer"/>


public class ClaimsTransformer : ClaimsAuthenticationManager
    public override IClaimsPrincipal Authenticate(string resourceName, IClaimsPrincipal incomingPrincipal)
        if (!incomingPrincipal.Identity.IsAuthenticated)
            return base.Authenticate(resourceName, incomingPrincipal);

        var _id = incomingPrincipal.Identities.First();
        _id.Claims.Add(new Claim("http://foo", "foo"));
        _id.Claims.Add(new Claim("http://bar", "bar"));

        return incomingPrincipal;


public class WsFederationRequestValidator : RequestValidator
    protected override bool IsValidRequestString(HttpContext context, string value, RequestValidationSource requestValidationSource, string collectionKey, out int validationFailureIndex)
        validationFailureIndex = 0;
        if (requestValidationSource == RequestValidationSource.Form && !String.IsNullOrEmpty(collectionKey) && collectionKey.Equals(WSFederationConstants.Parameters.Result, StringComparison.Ordinal))
            var _unvalidatedFormValues = System.Web.Helpers.Validation.Unvalidated(context.Request).Form;

            SignInResponseMessage _message = WSFederationMessage.CreateFromNameValueCollection(WSFederationMessage.GetBaseUrl(context.Request.Url), _unvalidatedFormValues) as SignInResponseMessage;

            if (_message != null)
return true;

        return base.IsValidRequestString(context, value, requestValidationSource, collectionKey, out validationFailureIndex);

Global.asax Events

Global.asax contains the following events:

  • Application_Init: Fired when an application initializes or is first called. It’s invoked for all HttpApplication object instances.
  • Application_Disposed: Fired just before an application is destroyed. This is the ideal location for cleaning up previously used resources.
  • Application_Error: Fired when an unhandled exception is encountered within the application.
  • Application_Start: Fired when the first instance of the HttpApplication class is created. It allows you to create objects that are accessible by all HttpApplication instances.
  • Application_End: Fired when the last instance of an HttpApplication class is destroyed. It’s fired only once during an application’s lifetime.
  • Application_BeginRequest: Fired when an application request is received. It’s the first event fired for a request, which is often a page request (URL) that a user enters.
  • Application_EndRequest: The last event fired for an application request.
  • Application_PreRequestHandlerExecute: Fired before the ASP.NET page framework begins executing an event handler like a page or Web service.
  • Application_PostRequestHandlerExecute: Fired when the ASP.NET page framework is finished executing an event handler.
  • Applcation_PreSendRequestHeaders: Fired before the ASP.NET page framework sends HTTP headers to a requesting client (browser).
  • Application_PreSendContent: Fired before the ASP.NET page framework sends content to a requesting client (browser).
  • Application_AcquireRequestState: Fired when the ASP.NET page framework gets the current state (Session state) related to the current request.
  • Application_ReleaseRequestState: Fired when the ASP.NET page framework completes execution of all event handlers. This results in all state modules to save their current state data.
  • Application_ResolveRequestCache: Fired when the ASP.NET page framework completes an authorization request. It allows caching modules to serve the request from the cache, thus bypassing handler execution.
  • Application_UpdateRequestCache: Fired when the ASP.NET page framework completes handler execution to allow caching modules to store responses to be used to handle subsequent requests.
  • Application_AuthenticateRequest: Fired when the security module has established the current user’s identity as valid. At this point, the user’s credentials have been validated.
  • Application_AuthorizeRequest: Fired when the security module has verified that a user can access resources.
  • Session_Start: Fired when a new user visits the application Web site.
  • Session_End: Fired when a user’s session times out, ends, or they leave the application Web site.

Following events are triggered one time.

  • Application_Init: Triggered when application is initialized, before it’s started.
  • Application_Start: Triggered when application is started.
  • Session_Start: Triggered when a user enters the site.
  • Session_End: Triggered when a user leaves the site.
  • Application_Disposed: Triggered when application is terminated, before it’s ended.
  • Application_End: Triggered when application is ended.

Events are triggered in the following order (per user’s request):

  • Application_BeginRequest
  • Application_AuthenticateRequest
  • Application_AuthorizeRequest
  • Application_ResolveRequestCache
  • Application_AcquireRequestState
  • Application_PreRequestHandlerExecute
  • Application_PreSendRequestHeaders
  • Application_PreSendRequestContent
  • <<code is executed>>
  • Application_PostRequestHandlerExecute
  • Application_ReleaseRequestState
  • Application_UpdateRequestCache
  • Application_EndRequest

Mode details can be read on Working with ASP.NET Global.asax.

October 1, 2013 Update :

There is also the following Global.asax events:

  • Application_PostAuthenticateRequest

SimpleMembership to Replace ASP.NET Membership Provider

If you have ASP.NET 4.5 installed and new up a new ASP.NET MVC 4 project in Visual Studio, or if you are in Visual Studio 2012, you will see that the AccountController implementation is different than previous version (see this post).

Well, ASP.NET 4.5 comes with new membership provider called SimpleMembership. Among other features, what I like the most about this is its support on OAuth like Facebook, Twitter or Google accounts. In addition to that, you can know define your own User table in database and SimpleMembership will just integrate itself to your table, providing that the User table has UserID and UserName column.

SimpleMembership allows easy integration with social media sites like Facebook or Twitter, particularly ‘log-in-with-Facebook’ feature. As a matter of fact, this feature comes out of the box when you new up ASP.NET MVC 4 project in Visual Studio.

Jon Galloway has the complete coverage on SimpleMembership here: SimpleMembership

And here’s the step to add login-with feature on your new MVC 4 project: OAuth Support for WebForms and MVC