MVC Html.HiddenFor在循环中将模型传递回Controller

时间:2017-07-31 00:08:20

标签: c# asp.net-mvc submit

我正在遍历我的模型的IEnumerable:

// getArticle {{{
  /**
   * Handles the view of an article
   *
   * @param {HTTP} request
   * @param {HTTP} response
   */
  getArticle: function (request, response) {
    /**
     * Get the article matching the given URL
     *
     * @async
     * @returns {Promise} Promise containing the article
     */
    async function getArticle () {
      let url = request.params.url

      return Article
        .findOne({ url: url })
        .populate('category', 'title')
        .exec()
    }

    /**
     * Asynchronous execution block
     *
     * @async
     * @throws Will throw an error to the console if it catches one
     */
    (async function () {
      try {
        let article = await getArticle()

        response.render('blog/article', {
          title: article.title,
          article: article
        })
      } catch (error) {
        console.log(error)
      }
    }())
},

并在提交时我想将我选择的模型实例传回给我的控制器:

@model IEnumerable<Testing.Models.ProductItem>
@{
    ViewBag.Title = "Buy Products";
}

<div class="row">
    @foreach (var product in Model)
    {
        using (Html.BeginForm())
        {
            @Html.HiddenFor(Model => product)
            ... More Controls and stuff...
            <input type="submit" value="Add To Kart" class="btn btn-info">

        }

    }
</div>

但是我尝试了一些东西,但似乎总是将null传递给控制器​​......请有人请帮助我指出正确的方向吗?

修改

我实际上并不需要完整的模型实例,因为我可以从控制器中获取ID - 所以我尝试了以下内容:

    [HttpPost]
    public ActionResult Index(ProductItem product)
    {
        ... Do Stuff ...
        return View();
    }

发布到控制器:

@model IEnumerable<Testing.Models.ProductItem>
@{
    ViewBag.Title = "Buy Products";
}

<div class="row">
    @foreach (var product in Model)
    {
        using (Html.BeginForm())
        {
            @Html.HiddenFor(Model => product.ID)
            @Html.TextBox("qty", "1", htmlAttributes: new { @style = "width: 30px;" })

            ... More Controls and stuff...

            <input type="submit" value="Add To Kart" class="btn btn-info">

        }

    }
</div>

文本框不是模型的一部分,因为它是用户输入 - 这个值很好地传递给actions参数,但是我仍然在HiddenFor控件中获取null。这与控件的命名有关吗?我似乎无法为HiddenFor控件添加名称。

我知道这对原始问题有所不同,但我希望你仍然可以提供帮助。

我注意到BeginForm在循环中 - 为列表中的每个项目创建...是否有一个简单的替代方法(注意我还没有尝试过任何东西)。

3 个答案:

答案 0 :(得分:2)

听起来你正试图在复杂的类型上使用HiddenFor并且不会起作用。您需要使用像ProductId这样的ProductItem属性,或类似的东西,很可能是int或Guid。

现在您已经清除了对简单字段的复杂绑定,您会注意到您的名称已设置为product.id,这就是为什么它在控制器中始终为null。您无法使用Hidden for覆盖name属性,因此您希望将代码更改为:

final

答案 1 :(得分:0)

我已设法通过以下方式达到我想要的功能(正确或错误):

@model List<ShoppingKartTest.Models.ProductItem>
@{
    ViewBag.Title = "Buy Products";
}



@foreach (var item in Model)
{
    using (Html.BeginForm())
    {

       <input type="hidden" value="@item.ID" name="ID" />
       @Html.TextBox("qty", "1", new { @style = "width: 30px;" })


       <input type="submit" value="Add To Kart" class="btn btn-info">
    }
}

正确地将隐藏ID和文本框内容提交给Controller Action:

[HttpPost]
public ActionResult Index(int ID, int qty)
{
    //... Do stuff with parameters...
    return View();
}

我很想听听有关这方面的任何意见。我知道上面有人告诉我,我不应该在循环中使用我的BeginForm ......但它对我有效。

答案 2 :(得分:-1)

而不是Model =&gt; product.Id,试试p =&gt; product.Id

   @model IEnumerable<Testing.Models.ProductItem>
   @{
       ViewBag.Title = "Buy Products";
    }

    <div class="row">
    using (Html.BeginForm())
    {
       @foreach (var product in Model)
       {
             @Html.HiddenFor(p => product.ID)
             @Html.TextBox("qty", "1", htmlAttributes: new { @style = "width: 
           30px;" })

            ... More Controls and stuff...         

        }
        <input type="submit" value="Add To Kart" class="btn btn-info">
    }
    </div>