Archive

Posts Tagged ‘ASP.NET MVC’

OWIN and Web Api

November 30, 2014 Leave a comment

In this post I am going to talk about how to get started with WEB API project with OWIN . As usual I am going to start with File > New Project > ASP.NET Web Application > Empty Solution and run the following Powershell command to get all the necessary OWIN packages from nuget.

PM> Install-Package Microsoft.AspNet.WebApi.Owin
PM> Install-Package Microsoft.Owin.Host.SystemWeb
PM> Install-Package Microsoft.Owin.Diagnostics

As you may have noticed the second package is to run OWIN Middleware on IIS but you could easily change that to "OWIN Self host" and spawn the web api on a console application with no dependencies on IIS.

The primary motivation and goals of OWIN specification is to develop web application which are independent of Web Server technology like IIS. Another goal is to move away from the System.Web.dll as it’s a 13-year-old assembly. That time it served it’s purpose as it was designed mainly keeping ASP.NET Web Forms in mind but now has a lot of dead weight when it executes code. We still can’t get away with it but in the ASP.Net vNext it is gone and your web application will run faster and will scale better.

For more information on OWIN please visit the http://owin.org/ website.

Anyways back to OWIN, now we are going to write a start-up class which the OWIN runtime will use it to bootstrap our web application and this is how the start-up code looks like.

Startup.cs

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        app.UseWelcomePage();
    }
}

This is how the OWIN pipeline identifies the startup routine with the above method signature. As you can see it takes an interface IAppBuilder in which you can plug your own middleware and in the above code we are plugging the welcome page middleware component to display the page. This is the pattern which is used in development where you will develop your own middleware and plug that into the app builder.

Now when we run the application we can see the OWIN "Welcome page "running using IIS Express.

Owin Startup Page

In the next step I am going to add a simple Customer Controller as shown below.

CustomerController.cs

public class CustomerController : ApiController
{
    private List<Customer> customers;

    public CustomerController()
    {
        customers = new List<Customer>();
        for (var i = 0; i < 3; i++)
        {
            customers.Add(new Customer
            {
                Id = i,
                FirstName = "First" + i,
                LastName = "Last" + i
            });
        }
    }

    // GET: api/Customer
    public IEnumerable<Customer> Get()
    {
        return customers;
    }

    // GET: api/Customer/5
    public Customer Get(int id)
    {
        return customers.FirstOrDefault(c => c.Id == i);
    }

    // POST: api/Customer
    public void Post(Customer customer)
    {

    }

    // PUT: api/Customer/5
    public void Put(int id)
    {

    }

    // DELETE: api/Customer/5
    public void Delete(int id)
    {
    }
}

So the controller code is done and let’s wire up the controller into the OWIN pipeline by adding the HttpConfiguration to the OWIN start-up class which has the routing configuration.

Here is the complete start-up class code.

Startup.cs

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        var config = new HttpConfiguration();

        config.Routes.MapHttpRoute(
           name: "DefaultApi",
           routeTemplate: "api/{controller}/{id}",
           defaults: new { id = RouteParameter.Optional });

        app.UseWebApi(config);
        app.UseWelcomePage();
    }
}

Lets do some quick tests in order to see if everything is working correctly. I am going to use the POSTMAN extension for Chrome and will execute following GET request.

/api/customer
/api/cutomer/1

and with no surprises here is the result of 2 request.

Customer Web Api with Get

Customer Web Api with Get specific customer

As you can see it is fairly simple to set up OWIN and start using it in a Web api application. Moreover, there are 2 more ways to define the OWIN start-up class. First either you can decorate your with assemblu attribute as shown below

assembly: OwinStartup(typeof(OwinTestingDemo.Startup))]

or you can define it in your web.config as

<appSettings>  
  <add key="owin:appStartup" value="OwinTestingDemo.Startup" />
</appSettings>

The choice of different startup may come handy in case for different environment you may want to run different middleware components.

That’s it for now and in the next post I am going to show how we can simplify testing web api with OWIN.

Securing Web API using Azure Part – 3: Building the solution

