WebPI Multiple Put / Post Options

I am trying to publish several parameters on a WebAPI controller. One parameter is the URL, and the other is from the body. Here is the URL: /offers/40D5E19D-0CD5-4FBD-92F8-43FDBB475333/prices/

Here is my controller code:

 public HttpResponseMessage Put(Guid offerId, OfferPriceParameters offerPriceParameters) { //What!? var ser = new DataContractJsonSerializer(typeof(OfferPriceParameters)); HttpContext.Current.Request.InputStream.Position = 0; var what = ser.ReadObject(HttpContext.Current.Request.InputStream); return new HttpResponseMessage(HttpStatusCode.Created); } 

The body content is in JSON:

 { "Associations": { "list": [ { "FromEntityId":"276774bb-9bd9-4bbd-a7e7-6ed3d69f196f", "ToEntityId":"ed0d2616-f707-446b-9e40-b77b94fb7d2b", "Types": { "list":[ { "BillingCommitment":5, "BillingCycle":5, "Prices": { "list":[ { "CurrencyId":"274d24c9-7d0b-40ea-a936-e800d74ead53", "RecurringFee":4, "SetupFee":5 }] } }] } }] } } 

Any idea why the default binding cannot be bound to the offerPriceParameters argument of my controller? It is always null. But I can recover data from the body using DataContractJsonSerializer .

I am also trying to use the FromBody attribute of the argument, but it does not work either.

+135
asp.net-web-api
Jan 18
source share
13 answers

EDIT: If you are using WebAPI 2 (and hopefully you read this after I have done this editing) see http://www.asp.net/web-api/overview/formats-and-model-binding/ parameter-binding-in-aspnet-web-api .

You cannot do this using WebAPI. See http://www.west-wind.com/weblog/posts/2012/May/08/Passing-multiple-POST-parameters-to-Web-API-Controller-Methods for a detailed introduction to it, as well as with some useful workarounds.

If you are looking "out of the body," you will also find a comment regarding a specific alternative attempt.

+84
Jan 18 '13 at
source share
 [HttpPost] public string MyMethod([FromBody]JObject data) { Customer customer = data["customerData"].ToObject<Customer>(); Product product = data["productData"].ToObject<Product>(); Employee employee = data["employeeData"].ToObject<Employee>(); //... other class.... } 

using the link

 using Newtonsoft.Json.Linq; 

Use query for jQuery Ajax

 var customer = { "Name": "jhon", "Id": 1, }; var product = { "Name": "table", "CategoryId": 5, "Count": 100 }; var employee = { "Name": "Fatih", "Id": 4, }; var myData = {}; myData.customerData = customer; myData.productData = product; myData.employeeData = employee; $.ajax({ type: 'POST', async: true, dataType: "json", url: "Your Url", data: myData, success: function (data) { console.log("Response Data ↓"); console.log(data); }, error: function (err) { console.log(err); } }); 
+61
May 18 '16 at 11:20
source share

In its initial state, the WebAPI does not support binding of several POST parameters. As Colin points out, there are a number of limitations that are outlined in my blog post that he refers to.

There is a workaround by creating a custom binder parameter. The code for this is ugly and confusing, but I posted the code along with a detailed explanation on my blog, ready to connect to the project here:

Passing a few simple POST values ​​to ASP.NET web API

+56
Jan 19 '13 at 10:35
source share

If you use attribute routing, you can use the [FromUri] and [FromBody] attributes.

Example:

 [HttpPost()] [Route("api/products/{id:int}")] public HttpResponseMessage AddProduct([FromUri()] int id, [FromBody()] Product product) { // Add product } 
+20
Jul 10 '15 at 15:22
source share

We passed the Json object using the HttpPost method and analyzed it in a dynamic object. It works great. this is an example code:

 ajaxPost: ... Content-Type: application/json, data: {"AppName":"SamplePrice", "AppInstanceID":"100", "ProcessGUID":"072af8c3-482a-4b1c‌​-890b-685ce2fcc75d", "UserID":"20", "UserName":"Jack", "NextActivityPerformers":{ "39‌​c71004-d822-4c15-9ff2-94ca1068d745":[{ "UserID":10, "UserName":"Smith" }] }} ... 

WebAPI:

 [HttpPost] public string DoJson2(dynamic data) { //whole: var c = JsonConvert.DeserializeObject<YourObjectTypeHere>(data.ToString()); //or var c1 = JsonConvert.DeserializeObject< ComplexObject1 >(data.c1.ToString()); var c2 = JsonConvert.DeserializeObject< ComplexObject2 >(data.c2.ToString()); string appName = data.AppName; int appInstanceID = data.AppInstanceID; string processGUID = data.ProcessGUID; int userID = data.UserID; string userName = data.UserName; var performer = JsonConvert.DeserializeObject< NextActivityPerformers >(data.NextActivityPerformers.ToString()); ... } 

The type of a complex object can be an object, an array, and a dictionary.

+18
Jan 24 '13 at 2:35
source share

You can enable multiple POST parameters using the MultiPostParameterBinding class from https://github.com/keith5000/MultiPostParameterBinding

To use it:

1) Download the code in the Source folder and add it to the web API project or any other project in the solution.

2) Use the [MultiPostParameters] attribute for action methods that must support multiple POST parameters.

 [MultiPostParameters] public string DoSomething(CustomType param1, CustomType param2, string param3) { ... } 

3) Add this line to Global.asax.cs in the Application_Start method before calling GlobalConfiguration.Configure (WebApiConfig.Register) :

 GlobalConfiguration.Configuration.ParameterBindingRules.Insert(0, MultiPostParameterBinding.CreateBindingForMarkedParameters); 

4) Ask your clients to pass parameters as properties of the object. Example JSON object for the DoSomething(param1, param2, param3) method DoSomething(param1, param2, param3) :

 { param1:{ Text:"" }, param2:{ Text:"" }, param3:"" } 

