Under the value, we can pass our response data in whichever format we want to return the data. I want to call Post method. Hence, select POST method from the list of HTTP methods. We try and pass the Web API URL in the URL tab in order to make sure you need to first run your project and pass localhost URL.
From answer in this question: How to get Json Post Values with asp.net webapi
Autoparse using parameter binding; note that the dynamic
is made up of JToken
, hence the .Value
accessor.
public void Post([FromBody]dynamic value) {
var x = value.var1.Value; // JToken
}
Read just like Request.RequestUri.ParseQueryString()[key]
public async Task Post() {
dynamic obj = await Request.Content.ReadAsAsync<JObject>();
var y = obj.var1;
}
Same as #2, just not asynchronously (?) so you can use it in a helper method
private T GetPostParam<T>(string key) {
var p = Request.Content.ReadAsAsync<JObject>();
return (T)Convert.ChangeType(p.Result[key], typeof(T)); // example conversion, could be null...
}
Caveat -- expects media-type application/json
in order to trigger JsonMediaTypeFormatter
handling.
After spending a good bit of time today trying to wrap my brain around the (significant but powerful) paradigm shift between old ways of processing web form data and how it is done with WebAPI, I thought I'd add my 2 cents to this discussion.
What I wanted to do (which is pretty common for web form processing of a POST) is to be able to grab any of the form values I want, in any order. Say like you can do if you have your data in a System.Collections.Specialized.NameValueCollection
. But turns out, in WebAPI, the data from a POST comes back at you as a stream. So you can't directly do that.
But there is a cool little class named FormDataCollection
(in System.Net.Http.Formatting) and what it will let you do is iterate through your collection once.
So I wrote a simple utility method that will run through the FormDataCollection
once and stick all the values into a NameValueCollection
. Once this is done, you can jump all around the data to your hearts content.
So in my ApiController derived class, I have a post method like this:
public void Post(FormDataCollection formData)
{
NameValueCollection valueMap = WebAPIUtils.Convert(formData);
... my code that uses the data in the NameValueCollection
}
The Convert method in my static WebAPIUtils class looks like this:
/// <summary>
/// Copy the values contained in the given FormDataCollection into
/// a NameValueCollection instance.
/// </summary>
/// <param name="formDataCollection">The FormDataCollection instance. (required, but can be empty)</param>
/// <returns>The NameValueCollection. Never returned null, but may be empty.</returns>
public static NameValueCollection Convert(FormDataCollection formDataCollection)
{
Validate.IsNotNull("formDataCollection", formDataCollection);
IEnumerator<KeyValuePair<string, string>> pairs = formDataCollection.GetEnumerator();
NameValueCollection collection = new NameValueCollection();
while (pairs.MoveNext())
{
KeyValuePair<string, string> pair = pairs.Current;
collection.Add(pair.Key, pair.Value);
}
return collection;
}
Hope this helps!
I had a problem with sending a request with multiple parameters.
I've solved it by sending a class, with the old parameters as properties.
<form action="http://localhost:12345/api/controller/method" method="post">
<input type="hidden" name="name1" value="value1" />
<input type="hidden" name="name2" value="value2" />
<input type="submit" name="submit" value="Submit" />
</form>
Model class:
public class Model {
public string Name1 { get; set; }
public string Name2 { get; set; }
}
Controller:
public void method(Model m) {
string name = m.Name1;
}
It is hard to handle multiple parameters on the action directly. The better way to do it is to create a view model class. Then you have a single parameter but the parameter contains multiple data properties.
public class MyParameters
{
public string a { get; set; }
public string b { get; set; }
}
public MyController : ApiController
{
public HttpResponseMessage Get([FromUri] MyParameters parameters) { ... }
}
Then you go to:
http://localhost:12345/api/MyController?a=par1&b=par2
Reference: http://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api
If you want to use "/par1/par2", you can register an asp routing rule. eg routeTemplate: "API/{controller}/{action}/{a}/{b}".
See http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-in-aspnet-web-api
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