Continuing with my Securing Web API series in this post I am going to start setting up the solution in visual studio and start building up the Simple Web Token Library. The idea behind this library is to build a reusable library which can be used with Azure ACS but can easily be extended for any identity provider which provides a simple web token based security.

In the first part we learned how to configure simple web tokens using Azure and in the second part we looked into designing interfaces which gives us a nice separation of concern.

Just to recap…

Securing Web API using Azure Part – 1: Simple Web Tokens (Azure Configuration)

Securing Web API using Azure Part – 2: Designing Interfaces (Web Token Orchestration)

So as usual I will start with File > New > ASP.Net Web Application and then select ASP.NET Web Api as shown below.

File new project web api

and now I am going to add a new class library “SimpleWebTokenLibrary” to the solution and create some folders as shown below.

Solution Structure

The structure is pretty straight forward and most of the interfaces, web token constant class, I have already covered in my previous post. The only interface which I haven’t covered is the ISettings interface which allows me to decouple the dependency on app config or web config. This may seems like a simple thing but it helps a lot when you are doing a lot of testing and don’t have to copy around your app settings into your test project.

ISettings.cs

public interface ISettings
{
    string GetSettings(string key);
}

and the implementation class just acts as a facade to the .net configuration manager class.

public class AppSettingsProvider : ISettings
{
    public string GetSettings(string key)
    {
        return ConfigurationManager.AppSettings[key];
    }
}

Also to avoid passing magic string for config settings key I am going to encapsulate that into a settings name class for better readability of code and reducing the magic string code smell.

SettingNames.cs

public static class SettingNames
{
    public const string ServiceNamespace = "ServiceNamespace";

    public const string IdpHostName = "IdpHostName";

    public const string TrustedTokenPolicyKey = "TrustedTokenPolicyKey";

    public const string TrustedAudience = "TrustedAudience";

    public const string ServiceUserId = "ServiceUserId";

    public const string ServiceUserPassword = "ServiceUserPassword";

    public const string RealmScope = "RealmScope";
}

Now I am going to create another class in the Common folder call ResponseManager which will help generating the appropriate http response messages and the http header based on different scenarios.

ResponseManager.cs

public class ResponseManager
{
    public static Task<HttpResponseMessage> GenerateTaskResponse(
                    string message, 
                    CancellationToken cancellationToken)
    {
        return Task.Factory.StartNew(
                () => new HttpResponseMessage(HttpStatusCode.Unauthorized) 
                { 
                    Content = new StringContent(message) 
                },cancellationToken);
    }
}

And to encapsulate identity provider settings like host name, service namespace, relying application etc. I am going to create the following class.

IdentityProviderSettings.cs

public class IdentityProviderSettings
{
    public IdentityProviderSettings(ISettings settings)
    {
        IdpHostName = settings.GetSettings(SettingNames.IdpHostName);
        ServiceNamespace = settings.GetSettings(SettingNames.ServiceNamespace);
        TrustedAudienceValue = settings.GetSettings(SettingNames.TrustedAudience);
        TrustedSigningKey = settings.GetSettings(SettingNames.TrustedTokenPolicyKey);
    }

    public string TrustedAudienceValue { get; set; }

    public string TrustedSigningKey { get; set; }

    public string IdpHostName { get; set; }

    public string ServiceNamespace { get; set; }

    public string TrustedTokenIssuer
    {
        get
        {
            return string.Format(WebTokenConstant.UrlFormat, 
                                this.ServiceNamespace.ToLowerInvariant(), 
                                this.IdpHostName.ToLowerInvariant());
        }
    }
}

So now we are all done with our basic classes lets look into the WebTokenProvider class whose responsibility is to use the service username and password to build and OAuth request and retrieve a token which contains information like the encrypted token, relying party, identity provider etc.

WebTokenProvider.cs

public class WebTokenProvider : IWebTokenProvider
{
    private readonly ISettings settings;

    public WebTokenProvider(ISettings settings)
    {
        this.settings = settings;
    }

