MVC 3使用Ajax形式发布模型和HttpPost操作方法的附加参数

时间:2012-08-12 21:20:38

标签: ajax asp.net-mvc razor asp.net-ajax

使用ASP.NET MVC 3和Razor,我有一个针对MyViewModel类的强类型视图。在视图中,我有一个由一组单选按钮组成的AJAX表单。在它下面,我有一个普通的HTML表单,用于收集MyViewModel的数据。根据在AJAX表单中选择的单选按钮,我想用一组默认值或另一组更新HTML表单。在AJAX表单中,我试图发布两个数据:1)表示所选选项的值(基于单选按钮value参数),以及2)视图中的Model 。我希望控制器操作根据收到的选项更新模型,然后返回一个部分视图,其中更新的模型对象作为参数。我该怎么做呢?这是我尝试的AJAX表单的代码:

@using (Ajax.BeginForm("MyAction", "MyController",
        new AjaxOptions {
            HttpMethod = "POST",
            InsertionMode = InsertionMode.Replace,
            UpdateTargetId = "createForm"
        })) 
{
    <div id="formOptions">
        @foreach (Option op in Model.GetOptions()) {
            <div class="editor-field">
            @Html.RadioButton("option", op.OptionType, false, new { @id = op.ID, @name = op.ID, @title = @op.Description, @onfocus = "javascript:$(this).closest('form').find(':submit').first().click()" })
            <label for="@op.ID">@op.Name</label>
            </div>
        }
    </div>
    @Html.Hidden("model", Model)
    <input type="submit" value="Select" style="display:none;" />
}

我的问题是HttPost操作方法中的model参数为null。但是,option参数似乎正确传递。我不确定我是否以不应该使用的方式使用Html.Hidden输入或者问题是什么。如果需要,我可以发布更多代码。

这是我第一次做这样的事情,所以在阅读了很多(貌似)类似的问题之后,我仍然无法解读我想要做的事情的解决方案。我看到很多不同的东西,比如JSON编码,使用JQuery等,但是我不确定我是否需要这些东西,或者我是否可以使用MVC功能实现这一点(我宁愿不重新编写已经存在的东西)内置于MVC 3)。如果有人能指出我正确的方向或可能给出一些代码示例,我们将不胜感激。而且,鉴于我的最终目标是什么,如果有一种更好的方法来基于选项控件异步更新表单,我会非常有兴趣听到它。谢谢!

编辑:

我还注意到使用HttpPost的请求不会进入控制器,但是HttpGet会这样做。有谁在那里?这让我疯了!

增加控制器方法:

public PartialViewResult CreateForm(OptionType opType, MyViewModel model) {
    model.ApplyOptionValues(opType);
    return PartialView("_CreateForm", model);
}

2 个答案:

答案 0 :(得分:0)

我不会将整个模型发回给您尝试使用@Html.Hidden("model", Model)的控制器,只需在表单中放置您需要的特定项目,其名称/类型与您的控制器匹配。您可以使用所选单选按钮的值以及隐藏输入的值将标识信息传递给控制器​​,并执行您需要的任何逻辑。

话虽这么说,我认为最好的解决方案是使用一些像JQuery这样的javascript框架来处理所有的AJAX请求。 Asp.net MVC使用内置部件进行简单操作变得非常容易,但是一旦你需要执行更复杂的操作,它肯定会失败。与使用正确的工具(JQuery)相比,您最终会在限制范围内付出更多努力。

确保使用[HttpPost]注释POST操作方法,以区别于GET方法。

还可以使用详细的Web调试器来准确检查发送到应用程序的内容。我喜欢Fiddler,这是非常受欢迎的。 http://www.fiddler2.com/fiddler2/

答案 1 :(得分:0)

我同意Mattbo的说法:将整个模型放在一个圆圈中是不必要的开销。你不会说你为什么,但我怀疑它是如此,你可以比较旧的&#39;和&#39;新&#39;值。鉴于模型源自控制器,您可以在ViewModel中包含模型的唯一标识符(例如GUID),将其放在隐藏字段中以包含在POST数据中,然后在返回POST中包含您的&#39; new&# 39;数据将自动映射到强类型的ViewModel。然后,您可以重新获取原始模型,并随心所欲地执行任何操作。

处理AJAX表单是一个单独的问题/形式:你有你的单选按钮,在(查看模型)表单中填写默认值(包括一个隐藏字段来记录选择了哪个收音机),用户填写其他数据和整个(非ajax)表单将发布到MyController.MyAction方法,默认绑定器将自动将表单值映射到MyViewModel,如果它们遵循正确的命名约定。所以AJAX与实际发布的表单无关。另外,你可以用AJAX来完成整个事情,Mattbo也建议。

[旁白]请原谅我,如果你已经知道,但你可以使用剃刀Html助手来创建你的字段:

@Html.EditorForModel()
@Html.EditorFor(model => model.[field name])

在Controller中,您将创建以下操作:     public ActionResult MyAction()     {       MyViewModel     }

[HttpPost]
public ActionResult MyAction(MyViewModel myModel)