3

I am very new to Angular , Developing an app in Angular 5 . I am trying to post some data to an API , below is my code

.Net Core Web API

    [Produces("application/json")]
    [Route("api/Audit")]
         public class AuditController : Controller
        {
            private IConfiguration _configuration;
            private CommomUtility util;
            private Login Login;

            public AuditController(IConfiguration configuration)
            {
                _configuration = configuration;
                util = new CommomUtility(configuration);
                Login = new Login(configuration);
            }

            [HttpPost]
            public JsonResult Action([FromBody] List<Dictionary<string, string>> li)
            {
                DataTable dt = new DataTable();
                string jsonString = string.Empty;
                try
                {
                    if (li[0]["ActionMethod"].Equals("CheckLogin", StringComparison.InvariantCultureIgnoreCase))
                    {
                        dt = Login.checkLogin(li);
                    }
                }
                catch (Exception ex)
                {
                }
                finally
                {
                    dt.TableName = "Result";
                    jsonString = util.DataTableToJson(dt);
                }
                return Json(JObject.Parse(jsonString));
           }
        }

Angular Login Componenet

    import { Component, OnInit } from '@angular/core';
import { HttpClient,HttpClientModule,HttpParams,HttpHeaders } from '@angular/common/http';

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {
  username: string="";
  password: string="";
  loginBtnText: string='Log In';
  clearBtnText: string='Reset Fields';
  message:string;
  cssClass:string;

  constructor(private http:HttpClient  ) { }

  ngOnInit() {
  }

  checkLogIn(){
    const params = new HttpParams();
    params.set('ActionMethod', 'CheckLogin');
    params.set('StaffCode', '15989');
    params.set('Password', '#####');
    var queryHeaders = new HttpHeaders();
    queryHeaders.append('Content-Type', 'application/json');
   debugger
    var v= this.http.post("http://localhost:57863/api/Audit/",
      params,{ headers: queryHeaders}
    )
    .subscribe(data => 
    {alert('ok');},
     error => 
     {alert("Error");}
    );
  }

  clearFields(){
    this.username="";
    this.password="";
    this.message="";
  }

}

I am invoking checkLogIn() on button click , after invoking this API it reach to constructor of API class only but does not go inside API Method.

I checked my browser Network tab and it show

415 Unsupported Media Type

Header section of request

When I invoking the Get API (values api) which is by default comes in .Net Core Web API template than it works and show alert OK but failed in case of POST

Update 1

enter image description here

enter image description here

Tanwer
  • 1,503
  • 8
  • 26
  • 41

4 Answers4

2

Seems like you have mentioned application/json in web API as Produces("application/json") but not passing it in header from the angular code.

Try this

import { HttpClient, HttpHeaders,HttpParams} from '@angular/common/http';

if can't change the web api then change angular code as show below and keep the web api as it is.

angular

checkLogIn(){
    var requestData=[];

    var params={
      "ActionMethod":"CheckLogin",
      "StaffCode":"15989",
      "Password":"####"
    }
    requestData.push(params);

    const httpOptions = {
          headers: new HttpHeaders({
            'Content-Type':  'application/json'
          })
        };

    //pass it if you can't modify web api
    var v= this.http.post("http://localhost:5000/api/Audit/",
      requestData,httpOptions
    )
    .subscribe(data => 
    {alert('ok');},
     error => 
     {alert("Error");}
    );

}

if you can change web api then,

angular

checkLogIn(){
    var requestData=[];

    var params={
      "ActionMethod":"CheckLogin",
      "StaffCode":"15989",
      "Password":"####"
    }


    const httpOptions = {
          headers: new HttpHeaders({
            'Content-Type':  'application/json'
          })
        };

   //pass it like this if you can change web api
    var v= this.http.post("http://localhost:5000/api/Audit/",
      params,httpOptions
    )
    .subscribe(data => 
    {alert('ok');},
     error => 
     {alert("Error");}
    );
}

web api controller

public class LoginContract
{
    public string ActionMethod { get; set; }
    public string StaffCode { get; set; }
    public string Password { get; set; }
}

[HttpPost]
public JsonResult Action([FromBody] LoginContract li)
{
    DataTable dt = new DataTable();
    string jsonString = string.Empty;
    try
    {
        if (li.ActionMethod.Equals("CheckLogin", StringComparison.InvariantCultureIgnoreCase))
        {
            dt = Login.checkLogin(li);
        }
    }
    catch (Exception ex)
    {
        Console.Write(ex);
    }
    finally
    {
        dt.TableName = "Result";
        jsonString = util.DataTableToJson(dt);
    }
    return Json(JObject.Parse(jsonString));
}

I think you haven't enabled the Cors Module in your web api. add the following code to Startup.cs of your web api.

