Marwan N
Marwan N

Reputation: 531

Enable CORS in Angular 6 and ASP.net

I am trying to send a POST request from my Angular 6 App to an API that sends Emails.

I tested the request with postman and it worked, however when I'm doing the POST request in my Angular app I get errors in my console.

My function in the Angular app:

sendMail(formBody: string): any {
    //let url = this.config.origin + "/api/SendEmail";
    let url = "http://localhost:49561/api/SendEmail";
    let headers = new HttpHeaders();
    headers = headers.append('Content-Type', 'application/json');

    return this.httpClient.post(url, formBody, { headers })
      .pipe(map(res => {
        return res;
      })).toPromise();
  }

I have added the following to my API:

 public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Enable Cors
            config.EnableCors();
            ...
    [EnableCors(origins: "http://localhost:4200/contact", headers: "*", methods: "*")]
    public class ContactFormsController : ApiController
    {
       ...

These are the warnings and errors I'm getting in the Console:

"Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:49561/api/SendEmail. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing)."

"Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:49561/api/SendEmail. (Reason: CORS request did not succeed)."

"ERROR Error: "Uncaught (in promise): HttpErrorResponse: {"headers":{"normalizedNames":{},"lazyUpdate":null,"headers":{}},"status":0,"statusText":"Unknown Error","url":null,"ok":false,"name":"HttpErrorResponse","message":"Http failure response for (unknown url): 0 Unknown Error","error":{"isTrusted":true}}""

EDIT: I have added the following in Web.config:

         <httpProtocol>
                <customHeaders>
                <add name="Access-Control-Allow-Origin" value="*" />
                </customHeaders>
         </httpProtocol>

and now I'm getting this Error instead of "‘Access-Control-Allow-Origin’ missing":

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:49561/api/SendEmail. (Reason: CORS preflight channel did not succeed)

EDIT:

After removing "content-type : application/json". I got this Error in the console:

ERROR Error: "Uncaught (in promise): HttpErrorResponse: {"headers":{"normalizedNames":{},"lazyUpdate":null},"status":500,"statusText":"Internal Server Error","url":"http://localhost:49561/api/SendEmail","ok":false,"name":"HttpErrorResponse","message":"Http failure response for http://localhost:49561/api/SendEmail: 500 Internal Server Error","error":{"Message":"An error has occurred.","ExceptionMessage":"The specified policy origin 'http://localhost:4200/contact' is invalid. It must not contain a path, query, or fragment.","ExceptionType":"System.InvalidOperationException","StackTrace":" at System.Web.Http.Cors.EnableCorsAttribute.ValidateOrigins(IList`1 origins)\r\n at System.Web.Http.Cors.EnableCorsAttribute.GetCorsPolicyAsync(HttpRequestMessage request, CancellationToken cancellationToken)\r\n at System.Web.Http.Cors.CorsMessageHandler.d__8.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Cors.CorsMessageHandler.d__5.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Cors.CorsMessageHandler.d__4.MoveNext()"}}"

Upvotes: 2

Views: 4199

Answers (2)

Satish Patil
Satish Patil

Reputation: 458

Use attribute ( dont use wildcard for Access-Control-Allow-Methods is not yet supported by all browsers.)

[EnablCors(origins: "*", headers: "*", methods: "GET, POST, PUT, DELETE, OPTIONS")]

In Global

And you have to handle "OPTIONS" method separately in global.asax, as the browser will send a pre-flight request to the server

protected void Application_BeginRequest()
{
    if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
    {
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH, DELETE, OPTIONS");
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
        HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
        HttpContext.Current.Response.End();
    }
}

Upvotes: 1

Hardik Gondalia
Hardik Gondalia

Reputation: 3717

Go to your App_start folder and open WebApiConfig.cs

Add following line:

 EnableCorsAttribute cors = new EnableCorsAttribute("*", "*", "GET, POST, PUT, DELETE, OPTIONS");
 config.EnableCors(cors);

final code:

public static void Register(HttpConfiguration config)
        {
            // Web API configuration and services

            // Web API routes
            config.MapHttpAttributeRoutes();
            EnableCorsAttribute cors = new EnableCorsAttribute("*", "*", "GET, POST, PUT, DELETE, OPTIONS");
            config.EnableCors(cors);
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
            config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
        }

You can replace * from localhost:4200 in Origins

Upvotes: 1

Related Questions