1/27/13

Cross Domain Support With Web API


As we know, cross-site HTTP requests from scripts are restricted due to security reasons.  Basically, if our web application runs on a domain (myapp.com), and we try to make a web service call via AJAX to a different domain (myservice.com), we get a cross domain error (not allowed). In the world of Web API and web services in general, we have the need to support cross domain requests because we may be building a service layer with the purpose to be consumed by multiple web applications with different domains.

This need has been identified by the WebApps Working Group which is part of the W3C, and the Cross-Origin Resource Sharing (CORS) recommendation was made. This allows us to enable web services to support cross-site HTTP requests.

A way to address this for Web API is to create a delegating handler that can authorize the request from different domains. Lucky for us, there is already a NuGet package that can be installed on our project. To install it, we can just enter the following on the Package Manager Console:

PM> Install-Package Thinktecture.IdentityModel

Once this handler is installed, we just need to register the CORS support in our global.asax Application_Start event handler. This can be done with the following snippet:

using Thinktecture.IdentityModel.Http.Cors.WebApi;

protected void Application_Start()
{
...
CrossOriginResourceSharing(GlobalConfiguration.Configuration);
}


void CrossOriginResourceSharing(HttpConfiguration httpConfig)
{
       string origin = "CrossDomainUrl"; 
       if (!String.IsNullOrWhiteSpace(origin))
       {
           var corsConfig = new WebApiCorsConfiguration();
           corsConfig.RegisterGlobal(httpConfig);   
           corsConfig.ForOrigins(origin).AllowAll();
       }
}

 In this code, we are just setting one single domain in the ForOrigins method, but there is support for multiple domains. We are also allowing cross domain access for all the resources, but if we need to allow access to only one resource/controller, we can use this method instead:

corsConfig.ForResources("Controller1").ForOrigins(origin).AllowAll();

If we need to control the methods (GET/POST), we can also use the following:

corsConfig.ForOrigins(origin).AllowMethods("GET").AllowAll();

One more thing to note is that this library also supports ASP.NET MVC and Web Forms application. For those web applications, the implementation is done with an HTTP module, so in addition to registering the CORS support, we also need to add the Module setting in the web.config file.

I hope this article is able to give you some understanding on how to address Cross-Domain access for Web API services. There is more information to learn about this library, so I advise to read more about it and learn all the capabilities that are available.

Web API Serialize ENUM Types as String


By default, Web API serializes ENUM data types to the numeric value. For some applications, it would be better to use the string representation instead of the number. An example would be when using  a JavaScript template framework which prevents the need to add implementation code to map the numbers to labels. But before we go crazy and start changing all the model definitions, we should know that there is a way to handle this at the application level.

To address this, we need to add a Media Type Formatter. In Web API, the media type determines how to serialize the data with a built-in support for JSON, XML and form-urlencoded.

The following helper method handles the configuration of the media formatter setting. This code should be added in the global.asax.cs file.

using Newtonsoft.Json;

protected void Application_Start()
{
   SerializeSettings(GlobalConfiguration.Configuration);
                
}


void SerializeSettings(HttpConfiguration config)
{
   JsonSerializerSettings jsonSetting = new JsonSerializerSettings();
   jsonSetting.Converters.Add(new Converters.StringEnumConverter());
   config.Formatters.JsonFormatter.SerializerSettings = jsonSetting;
}

The json serializer setting is configured with a converter which handles the serialization of ENUMs to strings (StringEnumConverter). This setting is then added to the application media formatter collection. This setting is then applied to any of the serialization that takes places during an API call, and the ENUM values should now reflect the string value instead of the number.

We can test this by using a developer's tool like fiddler and look at the JSON raw data that comes back from a WEB API request.

1/5/13

Copy Office 365 files to Local Disk


So we are done building your Office 365 website, and we would like to save a copy of the files to a local disk. We open SharePoint Designer and realized that we are able to see the files and folders. However we are not able to just right click and save the files to a Windows directory.  What do we do know?

In order to be able to copy files from Office 365 to Windows explorer, we need to map the Office 365 website to a local drive. This allows Windows explorer to navigate the folder structure as if the files are local to the computer.  Once this is done, we can copy the files from the Office 365 website to a local drive.

How to map Office 365 to a local drive:
  • Open Windows Explorer
  • Right-click on Network and then click Map Network Drive
  • Click on a link (bottom) that reads “Connect to a Web site that you can store your documents and pictures”
  • Click Next
  • Select Choose a custom network location and click next
  • Enter the full path to your website. Similar to http://www.mysite.com and check Connect using different credentials
  • Enter your office 365 credentials
Once mapped, you can now use Windows explorer to see all the files and directories. You can now copy  and save the files in your local directory.


As a side note, you can also save your website as a template. The template is saved as a single file that contains all the content (.aspx, master pages, and images) files. In order to see the individual files, you would need to open the file using Visual Studio 2010 or newer.