When you have created a Restful API using the ASP.NET Web API and if your API is in one domain and the UI is in another domain then you might get errors due to cross-domain issues.
- http://localhost:5000/api/ 404 (Not Found).
- http://localhost:5000/api/. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:54317' is therefore not allowed access. The response had HTTP status code 404.
In other words you cannot make a call to the WebAPI via your front end that is hosted on a different domain.
Then you can resolve it using Web API Cross Handler, you need to add a WepAPICrossHandler.cs code in the App_Start folder and register this code in Application_Start().
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Web;
- using System.Net.Http;
- using System.Threading;
- using System.Threading.Tasks;
- using System.Net;
-
- namespace WebAPI
- {
- public class WepAPICrossHandler : DelegatingHandler
- {
- 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";
-
- protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
- {
- bool isCorsRequest = request.Headers.Contains(Origin);
- bool isPreflightRequest = request.Method == HttpMethod.Options;
- if (isCorsRequest)
- {
- if (isPreflightRequest)
- {
- 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);
- }
-
- TaskCompletionSource<HttpResponseMessage> tcs = new TaskCompletionSource<HttpResponseMessage>();
- tcs.SetResult(response);
- return tcs.Task;
- }
- else
- {
- return base.SendAsync(request, cancellationToken).ContinueWith<HttpResponseMessage>(t =>
- {
- HttpResponseMessage resp = t.Result;
- resp.Headers.Add(AccessControlAllowOrigin, request.Headers.GetValues(Origin).First());
- return resp;
- });
- }
- }
- else
- {
- return base.SendAsync(request, cancellationToken);
- }
- }
- }
- }
For using this code you need to make the following change in the Application_Start() method in the Global.asax.cs file.
- GlobalConfiguration.Configuration.MessageHandlers.Add(new WepAPICrossHandler());
After then we will add controller on our UI (front-end) side.
Suppose we have added a HomeController.cs.
- public class HomeController : ApiController
- {
- public string GetEmployeeInformation(string JSONString)
- {
- var seriptSerialization = new System.Web.Script.Serialization.JavaScriptSerializer();
- Employee employee = seriptSerialization.Deserialize<Employee>(JSONString);
-
-
- return employee.EmployeeName;
- }
-
- public string PostSubmitdata([FromBody]Employee emp)
- {
- return emp.EmployeeName;
- }
- }
If you have found there is something error like : The type or namespace 'Script' does not exist in the namespace 'System.Web' (are you missing an assembly reference?)
Then you have to add references for System.Web.Extensions.dll
And the Employee class:
- public class Employee
- {
- public string EmployeeName { get; set; }
- public EmployeeDetails empdetails { get; set; }
- }
- public class EmployeeDetails
- {
- public string email { get; set; }
- public string firstName { get; set; }
- public string lastName { get; set; }
- }
Then we will look at the WebApiConfig.cs file in the App_Start folder.
- public static void Register(HttpConfiguration config)
- {
- config.Routes.MapHttpRoute(
- name: "DefaultApi",
- routeTemplate: "api/{controller}/{action}/{id}",
- defaults: new { id = RouteParameter.Optional }
- );
- }
So we can write the GET and POST methods as shown below.
- <!DOCTYPE>
- <html>
- <head>
- <title></title>
- <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
- <script language="javascript" type="text/javascript">
-
-
- var reqdata = {
- EmployeeName: "JD Mishra",
- empdetails: {
- email: '[email protected]',
- firstName: 'Jagdev',
- lastName: 'Mishra'
- }
- }
- var stringReqdata = JSON.stringify(reqdata);
-
-
- function GetEmployeeInformation() {
- var url = "http://localhost:5000/api/Home/GetEmployeeInformation?JSONString=" + stringReqdata;
- jQuery.ajax({
- crossDomain: true,
- dataType: "json",
- url: url,
- async: false,
- context: document.body
- }).success(function (data) {
- alert(data);
- });
- };
-
- function PostSubmitdata() {
- var url = "http://localhost:5000/api/Home/PostSubmitdata";
- jQuery.ajax({
- crossDomain: true,
- async: false,
- type: "POST",
- url: url,
- data: stringReqdata,
- dataType: "json",
- context: document.body,
- contentType: 'application/json; charset=utf-8'
- }).success(function (data) {
- alert(data);
- })
- }
- </script>
- </head>
- <body>
- <a href="#" onclick="GetEmployeeInformation();">Get</a><br />
- <a href="#" onclick="PostSubmitdata();">Post</a>
- </body>
- </html>
Thanks.