怎样的产品和数量传递给ASP.NET MVC4的Web API的形式提交数量、形式、产品、API

2023-09-11 01:40:01 作者:拥有迩的美

ASP.NET MVC4应用程序允许用户输入订购的产品数量和他们passses到 网络API控制器。

控制器接收空的产品清单产品的参数。调试器显示的数据公布。 如何重构视图,使产品能够通过对Web API?

查看:

  @inherits ViewBase< MyApp.MobileOrderOrderViewModel>
<!DOCTYPE HTML>
< HTML>
<身体GT;
    @using(Html.BeginForm())
    {
        <表>
            @for(INT I = 0; I< Model.Products.Count;我++)
            {
                &其中; TR>
                    < TD> @ Model.Products [I] .ID< / TD>
                    < TD>
                        @ Html.HiddenFor(M => Model.Products [I] .ID)
                        @ Html.TextBoxFor(M => Model.Products [I] .Quantity,新{@类=数量,类型=​​数字,最小= 0})
                    < / TD>
                < / TR>
            }
        < /表>
        <输入类型=提交值=发送订单>
        @ Html.HiddenFor(M => Model.CustomerId)
    }


<脚本>
    $(函数(){
        使用严格;
        VAR BASE_URL ='@ Url.Content(〜/);
        $(形式)。递交(函数(EV){
            变种elementsToSend = [];
            。EV preventDefault();
            VAR quantityElements = $(input.quantity)。过滤器(功能(索​​引,元){
                如果($(本).VAL()!= 0){
                    返回true;
                }
                其他 {
                    返回false;
                }
            });

            $每个(quantityElements,功能(索引,元){
                。变种productIdElement = $(元件)prevAll()[0];
                elementsToSend.push(productIdElement);
                elementsToSend.push(元);
            });
            VAR dataToPost = $(elementsToSend).serializeArray();
            $。员额(BASE_URL +API /订购?+ $ .PARAM({
                klient:$(#客户ID)VAL()。
            }),dataToPost);
        });
    })
< / SCRIPT>
 

视图模型:

 公共类MobileOrderOrderViewModel:ViewModelBase
{
    公共字符串客户ID {获得;组; }

    公开名单< OrderedItems>产品{获得;组; }

 公共MobileOrderOrderViewModel(字符串客户){
    客户ID =客户;
    ...填充从数据库产品属性
    }

}
 
ASP.NET MVC4中调用WEB API的四个方法

型号:

 公共类OrderedItems
    {
        公共字符串ID;
        公共小数数量;
    }
 

的WebAPI控制器:

 公共类OrderController:ApiController
    {

        公众的Htt presponseMessage邮报(字符串客户ID,[FromBody]名单,其中,OrderedItems>产品){
   //为什么products.Count()为0吗?
  ...
   }
}
 

更新

我根据答案修改code。警报()显示字符串是在回答中描述的格式,但产品参数仍然是空的。

铬表明请求类型是

内容类型:应用程序/ x-WWW的形式urlen codeD;

但缓冲区包含JSON字符串。也许这混淆的Web API。如何解决?

  $每个(quantityElements,功能(索引,元){
            。变种productIdElement = $(元件)prevAll()[0];
            变种产品= {
                ID:$(productIdElement).VAL()
                数量:$(元素).VAL()
            };
            elementsToSend.push(产品);
        });

        VAR dataToPost = JSON.stringify(elementsToSend);
        $。员额(BASE_URL +API /订购?+ $ .PARAM({
            客户ID:$(#客户ID)VAL()。
        }),dataToPost);
 

解决方案

现在的问题是与您的数据序列化。

为了得到适当的绑定它必须以下面的格式:

 产品:
              {ID:1,量:20},
              {ID:5,量:100},
              ...
             ]
 

在你的情况下code产生错误的输出:

  $每个(quantityElements,功能(索引,元){
                。变种productIdElement = $(元件)prevAll()[0];
                elementsToSend.push(productIdElement);
                elementsToSend.push(元);
            });
 

如果我'不是错了,它会产生如下:

  [
   {名字:ID [1],值为:1},
   {名字:量[1],值:20}
   {名字:ID [2],值:5},
   {名字:量[2],值:100}
   ...
]
 

您可以通过类似解决这个问题:

  $。每个(quantityElements,功能(索引,元){
      。变种productIdElement = $(元件)prevAll()[0];
      变种产品= {
           ID:$(productIdElement).VAL()
           数量:$(元素).VAL()
       };

       products.push(产品);
 });
 

比,而不是 serializeArray()使用 JSON.stringify(产品)

更新

试着用发送到服务器:

  $交(BASE_URL +API /订购?+ $(#客户ID)VAL(),产品。);
 

PS在这种情况下,你不必字符串化产品反对,因为。$交支持纯对象作为以及

ASP.NET MVC4 applications allows to enter ordered product quantities and passses them to Web API controller.

Controller receives empty product list as product parameter. Debugger shows that data is posted. How to refactor view so that products can passed to Web API ?

View:

@inherits ViewBase<MyApp.MobileOrderOrderViewModel>
<!DOCTYPE html>
<html>
<body>
    @using (Html.BeginForm())
    {
        <table>
            @for (int i = 0; i < Model.Products.Count; i++)
            {
                <tr>
                    <td>@Model.Products[i].Id</td>
                    <td>
                        @Html.HiddenFor(m => Model.Products[i].Id)
                        @Html.TextBoxFor(m => Model.Products[i].Quantity, new { @class="quantity", type = "number", min = 0 })
                    </td>
                </tr>
            }
        </table>
        <input type="submit" value="Send order">
        @Html.HiddenFor(m => Model.CustomerId)
    }


<script>
    $(function () {
        "use strict";
        var BASE_URL = '@Url.Content("~/")';
        $("form").submit(function (ev) {
            var elementsToSend = [];
            ev.preventDefault();
            var quantityElements = $("input.quantity").filter(function (index, element) {
                if ($(this).val() != 0) {
                    return true;
                }
                else {
                    return false;
                }
            });

            $.each(quantityElements, function (index, element) {
                var productIdElement = $(element).prevAll()[0];
                elementsToSend.push(productIdElement);
                elementsToSend.push(element);
            });
            var dataToPost = $(elementsToSend).serializeArray();
            $.post(BASE_URL + "api/Order?" + $.param({
                klient: $("#CustomerId").val()
            }), dataToPost);
        });
    })
</script>

ViewModel:

public class MobileOrderOrderViewModel : ViewModelBase
{
    public string CustomerId { get; set; }

    public List<OrderedItems> Products { get; set; }

 public MobileOrderOrderViewModel( string customer ) {
    CustomerId = customer;
    ... populate Products property from database
    }

}

Model:

    public class OrderedItems
    {
        public string Id;
        public decimal Quantity;
    }

WebAPI Controller:

    public class OrderController :ApiController
    {

        public HttpResponseMessage Post(string customerid, [FromBody]List<OrderedItems> products) {
   // Why  products.Count() is 0 here ?
  ...
   }
}

Update

I changed code according to answer. alert() shows that string is in format described in answer but products parameter is still empty.

chrome shows that request type is

Content-Type:application/x-www-form-urlencoded;

but buffer contains json string. Maybe this confuses Web API. How to fix ?

        $.each(quantityElements, function (index, element) {
            var productIdElement = $(element).prevAll()[0];
            var product = {
                id: $(productIdElement).val(),
                quantity: $(element).val()
            };
            elementsToSend.push(product);
        });

        var dataToPost = JSON.stringify(elementsToSend);
        $.post(BASE_URL + "api/Order?" + $.param({
            customerid: $("#CustomerId").val()
        }), dataToPost);

解决方案

The problem is with your data serialization.

In order to be properly binded it has to be in the following format:

"products" : [ 
              {"id":1, "quantity":20},
              {"id":5, "quantity":100},
              ...
             ]

In your case the following code produces a wrong output:

 $.each(quantityElements, function (index, element) {
                var productIdElement = $(element).prevAll()[0];
                elementsToSend.push(productIdElement);
                elementsToSend.push(element);
            });

If I'am not wrong it produces something like:

[ 
   {name:"id[1]", value:1},
   {name:"quantity[1]", value:20}
   {name:"id[2]", value:5},
   {name:"quantity[2]", value:100}
   ...
]

You can fix this by something like:

$.each(quantityElements, function (index, element) {
      var productIdElement = $(element).prevAll()[0];
      var product = {
           id : $(productIdElement).val(),
           quantity : $(element).val()
       };

       products.push(product);
 });

Than instead of serializeArray() use JSON.stringify(products)

UPDATE

Try posting it to the server with:

$.post(BASE_URL + "api/Order?" + $("#CustomerId").val(), products);

P.S in this case you don't have to stringify products object because .$post supports plain objects as well