Tuesday 26 September 2017

Response to Preflight Request Doesn't Pass Access Control Check: The 'Access-Control-Allow-Origin'

In the tip, I would try to explain scenario where a developer might come across a situation trying to login using Angular http POST data typically email, password some Token with Web Api. If both the client , server app are hosted in the same domain, then there won't be any issue, but this is something that is not same always.<11>
Let's Say client running on http://localhost:4200 and API is running on http://localhost:50000.In this case when client tries to access the api via  http POST method, then the application is likely to throw exception somewhat like below:

"Fix To Response to preflight request doesn't pass access control check: 
<11>
The 'Access-Control-Allow-Origin' header contains multiple values"

There are several ways to resolve this issue:

1. Adding the following customHeaders to the web.config of the Web API server.

<httpprotocol>    <customheaders>        <add name="Access-Control-Allow-Origin" value="*" />        <add name="Access-Control-Allow-Headers" value="Content-Type" />        <add name="Access-Control-Allow-Methods" value="GET,POST,PUT,DELETE,OPTIONS" />        <add name="Access-Control-Allow-Credentials" value="true" />    </customheaders></httpprotocol>


After adding above keys.The issue is gone.
2. Remove the headers from the web.config mentioned above.
3. Search for CORS in the nuget package manager in visual studio.
4. Apply the below attribute on controller level:
 [EnableCors(origins: "*", headers: "*", methods: "*")]
5. In order to apply CORS to all controllers in Web API, one can include the following as the first line in Register method in WebApiConfig.cs.

public static void Register(HttpConfiguration config){config.EnableCors();// Web API configuration and services// Configure Web API to use only bearer token authentication.config.SuppressDefaultHostAuthentication();config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));......


6. While implementing individual authentication using identity,There is one template available in visual studio inside provider folder ApplicationOAuthProvider.cs.in this file there is one method which grants resource credentials. The method name is:

public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)

In that method, one needs to check if some what like this is ever added.

context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "yourdomain:yourpostnumber" });


In this way you can resolve cross domain issues easily.
Happy Coding!!

        

Saturday 7 January 2017

Post List of string from ajax to controller

Here is the proper way of posting a list of string from ajax to controller.

Ajax setup one way:
           var stringArray = new Array();
            stringArray[0] = "item1";
            stringArray[1] = "item2";
            stringArray[2] = "item3";
         
            $.ajax({
                type: "POST",
                url: '@Url.Action("Search", "Home")',
                data: JSON.stringify({ listkey: stringArray }),
            success: function (data) {
                alert(data.Result);
            },
            dataType: "json",           
            contentType: 'application/json; charset=utf-8',
             });

Ajax Setup second way:

 $.ajax({
                type: "POST",
                url: '@Url.Action("Search", "Home")',
                data: { listkey: stringArray },
            success: function (data) {
                alert(data.Result);
            },
            dataType: "json",
            traditional: true
             });

Now,Controller:
 public ActionResult Search(List<string> listkey)
        {
            var n = listkey;
            return Json(new { });
        }

Thanks,