I am trying to post some JSON to a web api .net core but for some reason this is always null no matter what i have tried see code below.
this is my .net core web api code
[Produces("application/json")]
[Route("api/v1/Issues")]
[Authorize]
[EnableCors("AllowCors")]
public class IssuesController : Controller
{
[HttpPost]
public IActionResult PostIssues([FromBody] string issue)
{
//some code to desirialize
}
}
and this is how i am trying to post via angular (note that the appropriate services are loaded)
public addIssue(issue) {
const headers = new Headers();
this.authService.getToken().toPromise().then( t => {
headers.append('Authorization', `Bearer ${t.toString()}`);
headers.append('Content-Type', 'application/json')
this.http.post(`${this.baseUrl}/v1/issues`, issue, {
headers: headers
}).toPromise()
.then(res => {
console.log(res.json());
});
});
}
i have tried changing the post to
this.http.post(`${this.baseUrl}/v1/issues`, JSON.stringify(issue))
and even
this.http.post(`${this.baseUrl}/v1/issues`, {'issue', JSON.stringify(issue)})
but nothing seems to work anyone has any idea why this is happening?
To clarify the string issue
received on the API is what is always null.
Here is the successfull response of when i reaches the server you can see the request payload is not null but reaches the web api as null
UPDATE 1 Explanation required if possible Alright i wanted to do a little experiment the same code worked fine for a 4.5 framework instead of a .net core however what i tried to do for .net core and worked was create a class called foo see below
public class Foo
{
public string Name { get; set; }
public string Json { get; set; }
}
And modify my Controller to accept this object
[HttpPost]
public IActionResult PostIssues([FromBody] Foo issue)
{
Debug.Write(issue);
return Ok(issue);
}
As well as my Angular project to pass a similar format body
public addIssue(issue) {
const headers = new Headers();
this.authService.getToken().toPromise().then( t => {
headers.append('Authorization', `Bearer ${t.toString()}`);
headers.append('Content-Type', 'application/json');
this.http.post(`${this.baseUrl}/v1/issues`, {'name' : 'name', 'json': JSON.stringify(issue)}, {
headers: headers,
withCredentials: true
}).toPromise()
.then(res => {
console.log(res.json());
});
});
}
And this manages to pass successfully and bind to the controller
Why is this Ok but not able to pass a Json directly? and why does my original code works on 4.5 framework but not on .net core?
I'll try to answer all your questions.
string issue received on the API is always null
Passing a JSON to this will always get you a null because you are trying to bind to a primitive data type. To fix this you have two options
Bind to a model ( viewmodel )
When your parameter is a class, asp will bind this class to the json data you passed that's why you were able to get the name
data.
Based on your update, you might probably go this route.
More info: https://docs.microsoft.com/en-us/aspnet/core/mvc/models/model-binding
Now you might be wondering why would you create a class just to be used on your api when the parameter is just a string?! If you want to use just the string
in your api then you can do this
Pass the data using FormData
You need to change your api like this
public IActionResult PostIssues(string issue){..}
You don't need to specify the [FromBody]
here.
In your client-side,
public addIssue(issue) {
const headers = new Headers();
this.authService.getToken().toPromise().then( t => {
headers.append('Authorization', `Bearer ${t.toString()}`);
// new code here
var formData = new FormData();
formData.append('issue',issue); //you need to specify the parameter name here.
this.http.post(`${this.baseUrl}/v1/issues`, formData, {
headers: headers
}).toPromise()
.then(res => {
console.log(res.json());
});
});
}
Hope this helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With