3

I currently have this WEB API running locally:

// POST api/CsvParse
[HttpPut]
public void Put([FromBody]string value)
{
    if (string.IsNullOrEmpty(value))
        throw new Exception("Input is null or empty.");
}

I currently have it running locally, and am sending a string to the put using POSTMAN. I have selected the body tab, and have the string pasted into the raw body tab:

enter image description here

It states that my text is unsupported, or when I add a break point the value is null or I get the error describing the format is incorrect.

What am I doing wrong?

Nkosi
  • 235,767
  • 35
  • 427
  • 472
Kat
  • 2,460
  • 2
  • 36
  • 70

5 Answers5

2

Change the media type to x-www-form-urlencoded rather than multipart/form-data.

Also, WebAPI is particular about FromBody parameters. http://encosia.com/using-jquery-to-post-frombody-parameters-to-web-api/

For you, I think this is the relevant part:

  1. [FromBody] parameters must be encoded as =value

The final hurdle remaining is that Web API requires you to pass [FromBody] parameters in a particular format. That’s the reason why our value parameter was null in the previous example even after we decorated the method’s parameter with [FromBody].

Instead of the fairly standard key=value encoding that most client- and server-side frameworks expect, Web API’s model binder expects to find the [FromBody] values in the POST body without a key name at all. In other words, instead of key=value, it’s looking for =value.

This part is, by far, the most confusing part of sending primitive types into a Web API POST method. Not too bad once you understand it, but terribly unintuitive and not discoverable.

Chris Bergin
  • 415
  • 2
  • 8
2

That's because there is no media type formatter that can serialize a raw string into your model (your route parameter with [FromBody] attribute).

A quick and dirty workaround is to directly read the body of your request as a string:

[HttpPut]
public async Task<HttpResponseMessage> Put(HttpRequestMessage request)
{
    var myCsv = await request.Content.ReadAsStringAsync();

    // do stuff with your string

    return new HttpResponseMessage(HttpStatusCode.OK);
}

As an alternative you could implement a custom media type formatter yourself, as per this answer.

Community
  • 1
  • 1
Federico Dipuma
  • 17,655
  • 4
  • 39
  • 56
0

Try adding a content type of text/plain

enter image description here

jhilden
  • 12,207
  • 5
  • 53
  • 76
0

There is a similar Q&A here

I found that solution #1 worked for me as I was trying to PUT JSON containing the Key/Value pair. So originally my JSON looked like this

{
    "subscriber": {
    "Id": "2",
    "subscriptions":[
        {
            "Name": "Subscription 1",
            "Id": "18",
            "IsSubscribed": false
        },
        {
            "Name": "Subscription 2",
            "Id": "19",
            "IsSubscribed": false
        },
        {
            "Name": "Subscription 3",
            "Id": "20",
            "IsSubscribed": false
        }
    ]
    }
}

But I modified it to become

{
    "Id": "2",
    "subscriptions":[
        {
            "Name": "Subscription 1",
            "Id": "18",
            "IsSubscribed": false
        },
        {
            "Name": "Subscription 2",
            "Id": "19",
            "IsSubscribed": false
        },
        {
            "Name": "Subscription 3",
            "Id": "20",
            "IsSubscribed": false
        }
    ]
}

And that worked. My PUT request from Postman was recognised in my C# web api using [FromBody]

Community
  • 1
  • 1
IsolatedStorage
  • 1,175
  • 12
  • 12
0

Just to add my bit, there is one more solution to pass primitives into a POST or a PUT method. Just specify the model as JObject. ASP.Net core web api then binds incoming JSON object(containing primitives like string) into JObject model object.

Your code would look like this:

// POST api/CsvParse
[HttpPut]
public void Put([FromBody]JObject value)
{
    //access your string data
    string data = value[SPECIFY_KEY_HERE];

    if (string.IsNullOrEmpty(data))
        throw new Exception("Input is null or empty.");
}
Deepak Pathak
  • 626
  • 1
  • 9
  • 19