How to use Office UI Fabric in your Web Applications

The Office UI Fabric framework is a easy to use UI framework that provides you with CSS and JavaScript components allowing you to style your web applications, making them seamlessly integrate with the Office 365 and SharePoint Online user experience.

You can fine out more at on the Office UI Fabric site and you can visit the Office UI JS GitHub site here to find out how to use the JavaScript components.

In my video here I show a quick demo of how to include the components in your own web application.

ASP.Net Core 1.0 RTM – Serving Static Files

If you have been using ASP.Net Core pre RTM release then you might have been using the Microsoft.AspNetCore.StaticFiles dependency to serve up static content from your ASP.Net web application.

If you have been using the latest stable version of this dependency 1.0.0 then you may come across an issue when using the RTM release of ASP.Net Core.

With the RTM release and Update 3 for Visual Studio 2015 we now have a Program.cs with a Main() entry point to our application added to our project when we create a new web application.


public class Program
 {
    public static void Main(string[] args)
    {
        var host = new WebHostBuilder()
           .UseKestrel()
           .UseContentRoot(Directory.GetCurrentDirectory())
           .UseIISIntegration()
           .UseStartup<Startup>()
           .Build();

           host.Run();
    }
 }

As you can see there is a .UseContentRoot extension method that gets called setting the content root of our application to the current directory.

To use static files we still need need to reference the Microsoft.AspNetCore.StaticFiles dependency but we must use the pre-release version 1.0.0-rc2-final or we will get the following error.

Error CS0121 The call is ambiguous between the following methods or properties: ‘Microsoft.AspNetCore.Hosting.WebHostBuilderExtensions.UseContentRoot(Microsoft.AspNetCore.Hosting.IWebHostBuilder, string)’ and ‘Microsoft.AspNetCore.Hosting.HostingAbstractionsWebHostBuilderExtensions.UseContentRoot(Microsoft.AspNetCore.Hosting.IWebHostBuilder, string)’

The reason is that the WebHostBuilderExtensions class that contains the UseContentRoot method has been moved to the Microsoft.AspNetCore.Hosting assembly and if you reference version 1.0.0 and not 1.0.0-rc2-final version of the Microsoft.AspNetCore.StaticFiles assembly then you will get an ambiguous reference between these namespaces.

To setup static file serving correctly with RTM just add a dependency to 1.0.0-rc2-final version of Microsoft.AspNetCore.StaticFiles and then add the following in your Startup.cs.


public void Configure(IApplicationBuilder app)
{
    app.UseStaticFiles();
}

You can see the updated documentation for static files here:

https://docs.asp.net/en/latest/fundamentals/static-files.html

Custom Tag Helpers with ASP.Net Core & MVC 6

I was playing around with the new tag helper functionality in MVC 6 and decided to put together a quick tutorial on how to create custom tag helpers for your own MVC 6 projects.

I was targeting the ASP.Net Core 1.0 framework in this video but it also applies to .Net 4.6 framework with MVC 6.

I was never really a fan of mixing markup and code within Razor views and I believe tag helpers are a much nicer way to separate out code a functionality in your web projects.

CORS Support in WebAPI and XDomainRequest with IE.

The WebAPI framework in the latest release of .Net 4.5 is a great way to easily create HTTP based web services from scratch, it gives you a lot of great features out of the box which allows you to return JSON or XML data back to a client application using Javascript or the server side HttpClient class.

If you would like to know more about WebAPI the head over to the official site to get up to speed with how it works. http://www.asp.net/web-api

One thing that isn’t included with the 4.5 release is the ability to do cross domain calls into your WebAPI services, there is no support for CORS out of the box with the current release. However CORS support is coming with the next release of ASP.Net and can be seen if you browse the ASP.Net source over at codeplex http://aspnetwebstack.codeplex.com/.

If you are reading this and wondering what CORS stands for its Cross-Origin Resource Sharing and it’s a new specification from W3C that aims to standardise the mechanism for cross domain requests by using standard HTTP headers in the request and reponse. You can read more about the specification at the W3C site http://www.w3.org/TR/cors/.

You can also read about CORS support for ASP.Net and WebAPI at this site http://aspnetwebstack.codeplex.com/wikipage?title=CORS%20support%20for%20ASP.NET%20Web%20API.

The problem is that if you want CORS support right now then you have two choices:

  1. Download the full ASP.Net web stack dev branch, compile it and use the 5.0.0.0 assemblies in your application.
  2. Write you own HTTP handler to add support.

