WebAPI多个Put/Post参数

Nor*_*ard 139 .net asp.net-web-api

我试图在WebAPI控制器上发布多个参数.一个参数来自URL,另一个参数来自正文.这是网址: /offers/40D5E19D-0CD5-4FBD-92F8-43FDBB475333/prices/

这是我的控制器代码:

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);
}
Run Code Online (Sandbox Code Playgroud)

正文的内容是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
                        }]
                    }
                }]
            }
        }]
    }
}
Run Code Online (Sandbox Code Playgroud)

知道为什么默认绑定无法绑定到offerPriceParameters我的控制器的参数?它始终设置为null.但是我能够使用the从身体恢复数据DataContractJsonSerializer.

我也尝试使用FromBody参数的属性,但它也不起作用.

Fat*_*DAL 62

[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....
}
Run Code Online (Sandbox Code Playgroud)

使用referance

using Newtonsoft.Json.Linq;
Run Code Online (Sandbox Code Playgroud)

使用Request 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);
    }
});
Run Code Online (Sandbox Code Playgroud)

  • 好的解决方案 如果其他人还不清楚,如果从ajax调用中传入简单的多个参数,也可以使用.ToObject <int>(),. ToObject <decimal>(),. ToString()等. (2认同)

Ric*_*ahl 58

本机WebAPI不支持绑定多个POST参数.正如科林指出的那样,我在博客文章中提到了许多限制.

通过创建自定义参数绑定器可以解决此问题.执行此操作的代码是丑陋和令人费解的,但我已经在我的博客上发布了代码以及详细解释,准备插入到项目中:

将多个简单POST值传递给ASP.NET Web API

  • 截至 2019 年,它现在确实如此。 (2认同)

Bry*_*ner 21

如果正在使用属性路由,则可以使用[FromUri]和[FromBody]属性.

例:

[HttpPost()]
[Route("api/products/{id:int}")]
public HttpResponseMessage AddProduct([FromUri()] int id,  [FromBody()] Product product)
{
  // Add product
}
Run Code Online (Sandbox Code Playgroud)

  • 我正在使用 aspnetcore,你必须使用 `[FromRoute]` 而不是 `[FromUri]` (4认同)

Bes*_*Ley 18

我们通过HttpPost方法传递Json对象,并在动态对象中解析它.它工作正常.这是示例代码:

[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());

   ...
}
Run Code Online (Sandbox Code Playgroud)

的WebAPI:

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"
           }]
       }}
...
Run Code Online (Sandbox Code Playgroud)

复杂的对象类型可以是对象,数组和字典.


Kei*_*ith 8

您可以使用https://github.com/keith5000/MultiPostParameterBinding中的MultiPostParameterBinding类来允许多个POST参数

要使用它:

1)下载Source文件夹中的代码,并将其添加到Web API项目或解决方案中的任何其他项目.

2)在需要支持多个POST参数的操作方法上使用属性[MultiPostParameters].

[MultiPostParameters]
public string DoSomething(CustomType param1, CustomType param2, string param3) { ... }
Run Code Online (Sandbox Code Playgroud)

3)在调用GlobalConfiguration.Configure(WebApiConfig.Register)之前的任何地方,将Global.asax.cs中的这一行添加到Application_Start方法:

GlobalConfiguration.Configuration.ParameterBindingRules.Insert(0, MultiPostParameterBinding.CreateBindingForMarkedParameters);
Run Code Online (Sandbox Code Playgroud)

4)让您的客户将参数作为对象的属性传递.该DoSomething(param1, param2, param3)方法的示例JSON对象是:

{ param1:{ Text:"" }, param2:{ Text:"" }, param3:"" }
Run Code Online (Sandbox Code Playgroud)

示例JQuery:

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

请访问该链接了解更多详情.

免责声明:我与链接资源直接关联.


Gre*_*Gum 8

一个简单的参数类可用于传递帖子中的多个参数:

public class AddCustomerArgs
{
    public string First { get; set; }
    public string Last { get; set; }
}

[HttpPost]
public IHttpActionResult AddCustomer(AddCustomerArgs args)
{
    //use args...
    return Ok();
}
Run Code Online (Sandbox Code Playgroud)


Ant*_*uza 5

好的问题和评论-从这里的回复中学到了很多:)

作为另一个示例,请注意,您还可以将车身和路线混合使用,例如

[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"
         */
    }
}
Run Code Online (Sandbox Code Playgroud)

像这样调用:

POST /api/test/id/123 HTTP/1.1
Host: localhost
Accept: application/json
Content-Type: application/x-www-form-urlencoded
Authorization: Bearer x.y.z
Cache-Control: no-cache

username=user1&password=pass1


enter code here
Run Code Online (Sandbox Code Playgroud)


Loa*_*ron 5

2021 年,出现了新的解决方案。Pradip Rupareliya 提出了一个很好的建议,我将仅使用 Dict 进行补充,而不是像他那样使用辅助数据结构:

[HttpPost]
public ActionResult MakePurchase([FromBody] Dictionary<string, string> data)
{
    try
    {
        int userId = int.Parse(data["userId"]);
        float boughtAmountInARS = float.Parse(data["boughtAmountInARS"]);
        string currencyName = data["currencyName"];
    }
    catch (KeyNotFoundException)
    {
        return BadRequest();
    }
    catch (FormatException)
    {
        return BadRequest();
    }
}
Run Code Online (Sandbox Code Playgroud)