    public string GenerateToken()
    {
        var wrapPassword = settings.GetSettings(SettingNames.ServiceUserPassword);
        var wrapUsername = settings.GetSettings(SettingNames.ServiceUserId);
        var scope = settings.GetSettings(SettingNames.RealmScope);

        var client = new WebClient
        {
            BaseAddress = string.Format(
                            WebTokenConstant.UrlFormat,
                            settings.GetSettings(SettingNames.ServiceNamespace),
                            settings.GetSettings(SettingNames.IdpHostName))
        };

        var values = new NameValueCollection
        {
            { WebTokenConstant.WrapName, wrapUsername },
            { WebTokenConstant.WrapPassword, wrapPassword },
            { WebTokenConstant.WrapScope, scope }
        };

        var responseBytes = client.UploadValues(
                                    WebTokenConstant.WrapVersion09,
                                    WebTokenConstant.Post, values);

        var response = Encoding.UTF8.GetString(responseBytes);

        return HttpUtility.UrlDecode(
            response.Split('&')
            .Single(value => value.StartsWith(
                                    WebTokenConstant.WrapAccessToken,
                                    StringComparison.OrdinalIgnoreCase))
            .Split('=')[1]);
    }
}

The above implementation looks very straight forward and quite neat. As you can see all the extra effort we put around constants and removing magic string code smell paid off and it is quite easy to read and understand.

Now lets look into token validator class.

TokenValidator.cs

public class TokenValidator : ITokenValidator
{
    private readonly string trustedSigningKey;

    private readonly string trustedTokenIssuer;

    private readonly string trustedAudienceValue;

    public TokenValidator(IdentityProviderSettings identityProviderSettings)
    {
        trustedSigningKey = identityProviderSettings.TrustedSigningKey;
        trustedTokenIssuer = identityProviderSettings.TrustedTokenIssuer;
        trustedAudienceValue = identityProviderSettings.TrustedAudienceValue;
    }

    public bool Validate(string token)
    {
        var isExpired = this.IsExpired(token);

        return IsHMACValid(token, Convert.FromBase64String(this.trustedSigningKey))
               && (!this.IsExpired(token)
               && (this.IsIssuerTrusted(token)
               && this.IsAudienceTrusted(token)));
    }

    public Dictionary<string, string> GetNameValues(string token)
    {
        if (string.IsNullOrEmpty(token))
        {
            throw new ArgumentException();
        }

        return token.Split('&').Aggregate(
            new Dictionary<string, string>(),
            (dict, rawNameValue) =>
            {
                if (rawNameValue == string.Empty)
                {
                    return dict;
                }

                var nameValue = rawNameValue.Split('=');

                if (nameValue.Length != 2)
                {
                    throw new ArgumentException(
                                WebTokenConstant.InvalidFormEncoding);
                }

                if (dict.ContainsKey(nameValue[0]))
                {
                    throw new ArgumentException(
                                WebTokenConstant.DuplicateNameValuePair);
                }

                dict.Add(HttpUtility.UrlDecode(
                                        nameValue[0]), 
                                        HttpUtility.UrlDecode(nameValue[1]));
                return dict;
            });
    }

    private static ulong GenerateTimeStamp()
    {
        var ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
        return Convert.ToUInt64(ts.TotalSeconds);
    }

    private bool IsAudienceTrusted(string token)
    {
        var tokenValues = this.GetNameValues(token);

        string audienceValue;

        tokenValues.TryGetValue(
                        WebTokenConstant.AudienceLabel, 
                        out audienceValue);

        return !string.IsNullOrEmpty(audienceValue) && 
                            audienceValue.Equals(
                                this.trustedAudienceValue, 
                                StringComparison.Ordinal);
    }

    private bool IsIssuerTrusted(string token)
    {
        var tokenValues = this.GetNameValues(token);

        string issuerName;

        tokenValues.TryGetValue(WebTokenConstant.IssuerLabel, out issuerName);

        if (string.IsNullOrEmpty(issuerName))
        {
            return false;
        }

        return issuerName.Equals(this.trustedTokenIssuer);
    }

