0

I am currently looking at Angular for the first time and trying to post a simple string to an MVC controller. However, when I try to post the string using the Angular client, I get a bad request response.

Test Class:

public class Test 
{
    public string Email { get; set; }
}

Posting via Angular client:

this.client.post<boolean>(this.baseUrl + 'weatherforecast/Test', { Email: Email });

This results in a bad request response.

[HttpPost]
[Route("Test")]
public bool Test([FromBody] string Email)
{
    if (Email == "TestInput")
    {
        return true;
    }
    return false;
}

However this works:

[HttpPost]
[Route("Test")]
public bool Test([FromBody] Test EmailObject)
{
    if (EmailObject.Email == "TestInput")
    {
        return true;
    }
    return false;
}

If I try posting the JSON as simply "StringValue" instead of { Email: "StringValue" }, I get an Unsupported Media Type response.

I imagine there is a simple solution, but is there a way to allow a string to be posted to an MVC controller without requiring it to be passed in as a class?

1
  • the string gets unquoted before being sent, and therefore is invalid Commented Aug 23, 2020 at 1:39

2 Answers 2

2

A typical endpoint returns an IActionResult or an implementation of IActionResult. For example Ok(), which translates to an HTTP 200 response, NotFound translates to HTTP 404.

[HttpPost]
[Route("Test")]
public IActionResult Test([FromBody] Test EmailObject)
{
    if (EmailObject.Email == "TestInput")
    {
        return Ok(true);
    }
    return Ok(false);
}

Pretty sure you have to wrap it in an object in order to post it. That isn't a limitation of ASP.NET Core, but rather a rule of JavaScript in general. Simply typing "StringValue" is not valid JSON, but { Email:Email } is.

Side note:

You could use query strings:

[HttpGet]
[Route("Test")]
public IActionResult Test([FromQuery] string email)
{
    if (email == "TestInput")
    {
        return Ok(true);
    }
    return Ok(false);
}

Then call it like this:

http://example.com/api/Test?email=TestInput

Then a string would work.

Disclaimer: I do not know how Angular works, at all.

Sign up to request clarification or add additional context in comments.

Comments

1

Controller method that is tested with Postman and with payload "TestInput" and Content-Type: application/json

[HttpPost("Test")]
public bool Test([FromBody] string email)
{
   return email?.Equals("TestInput") == true;
}

Following description in this answer: https://stackoverflow.com/a/50021779/14072498

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

const payload = 'TestInput';

this.client.post<boolean>(this.baseUrl + 'weatherforecast/Test', `\"${payload}\"`, httpOptions);

Note

`\"${payload}\"`

can (should) be replaced with

JSON.stringify(payload)

but the latter did not work for a person that commented this answer.

4 Comments

It works using Postman, but not when sent by Angular as the string gets unquoted before being sent, you can test that by copying the xhr request from the browser and import it in postman
@RafiHenig: Several posts are indicating that missing content-type is causing this problem. By passing a simple string instead of a JSON, Angular fails to guess content-type. But, maybe I'm wrong.
I've tried setting Contnet-Type header to Application/Json with both Postman and Angular, only the former works
@RafiHenig: Updated my answer with JSON.stringify('TestInput')

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.