If you haven't install the CORS nuget package

Install-Package Microsoft.AspNetCore.Cors

Add the code inside ConfigureServices method.

services.AddCors(options =>
            {
                options.AddPolicy("AllowAll",
                    builder =>
                    {
                        builder
                        .AllowAnyOrigin() 
                        .AllowAnyMethod()
                        .AllowAnyHeader()
                        .AllowCredentials();
                    });
            });

Now in Configure method add the following code before app.UseMvc().

app.UseCors("AllowAll");

I hope this will fix your problem. If you have any issues or doubt let me know.

Suvethan Nantha
  • 2,404
  • 16
  • 28
  • Now it says 404 Not Found . And it should set Content Type to json but in header it only show 'Access-Control-Request-Headers: content-type' , and 'Request Method: OPTIONS' instead of POST – Tanwer Apr 06 '18 at 05:47
  • @Jack I have checked it is working for me? there can be errors but it can't be 404. can u attach the screenshot? – Suvethan Nantha Apr 06 '18 at 06:04
  • , check Update 1 , I have Posted two ScreenShot – Tanwer Apr 06 '18 at 06:13
  • @Jack check the updated answer, the error you got because cors is not enabled – Suvethan Nantha Apr 06 '18 at 06:29
  • , it works , Hit the api but parameters are null , Something is still blocking the params setting – Tanwer Apr 06 '18 at 06:37
  • @Jack check the updated answer I got the params from angular to web api without a problem. check both angular code and web api code – Suvethan Nantha Apr 06 '18 at 06:48
  • @Jack passing params and the datatype in your receiving side are not matching each other that's why you are getting always null. Change the web api as I told, it will work as charm :) – Suvethan Nantha Apr 06 '18 at 06:50
  • , yes it will work this way but imagine now I have to develop different API for every Purpose I have (say 100) , with List> I want to receive list of parameters as key value pair , there is one key (ActionMethod) which is mandatory which tell me what to do and other keys are parameters name with their value – Tanwer Apr 06 '18 at 06:57
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/168378/discussion-between-suvethan-nantha-and-jack). – Suvethan Nantha Apr 06 '18 at 07:04
  • @Jack I have updated my answer. Check it and let me know the feedback. – Suvethan Nantha Apr 06 '18 at 07:54
  • Thanks a lot , can you refer any post about redirection to other pages in Angular5 and how can I implement a mechanism like session in asp.net core to hold some values through out my Application – Tanwer Apr 06 '18 at 08:46
0

Error 415 Unsupported media type Saying that the value of request header content-type is not what server is expecting in the request. Try to set content-type header to value application/json in angular.

Agam
  • 1,015
  • 2
  • 11
  • 21
  • I did add Content Type , check my updated post , but in network tab it still show Content-Type: application/x-www-form-urlencoded;charset=UTF-8 – Tanwer Apr 06 '18 at 05:40
  • But you are not passing the json object in the request. Pass json payload directly in the request. – Agam Apr 06 '18 at 05:43
  • @Jack in ajax world this is a very common problem. Search on internet about this. To solve it either your server should return the missing header with the host name of your angular app or if your angular app is deployed on same server, use relative path in ajax call. – Agam Apr 06 '18 at 06:21
0

The content-type seems to be wrong. You can try to send a JSON object as the payload directly. `

const payload = 
{'ActionMethod': 'CheckLogin',
'StaffCode': '15989',
'Password': 'a$a#'
}
var v= this.http.post("http://localhost:57863/api/Audit/",payload)`
Brian Li
  • 1
  • 1
0

You are facing COARS errors problem very famous as u invoking another processes link hitting so causes dont panic Do

webapiconfig.cs

  var cors = new System.Web.Http.Cors.EnableCorsAttribute("http://localhost:51156", 
  "*", "*");

        config.EnableCors(cors);

        // ADD JUST THIS LINE TO REGISTER FOLLOWING CLASS.
        config.Formatters.Add(new BrowserJsonFormatter());

now add following code to ovverride

// TO SEE DATA IN JSON IN CHROME BROWSER ADD FOLLOWING CLASS BrowserJsonFormatter and REGISTER IN METHOD ADD NEW OBJECT OF THIS CLASS.
public class BrowserJsonFormatter : System.Net.Http.Formatting.JsonMediaTypeFormatter
{
    public BrowserJsonFormatter()
    {
        this.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
        this.SerializerSettings.Formatting = Formatting.Indented;
    }

    public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType)
    {
        base.SetDefaultContentHeaders(type, headers, mediaType);
        headers.ContentType = new MediaTypeHeaderValue("application/json");
    }
}

//-----------------------------------------------------------------------------------------------------------------------
Ashish Kamble
  • 2,555
  • 3
  • 21
  • 29