【问题标题】:Getting input from a ViewUserControl back to the controller on submit在提交时将输入从 ViewUserControl 返回到控制器
【发布时间】:2014-10-28 10:13:31
【问题描述】:

我承认我是 MVC 的新手,这个问题可能是 RTFM 的一个案例。但我正在谷歌搜索这个问题,但似乎找不到解决方案。

我有一个简单的视图,用于填写特定模型的一些详细信息。我需要使用Html.Partial 渲染表单的一部分(实际上,这是一个包装器,用于渲染来自另一个项目的旧的非 MVC 控件)。

从控制器获取数据到视图中没有问题。

那么问题是什么?用户按下提交按钮后,如何将用户输入从局部视图返回到控制器?


这是我目前拥有的视图和控制器:

@model Poll

@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()

    <div class="form-horizontal">
        <h4>Poll</h4>
        <hr />
        @*@Html.ValidationSummary(true)*@
        @Html.HiddenFor(m => m.Id)
        @Html.HiddenFor(m => m.Name)
        @Html.Partial("~/ControlPlaceholder/QuestionPlaceholder.ascx", Model, new ViewDataDictionary(Model))

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Fill" class="btn btn-default" />
            </div>
        </div>
    </div>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

视图已从 MVC5 中可用的标准生成编辑视图几乎一对一地复制。请注意,这目前只是一个 PoC - 通常整个事情应该为Poll 中的每个问题呈现一个QuestionPlaceholder

这是控制器的相关部分:

    //
    // GET: /Poll/Fill
    [HttpGet]
    public ActionResult Fill(Guid id)
    {
        var poll = pollRepository.Get(id);
        return View(poll);
    }

    //
    // POST: /Poll/Fill
    [HttpPost]
    public ActionResult Fill(Poll poll, FormCollection collection)
    {
        try
        {
            return RedirectToAction("Index");
        }
        catch
        {
            return View(poll);
        }
    }

【问题讨论】:

  • 你需要包含你的视图和控制器
  • 只要您使用与您的模型属性名称匹配的名称属性部分呈现输入,那么它们就会绑定到您的模型。但你提到了一系列问题。在这种情况下,使用部分将不起作用,因为它不会正确索引您的属性,如果您在部分中有任何复选框,FormCollection 也不起作用。注意你不需要@Html.Partial 中的第三个参数(你已经在第二个参数中传递了模型)
  • @StephenMuecke 我知道第三个参数 - 那是我在试图让事情坚持下去。如果可能的话,我希望 QuestionPlaceholder 始终返回一个字符串(在最极端的情况下可能是 JSON) - 但是,该字符串需要从底层控件“解析”,我有点迷路了。
  • 为 typeof Question 创建一个 EditorTemplate 并让所有内容正确绑定不是更容易吗?
  • @StephenMuecke 这可能会更容易......假设我不必与其他项目共享问题控件。事实上,问题控件与另一个非 MVC 项目共享,这就是为什么我有一个占位符来加载它们,我需要以某种方式依赖它。

标签: c# asp.net-mvc model-view-controller asp.net-mvc-5


【解决方案1】:

很简单,只需将输入的名称设置为相应的动作参数,然后让 MVC ModelBinder 完成它的工作。在表单中渲染部分并不重要,它的输入元素值将传递给提交表单的操作。 另一种方法是使用 Request.Form["InputName"] 这不是我的第一个建议。

【讨论】:

  • 由于我使用占位符来呈现老式输入控件,我不认为依靠自动化ModelBinder 是个好主意...
  • 你为什么这么认为?试试看。
  • 因为问题是使用@foreach 生成的,所以我无法指定 ID,因为它们会重复。理想情况下,当用户按下提交时,我希望每个占位符“处理”它的内容。
  • 可以在动作参数中以类型数组的形式访问具有相同名称的 ID,它可以帮助您使用索引等技巧并获取每个占位符输入的值。
  • 我检查了返回给控制器的内容。首先,MVC 改变了 ID,checkChoice 变成了1_ctl00_checkChoice。但是,更糟糕的是,只有来自第一个问题的输入被发送到控制器(就像 Stephen Muecke 在 cmets 中提到的那样)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-15
  • 1970-01-01
相关资源
最近更新 更多