    public static bool IsHMACValid(string swt, byte[] sha256HMACKey)
    {
        var swtWithSignature = swt.Split(new[] { "&" + WebTokenConstant.HmacSha256Label + "=" }, 
                                                    StringSplitOptions.None);

        if (swtWithSignature.Length != 2)
        {
            return false;
        }

        var hmac = new HMACSHA256(sha256HMACKey);

        var locallyGeneratedSignatureInBytes = hmac.ComputeHash(
                                              Encoding.ASCII.GetBytes(swtWithSignature[0]));

        var locallyGeneratedSignature = HttpUtility.UrlEncode(
                                        Convert.ToBase64String(locallyGeneratedSignatureInBytes));

        return locallyGeneratedSignature == swtWithSignature[1];
    }

    private bool IsExpired(string swt)
    {
        try
        {
            var nameValues = this.GetNameValues(swt);
            var expiresOnValue = nameValues[WebTokenConstant.ExpiresLabel];
            var expiresOn = Convert.ToUInt64(expiresOnValue);
            var currentTime = Convert.ToUInt64(GenerateTimeStamp());

            return currentTime > expiresOn;
        }
        catch (KeyNotFoundException)
        {
            throw new ArgumentException();
        }
    }
}

As you can see the above code is an anatomy of simple web tokens and we are parsing the return web token to retrieve information like whether the issuer is trusted or not, whether the encrypted token and the signing key matches or not etc.

Finally the TokenHeaderValidiator class.

TokenHeaderValdiator.cs

public class TokenHeaderValidator : ITokenHeaderValidator
{
    public bool Validate(HttpRequestMessage request, 
                         CancellationToken cancellationToken, 
                         out string headerValue, 
                         out string[] nameValuePair, 
                         out Task<HttpResponseMessage> taskHttpResponseMessage)
    {
        nameValuePair = new string[] { };
        headerValue = request.Headers
                             .GetValues(WebTokenConstant.Authorization)
                             .First();

        if (string.IsNullOrEmpty(headerValue))
        {
            taskHttpResponseMessage = ResponseManager.GenerateTaskResponse(
                                        WebTokenConstant.AuthorizationHeaderIsEmpty, 
                                        cancellationToken);
            return false;
        }

        if (!headerValue.StartsWith(WebTokenConstant.AuthorizationProtocol))
        {
            taskHttpResponseMessage = ResponseManager.GenerateTaskResponse(
                                        WebTokenConstant.InvalidToken, 
                                        cancellationToken);
            return false;
        }

        nameValuePair = headerValue.Substring(WebTokenConstant.AuthorizationProtocol.Length)
                                   .Split(new[] { '=' }, 2);

        if (nameValuePair.Length != 2 || nameValuePair[0] != WebTokenConstant.AccessToken || 
            !nameValuePair[1].StartsWith("\"") || !nameValuePair[1].EndsWith("\""))
        {
            throw new ApplicationException(WebTokenConstant.Unauthorized);
        }

        taskHttpResponseMessage = null;
        return true;
    }
}

The two classes TokenValidator and TokenHeaderValidator will be injected into the TokenValidationHandler class which will sit in the ASP.NET Web API pipeline and will make sure that the token is authentic and everything is right before passing the request to the ApiController. If you are not sure how this all fits together then please have a look at SWT Token Orchestration diagram I provided in the previous post..

I know it’s a lot of code but I hope to complete the solution in my next post. I’ll also upload the whole solution with some test to my skydrive so that it is easy to understand the code and relate the concepts in a more manageable way.

Securing Web API using Azure Part – 1: Simple Web Tokens

May 31, 2014 3 comments

In this post I am going to talk about some of the nuances of securing web API using Azure and in order to keep my post short and sweet I am going to cover how to configure relying party and generating the SWT Token using Azure.

First I went and created a new ASP.NET Web API Project in Visual Studio 2013 and I am going to go my azure management portal to configure this newly created web application as a Relying Party. This configuration of Relying party is similar to my previous post Implementing Single Sign-On using Azure and I highly recommend to read it before you read this one.

Next I am going to add a service identity with username and password and the simple web token will be generated using this identity information for authentication.

Service Identity for the ASP.NET Web API Service

Now we are going add our ASP.NET Web API Service as relying party as shown below.

Configure our ASP.NET Web API as Relying Party.

