在表单回发的mvc4控制器中,id为null

时间:2014-03-10 18:40:18

标签: c# asp.net asp.net-mvc asp.net-mvc-4 razor

我正在尝试向购物车控制器发送一些值,但是当我试图在购物车控制器中访问它们时,它们在控制器中为空,尽管我在视图中的隐藏字段中具有正确值。 当我尝试将商品添加到购物车时,就会发生这种情况。 这就是我所拥有的:

Razor观点:

@using Solution.Order.Models
@model IEnumerable<CategoriesViewModel>

@{
    ViewBag.Title = "Categories";
}
@using (Html.BeginForm())
{
       <div class="panel-group">                   
    @foreach (var m in Model)
    {
        <div class="panel panel-default">
            <div class="panel-heading">
                <h4 class="panel-title">
                    <a data-toggle="collapse" id="#accordion" data-parent="#accordion" href="#@m.Categories.ID.ToString()">
                        @m.Categories.Name <span class="badge">@m.Categories.ItemCount</span>
                    </a>                     
                </h4>
            </div>
            <div id="@m.Categories.ID.ToString()" class="panel-collapse collapse">                
                <div class="panel-body">
                    <ul class="list-group">
                        @foreach (var i in m.Items)
                        {                            
                            <li class="list-group-item">
                                @i.Name | Price £@i.Price 

                                @using (Html.BeginForm("AddToCart", "Cart"))
                                {
                                    <div class="pull-right">
                                        @Html.HiddenFor(k => @i.Id)
                                        @Html.Hidden("returnUrl", Request.Url.PathAndQuery)
                                        <input type="submit" class="btn btn-success" value="Add"/>
                                    </div>
                                }
                            </li>                            
                        }
                    </ul>  
                </div>
            </div>
        </div>     
    }        
</div>                                  
}

<script>
    $(document).ready(function() {
        $('#accordion').on('click', function() {
            $('#accordion .in').collapse('hide');
        });
    });
</script>

控制器内容:

public RedirectToRouteResult AddToCart(Guid? Id, string returnUrl)
    {
        RestItem itemSingle = restItem.Items.FirstOrDefault(p => p.Id == Id);
        if (itemSingle != null)
        {
            GetCart().AddItem(itemSingle, 1);
        }
        return RedirectToAction("Index", new {returnUrl});
    }

在控制器中,Id值为null,但是当我查看页面的来源时,我能够看到id的隐藏值:

enter image description here

由于我仍然试图找到在MVC中开发的最佳方法,我所采用的方法可能不是最好的方法,因此我非常感谢每一条评论。 在此先感谢Laziale

2 个答案:

答案 0 :(得分:1)

表单中的输入字段包含名称i.Id”,但您的操作方法需要名称仅为Id的参数.MVC模型绑定需要您将名称属性值作为参数名称。

您可以明确保留具有匹配名称的隐藏字段

@foreach (var m in Model)
{
  <h4>Items</h4>
  <ul>
  @foreach(var i in m.Items)
  {
   <li>
     <h4>@i.Name | Price @i.Price</h4>
     @using(Html.BeginForm())
     {
       <div> 
          <input type="submit" class="btn btn-success" value="Add"/>
          @Html.Hidden("returnUrl", Request.Url.PathAndQuery)  

          <input type="hidden" name="Id" value="@m.Id" />   

       </div>
     }
    </li>
  }
}

这应该有效,假设你的Item的Id属性是Guid类型。

此外,您的外部表单标签不再使用。你可以删除它。如果没有看到你的viewmodel类,我将无法说你做错了/ rite。

很少有建议

  • 如果您在循环中显示多个项目,请考虑使用EditorTemplates。
  • 在这种特殊情况下,我更喜欢避免剃刀中的多个表格标签 在javascript中查看并捕获提交按钮单击事件并阅读 隐藏的变量值(对于returnUrl和itemId)和重定向 用户使用新的动作方法(因为你不担心 将操作方法​​保持为HttpPost属性。

答案 1 :(得分:0)

在此上下文中,您无法使用@Html.HiddenFor()帮助程序。您希望该字段的名称最终为Id,但正如您所看到的那样令人困惑且名称为i.Id。您应该像在下一行一样使用@Html.Hidden()方法。