The problem with option one is that most people don’t want to build their application on an unstable dev release of the framework. CORS support comes in the form of two new assemblies System.Web.Cors.dll and System.Web.Http.Cors.dll. The later is the assembly that you would use for WebAPI and the former is what you would use for ASP.Net. The problem is that these assemblies are both complied with version 5.0.0.0 of System.Web.dll and System.Web.Http.dll so you can’t just download the code for these assemblies and compile them against version 4.0.0.0 of the relevant assemblies or even grab the 5.0.0.0 version of the dependencies and compile against them. You will get either a compile time or a runtime security exception stating that there is a version mismatch between dependencies.

So bottom line is that unless you are willing to build your application on a dev release you are stuck with creating your own HTTP handler to deal with this. The approach below was taken from this blog post by Carlos Figueira http://code.msdn.microsoft.com/windowsdesktop/Implementing-CORS-support-a677ab5d and shows how you would implement a handler to deal with CORS support.

Creating a HTTP Handler for CORS Support

 public class CorsDelegatingHandler : DelegatingHandler
 {
     protected override Task<HttpResponseMessage> SendAsync(
         HttpRequestMessage request,
         CancellationToken cancellationToken)
     {
         string allowedDomains = WebConfigurationManager.AppSettings["CORSAllowCaller"];
         const string Origin = "Origin";
         const string AccessControlRequestMethod = "Access-Control-Request-Method";
         const string AccessControlRequestHeaders = "Access-Control-Request-Headers";
         const string AccessControlAllowOrigin = "Access-Control-Allow-Origin";
         const string AccessControlAllowMethods = "Access-Control-Allow-Methods";
         const string AccessControlAllowHeaders = "Access-Control-Allow-Headers";

         if (string.IsNullOrEmpty(allowedDomains))
         {
             return base.SendAsync(request, cancellationToken);
         }

         bool isCorsRequest = request.Headers.Contains(Origin);
         bool isPreflightRequest = request.Method == HttpMethod.Options;

         if (isCorsRequest)
         {
             if (isPreflightRequest)
             {
                 return Task.Factory.StartNew(() =>
                 {
                     HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
                     response.Headers.Add(AccessControlAllowOrigin, request.Headers.GetValues(Origin).First());

                     string accessControlRequestMethod =
                     request.Headers.GetValues(AccessControlRequestMethod).FirstOrDefault();

                     if (accessControlRequestMethod != null)
                     {
                         response.Headers.Add(AccessControlAllowMethods, accessControlRequestMethod);
                     }

                     string requestedHeaders = string.Join(", ", request.Headers.GetValues(AccessControlRequestHeaders));

                     if (!string.IsNullOrEmpty(requestedHeaders))
                     {
                         response.Headers.Add(AccessControlAllowHeaders, requestedHeaders);
                     }

                     return response;

                 }, cancellationToken);
             }
             else
             {
                 return base.SendAsync(request, cancellationToken).ContinueWith(t =>
                 {
                     HttpResponseMessage response = t.Result;
                     response.Headers.Add(AccessControlAllowOrigin, request.Headers.GetValues(Origin).First());
                     return response;
                 });
             }
         }
         else
         {
             return base.SendAsync(request, cancellationToken);
         }
     }
 }

The code above essentially looks for an Origin header in the request which indicates that the caller is coming from another domain. The requesting browser will add this header if the originating domain is different to the requested domain. It then adds the relevant CORS headers to the response which tells the browser that this call is allowed by the server. Most browsers support the Origin header using XHTTPRequest object so JQuery AJAX requests work fine, however IE does not add this header when using XHTTPRequest object so you need to use the XDomainRequest object instead which I will show in the next section.

Calling WebAPI from Javascript.

As I said above you will have to use XDomainRequest instead of XHTTPRequest object when making a cross domain request using CORS, otherwise the Origin header does not get added to the request.

You can see below how to achieve this:


if ($.browser.msie && window.XDomainRequest) {

    // Use Microsoft XDR
    var xdr = new XDomainRequest();
    xdr.open("get", this.url);
    xdr.onload = function () {
        bindData(JSON.parse(xdr.responseText), bindingNodeName);
    };
    xdr.send();

} else {

    $.ajax({
        type: "GET",
        url: this.url,
        dataType: "json",
        success: function (data) {
            bindData(data, bindingNodeName);
        }
    });
}

We essentially just need to check whether the browser is IE and supports the XDomainRequest object and if it does go ahead and use that object instead. The only thing to note here is that you will be getting back a string of data instead of the raw data when using XDomainRequest object and you will need to get your data out of the string before you use it. In the case of JSON it’s as easy at using the JSON.Parse helper method to get at your raw JSON object.