As you can see above that I am using SWT as the token format and use the Windows Azure Access Control Service as my Identity Provider also we need to create a rule group so we click on “Rule groups” and add a description and save the rule.

Create rule group

Now we are going to map incoming claims to outgoing claims like we did in the previous post, except that instead of an Azure website it is an ASP.NET Web API Service.

Claim Mapping in Rule

As you can see above nothing special here all I am saying is that when an input identifier claims has a value of “ServiceUser” then we want to return “prashant.brall” to action claim value. This is done just for illustration purposes only and in real life application the claim mapping can be assigning a specific API Key per consumer so that this key is sent as part of the SWT token for additional verification purposes.

Now we are going to the “Application Integration” option of the Azure Access Control Service and going to use the OAuth WRAP (Web Resource Authorization Protocol) as shown below.

OAuth Web Resource Authorization Protocol.

Lets put it all together and see the SWT Token live in action and instead of writing a program to test I am going to use Fiddler as I really like to see what is going across the wire at the raw http post level.

Generate SWT Token using Fiddler

and this is how the SWT Token looks like when I open in notepad.

Returned SWT Token from Azure ACS

As you can see I have highlighted the return claim value as “prashant.brall” and some returned encrypted token which we will cover in the next post. Also below is raw http post using Fiddler in case you want to use in your own Access Control Service.

POST https://prashantbrall.accesscontrol.windows.net/WRAPv0.9/ HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Host: prashantbrall.accesscontrol.windows.net
Content-Length: 95
Expect: 100-continue
Connection: Keep-Alive

wrap_name=ServiceUser&wrap_password=*********&wrap_scope=http%3a%2f%2flocalhost%3a51388%2f

Implementing Single Sign-On (SSO) using Azure

April 27, 2014 3 comments

In this post I am going to show you how you can secure On-Premises or Cloud based web application using Windows Azure Active Directory which provides identity and access management capability in the cloud.And depending on your requirements you may have various On-Premises or Cloud Federation Identity Management scenarios and it is hard to cover all of them,but hopefully this post will give you some insight into the cloud based identity management and may be useful for your projects.

Before we deep dive into it I assume you have some idea of this type of identity management and are familiar with terms like Identity Provider, Relying Party, Windows Identity Foundation, WS-Federation and the orchestration behind such authentication process. If you are new to this topic and need a bit of background then I highly recommend reading the book Programming Windows Identity Foundation.

Lets browse to the Azure Management Portal and start configuring Windows Azure Active Directory (WAAD) by clicking New > App Service > Active Directory > Access Control > Quick Create and I am going to create a new namespace as shown below.

Access Control Namespace

Once the namespace is created click on "Manage" so that we can configure and administrate Identity Providers, Relying party, Federation Metadata Endpoint etc.

Manage Access Control namespace

Lets take a quick look into various options in Azure ACS and the first thing you will notice is that by default there are three major Identity Providers i.e. Microsoft, Google and Yahoo and if you like you can easily add Facebook or any WS-Federation based Identity Provider like your own Active Directory Federation Server.

List of Identity Providers

Additional Identity Providers such as Facebook or any WS-Federation Identity Provider

Last October I posted about creating a simple website using ASP.NET MVC and deploying it into Azure. I am going to use the same website and secure the website using Windows Azure ACS. If you haven’t read that post I recommend you to have a look so that you would know how to publish your website to Windows Azure.

First thing we are going to do is to add our website as relying party, which means that this website relies on the Windows Azure ACS to manage and authenticate user and the website doesn’t do the identity management and authentication on its own.

Add local website as relying party.

As you can see from the above screenshot I have just added my local IIS website as relying party, the realm and the return URL, this is just the configuration and the actual website will be created in Visual Studio later.

Add relying party additional information.

As you can see in above screenshot there is nothing special going on, we can see all the three providers for this relying party and we can see "Create new rule group" automatically selected. At this moment we will just click "Save" and will tackle the rule group next.

In the "rule group" we are going to specify how input claims in Windows Azure ACS are transformed into output claims so that our application can read these claims and work out additional task based on the user claims.

Generally all the incoming claims will map straight to out going claims and you don’t have to do anything special but I am just showing what can be done through configuration.