JQuery example:

 $.ajax({ data: JSON.stringify({ param1:{ Text:"" }, param2:{ Text:"" }, param3:"" }), url: '/MyService/DoSomething', contentType: "application/json", method: "POST", processData: false }) .success(function (result) { ... }); 

For more information, visit the link .

Disclaimer: I am directly related to the linked resource.

+8
Oct 26 '15 at 12:32
source share

A simple class of parameters can be used to pass several parameters in a message:

 public class AddCustomerArgs { public string First { get; set; } public string Last { get; set; } } [HttpPost] public IHttpActionResult AddCustomer(AddCustomerArgs args) { //use args... return Ok(); } 
+8
Feb 06
source share

Good question and comments - learned a lot from the answers here :)

As an additional example, note that you can also mix body and routes, for example.

 [RoutePrefix("api/test")] public class MyProtectedController { [Authorize] [Route("id/{id}")] public IEnumerable<object> Post(String id, [FromBody] JObject data) { /* id = "123" data.GetValue("username").ToString() = "user1" data.GetValue("password").ToString() = "pass1" */ } } 

Call:

 POST /api/test/id/123 HTTP/1.1 Host: localhost Accept: application/json Content-Type: application/x-www-form-urlencoded Authorization: Bearer xyz Cache-Control: no-cache username=user1&password=pass1 enter code here 
+5
Aug 24 '16 at 16:39
source share

What does your routeTemplate look like for this case?

You sent this URL:

 /offers/40D5E19D-0CD5-4FBD-92F8-43FDBB475333/prices/ 

For this to work, I would expect such routing in your WebApiConfig :

 routeTemplate: {controller}/{offerId}/prices/ 

Other assumptions: - your controller is called OffersController . - the JSON object that you pass in the request body is of type OfferPriceParameters (not any derived type) - you do not have other methods on the controller that could prevent this (if you do, try to comment on them and see what happens)

And as Philippe mentioned, this will help you with questions if you start accepting some answers, since “accepting a 0% bid” can make people think that they are wasting their time

+1
Jan 19 '13 at 14:48
source share

If you do not want to go with the ModelBinding method, you can use DTO for this. For example, create a POST action in a DataLayer that takes a complex type and sends data from a BusinessLayer. You can do this by calling the UI-> API.

Here is an example of a DTO. Assign a Teacher to a student and assign several documents / obey the Student.

 public class StudentCurriculumDTO { public StudentTeacherMapping StudentTeacherMapping { get; set; } public List<Paper> Paper { get; set; } } public class StudentTeacherMapping { public Guid StudentID { get; set; } public Guid TeacherId { get; set; } } public class Paper { public Guid PaperID { get; set; } public string Status { get; set; } } 

Then the action in the DataLayer can be created as:

 [HttpPost] [ActionName("MyActionName")] public async Task<IHttpActionResult> InternalName(StudentCurriculumDTO studentData) { //Do whatever.... insert the data if nothing else! } 

To call it from BusinessLayer:

 using (HttpResponseMessage response = await client.PostAsJsonAsync("myendpoint_MyActionName", dataof_StudentCurriculumDTO) { //Do whatever.... get response if nothing else! } 

Now it will work if I want to immediately send the data of several Students. Change MyAction as shown below. There is no need to write [FromBody], WebAPI2 by default performs a complex type [FromBody].

 public async Task<IHttpActionResult> InternalName(List<StudentCurriculumDTO> studentData) 

and then calling it, pass the List<StudentCurriculumDTO> data.

 using (HttpResponseMessage response = await client.PostAsJsonAsync("myendpoint_MyActionName", List<dataof_StudentCurriculumDTO>) 
0
Mar 20 '17 at 5:04 on
source share

Request parameters such as

enter image description here

Web api code be like

 public class OrderItemDetailsViewModel { public Order order { get; set; } public ItemDetails[] itemDetails { get; set; } } public IHttpActionResult Post(OrderItemDetailsViewModel orderInfo) { Order ord = orderInfo.order; var ordDetails = orderInfo.itemDetails; return Ok(); } 
0
Mar 31 '19 at 10:44
source share

You can get the form data as a string:

  protected NameValueCollection GetFormData() { string root = HttpContext.Current.Server.MapPath("~/App_Data"); var provider = new MultipartFormDataStreamProvider(root); Request.Content.ReadAsMultipartAsync(provider); return provider.FormData; } [HttpPost] public void test() { var formData = GetFormData(); var userId = formData["userId"]; // todo json stuff } 

https://docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/sending-html-form-data-part-2

0
Aug 18 '19 at 13:24
source share

I also had this problem, I solved it, you can use my NuGet from below from the link:

Frombodyjson

-one
Jul 13 '19 at 9:37
source share



All Articles