2

I know that it's CORS problem. I have enabled cors in web api server side. Get method is working fine but while dealing with post method I am facing problem . Please some one answer me with very simple post example both on web api and client side. With explanation of how to deal with preflight, options etc..

Console

1) zone.js:2935 OPTIONS http://localhost:49975/api/Add_Client_/postgoals 404 (Not Found)

2) Failed to load http://localhost:49975/api/Add_Client_/postgoals: Response for preflight has invalid HTTP status code 404.

web.config

<httpProtocol>
  <customHeaders>
    <add name="Access-Control-Allow-Origin" value="*"/>
    <add name="Access-Control-Allow-Headers" value="Origin, Content-Type, X-Auth-Token"/>
    <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
    <add name="Content-Type" value="application/json"/>

    <add name="Access-Control-Allow-Credentials" value="true" />
  </customHeaders>
</httpProtocol>

Angular Post method

    save_Goals(){

  let headers : Headers= new Headers();
  //headers.append('Content-Type','application/x-www-form-urlencoded');
  //headers.append("Access-Control-Allow-Origin","true");
  headers.append('Content-Type', 'application/json');

  headers.append('Access-Control-Allow-Origin','*');
  headers.append('Access-Control-Allow-Methods','GET,PUT,POST,DELETE');
  headers.append('Access-Control-Allow-Headers','Content-Type');

  let options = new RequestOptions({ headers: headers });

    return this._http.post('http://localhost:49975/api/Add_Client_/postgoals', {goal:'foo'},options)
   .map(res =>  res.json());
  }

Thank you!

Daniel Widdis
  • 8,424
  • 13
  • 41
  • 63
Harsha Bhat
  • 197
  • 2
  • 3
  • 12
  • usually CORS problems don't come with 404 error (unless manually set server side). They can even come with 200 ok status. What is the CORS message in the console? adding some details could help too, such as are there custom headers added? what is the response header? (without showing sensible values) – Kaddath Feb 09 '18 at 08:52
  • Yes I have custom headers added in web.config file. – Harsha Bhat Feb 09 '18 at 10:08
  • please edit the original question, it's hard to read code in comments. So, amongst other things, the `OPTIONS` request is made to check if custom headers are allowed by the server, did you allow them? Knowing the exact CORS error if there is one would still be useful. – Kaddath Feb 09 '18 at 10:49
  • I have edited the question .. please go through, I stuck with it from many days. – Harsha Bhat Feb 10 '18 at 11:20

3 Answers3

2

I am late but still wants to post the answer so to other it can be helpful. Below code works for me like a charm!

Here is the detailed answer to the question:

Pass data into the HTTP header from the Angular side (Please note I am using Angular4.0+ in the application).

There is more than one way we can pass data into the headers. The syntax is different but all means the same.

// Option 1 
 const httpOptions = {
   headers: new HttpHeaders({
     'Authorization': 'my-auth-token',
     'ID': emp.UserID,
   })
 };


// Option 2

let httpHeaders = new HttpHeaders();
httpHeaders = httpHeaders.append('Authorization', 'my-auth-token');
httpHeaders = httpHeaders.append('ID', '001');
httpHeaders.set('Content-Type', 'application/json');    

let options = {headers:httpHeaders};


// Option 1
   return this.http.post(this.url + 'testMethod', body,httpOptions)

// Option 2
   return this.http.post(this.url + 'testMethod', body,options)

In the call you can find the field passed as a header as shown in the image below : enter image description here

  1. Make changes at the backEnd/Web API side

Add new WebApiConfig file and add below content.

public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            config.EnableCors(new EnableCorsAttribute("http://localhost:4200", headers: "ID", methods: "*") { SupportsCredentials = true }); // In the Header define all the header by comma cepration or you can write * if it works for you.
            /config.EnableCors(enableCorsAttribute);

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

In the Global.asax.cs file add below event

protected void Application_BeginRequest()
        {
            if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
            {
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers","ID");// In the Header define all the header by comma cepration or you can write * if it works for you.
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Credentials", "true");
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "http://localhost:4200");
                HttpContext.Current.Response.End();
            }
        }

And at the Web API side you can fetch that code with below statement :

 if (Request.Headers.Contains("ID"))
            {
                var ID= Request.Headers.GetValues("ID").First();
            }

you can follow these steps for below errors :

  • Response to preflight request doesn't pass access control check: No ''Access-Control-Allow-Origin'' header is present on the requested resource. Origin ''http://localhost:4200'' is therefore not allowed access

  • Response for preflight does not have HTTP ok status.

This code works for me, I am able to pass ID in the HTTP header and same I can retrieve at web API side.

Thanks and Happy coding!!

Trilok Pathak
  • 2,931
  • 4
  • 28
  • 34
1

I finally found a work around. what i did is i removed custom headers from web.config file. i.e,

<httpProtocol>
  <customHeaders>
    <add name="Access-Control-Allow-Origin" value="*"/>
    <add name="Access-Control-Allow-Headers" value="Origin, Content-Type, X-Auth-Token"/>
    <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
    <add name="Content-Type" value="application/json"/>

    <add name="Access-Control-Allow-Credentials" value="true" />
  </customHeaders>
</httpProtocol>

This content i removed

and in WebApiConfig.cs i did following changes

var enableCorsAttribute = new EnableCorsAttribute(origins:"*",headers:"*",methods:"*");

            var json = config.Formatters.JsonFormatter;

            json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
            config.Formatters.Remove(config.Formatters.XmlFormatter);

            config.EnableCors(enableCorsAttribute);

and Controller Looks like this.

[EnableCors(origins: "*", headers: "*", methods: "*", SupportsCredentials = true)]
    [RoutePrefix("api/Add_Client_")]
    public class Add_Client_Controller : ApiController
    {
[AcceptVerbs("POST")]

        [HttpPost]
        [Route("PostGoals")]
        public string PostGoals(string goal)
        {
            Goal g = new Goal();
            g.Goals = goal;
            db.Goals.Add(g);
            int res = db.SaveChanges();

            return ("Success");
        }
}

and Angular POST Method looks like following

 save_Goals(){

  let headers : Headers= new Headers();
        headers.append('Content-Type','application/x-www-form-urlencoded');
    headers.append('Access-Control-Allow-Origin','*');
      headers.append('Access-Control-Allow-Methods','GET,PUT,POST,DELETE');
      headers.append('Access-Control-Allow-Headers','Content-Type');

      let options = new RequestOptions({ headers: headers });
    return this._http.post('http://localhost:49975/api/Add_Client_/PostGoals?goal=check',options)
       .map(res =>  res.json());
    }

This is work around to send data with URL.

Harsha Bhat
  • 197
  • 2
  • 3
  • 12
0

also u can use chrome extension

https://chrome.google.com/webstore/detail/moesif-origin-cors-change/digfbfaphojjndkpccljibejjbppifbc

set header type application/x-www-form-urlencoded

let headers = new HttpHeaders();
headers = headers.set('Content-Type', 'application/x-www-form-urlencoded');
headers.append('Access-Control-Allow-Origin','*');
headers.append('Access-Control-Allow-Methods','GET,PUT,POST,DELETE');
headers.append('Access-Control-Allow-Headers','Content-Type');
Mohammad Reza Mrg
  • 1,552
  • 15
  • 30