Edit rule group for HIIT system

On this "Edit rule group" page we will click on "Generate" and it will populated some rules as shown below.

Automatically generated claim rules

Now I am going to add one more rule and the reason behind this rule is that as part of Microsoft Live Id provider it only returns the nameidentifier claim value and doesn’t return a username due to security reasons. Where as providers like Google and Yahoo do provide the claim value name with user’s first name, last name as well as the email address. Anyways we need to fix this as
WIF manages behind the scenes orchestration of authentication and mapping claim principal to ASP.NET User principal.

If the claim name is blank and as part of the post authentication process when WIF tries to map the name to the User.Identity.Name we are going to get an exception and hence I am mapping the name identifier to the name claim value.

The above fix is done just for this end to end demonstration and in a real life application you have to take nameidentifier claim from Microsoft and use Windows Live Id APIs to get username and map it to the name claim programmatically.

generate rules mapping for windows live id.

and here is the final output with our custom rule for windows live id.

final rule group output with custom name mapping for windows live id.

Before we jump into programming last thing we have to do is to go to the "Application Integration" page and get the WS-Federation Metadata endpoint as shown below. We will copy this URL as we will need this endpoint when we configure the identity management for our application.

WS Federatiom metadata endpoint

Lots of configuration and looks a bit complicated but once you have grasp the concept it is quite straight forward. Lets start with File > New Project > Web Application > ASP.MVC and click on the "Change Authentication" button and a new dialog window will pop-up as shown below.

setup federation metadata in visual studio

Select "Organizational Account", choose the On-Premises options from the drop down and provide the federation metadata endpoint we copied in the above step.

After this configuration you can see there are some additional assembly and bunch of configuration added to the web.config. The one which stands out is a whole new section for system.identityModel which has all the WS-Federated related information.

Also you can see there are two new HTTP module added to the config and they are WSFederationAuthenticationModule and SessionAuthenticationModule which are part of the System.IdentityModel.Services assembly and sits under the ASP.Net pipeline.

Next thing we will do is to set the website to run with local IIS server as shown below.

Set to use local IIS

Lets browse to the website and you will see it will redirect to the federation login page and present you with which identity providers you wish to log in.

Federated Login page

I am going to choose yahoo as my identity provider and it will take me to the yahoo log in page.

Yahoo log in page

So I enter my credential and can see it is all good and it redirects back to my website but when the redirect completes we get this following error.

Server Error in ‘/HIIT’ Application.


ID3206: A SignInResponse message may only redirect within the current web application: ‘/HIIT’ is not allowed.

WIF known exception

This is a well-known issue with WIF and it is a very easy fix, all we have to do is to append a ‘/’ to the returned URL and here is the code.

Global.asax.cs

public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
    }

    private void Application_BeginRequest(object sender, EventArgs e)
    {
        if (string.Compare(Request.Path, Request.ApplicationPath, 
            StringComparison.InvariantCultureIgnoreCase) == 0
            && !Request.Path.EndsWith("/"))
        {
            Response.Redirect(Request.Path + "/");
        }
    }
}

And this time now when I log in it takes me back to home page without any exceptions and you can see the username on the top right hand corner.

HIIT system - logged in page

Lets look a bit deep into the whole WIF behind the scenes orchestration through fiddler. When I browse to the website the WSFederationAuthenticationModule kicks in and it does a 302 i.e. http redirect to the access control service as shown below.

Fiddler browse to the website

From here based on the identity provider I choose it takes me to their login page and if it is all good then it uses the return url to do another post authentication redirect.

Fiddler post authentication redirect

Of course this is just the tip of the iceberg and there is a lot going on under the cover, specially with WIF and the ASP.NET pipeline.

If you are interested in playing around with this project the source code is available at http://1drv.ms/1lR5uqb. Unzip the file, run Visual Studio as Administrator and on project properties under Web click "Create Virtual Directory".

The live version of the demo is available at https://prashantbrall.azurewebsites.net/

Enjoy !!!

Have a toast with toastr.js

February 28, 2014 2 comments

In this post I am going to talk about a very simple notification jQuery plugin call toastr and I believe not many people have heard about it.

