0

So, according to this:

  • If the parameter is a “simple” type, Web API tries to get the value from the URI. Simple types include the .NET primitive types (int, bool, double, and so forth), plus TimeSpan, DateTime, Guid, decimal, and string, plus any type with a type converter that can convert from a string. (More about type converters later.)
  • For complex types, Web API tries to read the value from the message body, using a media-type formatter.

I have a POST action with a single string parameter coming from the user's input and can therefore be any character - foreign, unicode, apostrophe, '%20' etc. anything!

I am therefore reluctant to have this parameter in the URL and the [FromBody] decorator doesn't appear to be helping. Question is: what is the best [a-hem] pratice for posting a single string parameter to WebAPI controller?

C#:

[HttpPost]
[Route("api/add")]
public void Add([FromBody]string name)
{
    // name is null :(
}

JS:

function add(name: string) {
    return this.$http.post("api/add/", name);
}

enter image description here

5
  • I just tried to send simple string by post request without [FromBody] attribute from angular. I sent my value in request body. And it works. Can you check the request that it generates? (in browser or fiddler) Commented Jun 21, 2016 at 15:53
  • it was the lack of quote marks around the string value, which is just ridiculous! Commented Jun 21, 2016 at 16:04
  • fyi you didn't block out all of the instances of /localhost/****/ in your image :p Commented Jun 21, 2016 at 17:01
  • @Tsar - is your problem solved? Commented Jun 21, 2016 at 17:10
  • If not, I have two possible solutions. 1) you can send the object within request payload (like { name : "my requested name" }) or 2) create and use custom attribute to take care about string in body without quotes Commented Jun 21, 2016 at 17:14

2 Answers 2

1

If you really want the [FromBody] decorator, you should consider creating a DTO so that Model binder can read the posted data from the request body and map to this DTO object.

public class MyRequest
{
  public string Name { set;get;}
}

[HttpPost]
[Route("api/add")]
public void Add([FromBody]MyRequest model)
{
    //do something with model.Name
}

If you do not prefer to create a class, you can remove the [FromBody] decorator from your action method and keep a string type and send the value as querystring.

public void Add(string model)
{
    //do something with model.Name
}

and

$http.post('/api/add?name=Scott with a space')
    .then(function(response) {
        console.log('angular http response', response.data);
    })
Sign up to request clarification or add additional context in comments.

2 Comments

that's exactly what i was trying to avoid doing
Pay the pain one time (e.g. make a generic MyStringParameter object) and then use it for as many api methods as you want.
0

I have resolved this by wrapping the request object (name) in quotes, using angular.toJson`:

function add(name: string) {
    return this.$http.post("api/add/", angular.toJson(name));
}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.