It is relatively simple to use and I often use it as debugging tool when I am writing JQuery plugin or trolling through JavaScript code.

Lets get started with a new ASP.NET MVC project and nuget the package with the following command.

PM> Install-Package toastr

 

The nuget package will add the css and the JavaScript file to the Asp.Net MVC project and we need to wire up the toastr.css and the toastr.js in our bundle config as shown below.

BundleConfig.cs

public class BundleConfig
{
    public static void RegisterBundles(BundleCollection bundles)
    {
        bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
                    "~/Scripts/jquery-{version}.js"));

        bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
                    "~/Scripts/jquery.validate*"));

        bundles.Add(new ScriptBundle("~/bundles/modernizr").Include(
                    "~/Scripts/modernizr-*"));

        bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include(
                  "~/Scripts/bootstrap.js","~/Scripts/toastr.js",
                  "~/Scripts/respond.js"));

        bundles.Add(new StyleBundle("~/Content/css").Include(
                  "~/Content/bootstrap.css","~/Content/toastr.css",
                  "~/Content/site.css"));
    }
}

Now I’m going to create a simple page with 4 buttons showing characteristics of toastr notification functionality.

Index.cshtml

    <div class="jumbotron">
        <div class="row">
            <div class="col-md-3">
                <h3>Toastr Success</h3>
                <p><a id="toastr-success" class="btn btn-success">Success</a></p>
            </div>
            <div class="col-md-3">
                <h3>Toastr Information</h3>
                <p><a id="toastr-info" class="btn btn-info">Information</a></p>
            </div>
            <div class="col-md-3">
                <h3>Toastr Warning</h3>
                <p><a id="toastr-warning" class="btn btn-warning ">Warning</a></p>
            </div>
            <div class="col-md-3">
                <h3>Toastr Error</h3>
                <p><a id="toastr-error" class="btn btn-danger">Error</a></p>
            </div>
        </div>

In the below JavaScript code I am setting some of the toastr option like the position of the popup and wiring up the button click to the toastr notification function.

<script type="text/javascript">
    $(document).ready(function () {
        toastr.options = {
            "closeButton": true,
            "positionClass": "toast-bottom-full-width",
            "onclick": null,
            "showDuration": "0",
            "hideDuration": "0",
            "timeOut": "0",
            "showMethod": "fadeIn"
        };
        $('#toastr-success').click(function () {
            toastr.success('This is a success notification from toastr.')
        });

        $('#toastr-info').click(function () {
            toastr.info('This is an information notification provided by toastr.')
        });

        $('#toastr-warning').click(function () {
            toastr.warning('This is a warning notification provided by toastr.')
        });

        $('#toastr-error').click(function () {
            toastr.error('This is an error notification provided by toastr.')
        });
    });
</script>

The JavaScript code is pretty straight forward and there are other options you can set such as whether a user interaction is required or not on the pop-up, do you need to call another function as part of post processing etc.

And here is the final page in action and for demonstration purpose I have taken the screenshot of all the notification in one page.

Have a toast with toastr

and here is what it would look like in a mobile device.

Have a toast with toastr - Mobile View

Happy toasting !!!

Getting started with Azure and Visual Studio 2013

October 13, 2013 7 comments

In this post I am going to talk about how to get started with Windows Azure using Visual studio 2013 RC1 and hope to share some cool stuff of Windows Azure Cloud Services.

First step you have to do before you can start using the Azure Cloud Services is to register your windows live account with Azure Portal. Once you have registered yourself log in using this account into the Windows Management Portal.

Next thing we need to do is to create a website and I am going to create a website name prashantbrall.azurewebsites.net as shown below.

Now the website is ready and let’s have a quick look at the empty website.

Nothing special a simple empty website template.Now in order to get profile of this published website go to the dashboard page of the Azure Management Portal and download the publish profile.

Lets save this profile setting file locally and start with File > New Project in Visual Studio 2013.

The first thing you will notice is that all the different web application types are gone and this is what the One ASP.Net looks like. This also means that there is no differentiation between ASP.NET webforms ,ASP.NET MVC and it won’t sound horrible if you want to build hybrid web application i.e. ASP.NET webform and MVC in the same application.

Lets go ahead create a new web application and I’ll use the MVC template.

Now my solution is set and in order to publish this site on azure I need to import the profile which I download from the dashboard page.Right click on the project and click Publish> Import as shown below.

With this the profile is now imported and all the deployment information is in my solution. Just click “Publish” and the web publishing wizard will work out what are the difference between this deployment and the previous one. Since this is our first deployment it will have all the assemblies and dependencies in the deployment package.

As you can see the deployment has started and the cloud address where it is trying to deploy the package.

Lets make some changes to the content of the sample website and layout and redeploy the package and as I do that the wizard will work out the delta changes to my deployment and shows the differences.

This is pretty cool as you can see it even tells me which view I have changed since the last build.

 

And now my website is up and running and can be viewed at here.

Last thing I wanted to mention is that when I created a new website in Visual Studio 2013 it uses the Twitter BootStrap layout and CSS design for the website which gives a very nice look and has a very nice responsive design.If we view my website on Responsinator it shows how responsive and mobile friendly my website is and how it hides some menu items for mobile friendly look.

Happy Azurring !!!!

Using Output Cache Profile in ASP.NET MVC

September 29, 2013 2 comments

Caching is a quintessential part of any web application, as it improves the performance and load on the web server. The simplest way to add caching to your ASP.NET MVC application is to decorate your action method with the Output Attribute as following :-

 

[OutputCache(Duration=60,VaryByParam="none")]
public ActionResult Index()
{
    var employees = db.Employees;
    return View(employees.ToList());
}

However it is not a good practice to hard code such parameter values and specially when you have to apply different values for different set of caching. For example 60 second for long, 30 seconds for medium and 10 seconds for short caching.First problem with this approach is that you have to be very careful where you are making these changes and second problem is that for some reason if you have to change these values then you have to do search and replace, which is a very bad thing and totally against the DRY ( Don’t Repeat Yourself ) principle.

So overall it is a good practice to use the output cache profile and lets see how we can declare it in our web.config file.

Web.config

<caching>
   <outputCacheSettings>
     <outputCacheProfiles>
       <add name="Long" duration="60" varyByParam="none"/>
       <add name="Medium" duration="60" varyByParam="none"/>
       <add name="Short" duration="10" varyByParam="none"/>
     </outputCacheProfiles>
   </outputCacheSettings>      
 </caching>

And here is how we use the cache profile in our action method.

[OutputCache(CacheProfile="Long")]
public ActionResult Index()
{
    var employees = db.Employees;
    return View(employees.ToList());
}

 

This is very straight forward and nothing unusual but whats the point of blogging about something which hasn’t got any gotchas. And the gotcha is that you can’t use the cache profile on a child action and MVC will through this strange exception “Duration must be positive number.”

 

The above exception is actually misleading and basically output cache profile are not supporting for child action, partial views etc,however the fix for this problem is very easy and all we have to do is just extend the OutputCacheAttribute class. So we will write our own Partial cache attribute class .

PartialCacheAttribute.cs

   1:  public class PartialCacheAttribute : OutputCacheAttribute
   2:  {
   3:      public PartialCacheAttribute(string cacheProfileName)
   4:      {
   5:          var cacheSection = (OutputCacheSettingsSection)WebConfigurationManager
   6:                              .GetSection("system.web/caching/outputCacheSettings");
   7:   
   8:          var cacheProfile = cacheSection.OutputCacheProfiles[cacheProfileName];
   9:   
  10:          Duration = cacheProfile.Duration;
  11:          VaryByParam = cacheProfile.VaryByParam;
  12:      }   
  13:  }

 

As you can see nothing special we are using the GetSection method of WebConfigurationManager class and from that section we are getting the cache profile by its name at line 8. Now our child action method is all set to be decorated with this custom attribute and this is how the action method looks like :-

[ChildActionOnly]
[PartialCache("Short")]
public string GetEmployeesCount()
{
    return db.Employees.Count().ToString();
}

 

This was an issue with MVC 3 and still it’s an issue with MVC 4, but I hope this will get fixed in in MVC 5 😉