HTTP GET请求中的MVC3模型绑定?

没有定制,我可以在MVC 3中做这样的事情吗?

[HttpGet] public ViewResult MyAction(ViewModel model) { // Do stuff return View("ViewName", model); } 

我这样做的原因是作为工作流程的一部分在不同页面之间传递数据。 (即当用户在步骤1中查看所需内容时,将表单数据传递给第2步…)

只要您具有与Model类的Property name相同的参数Name,它就会起作用

假设你的class级是这样的

 public class ViewModel { public string Name { set;get;} public string Loc{ set;get;} } 

你可以这样做一个Get请求

 MyAction?Name=jon&Loc=America 

你能行的; 它会自动将查询字符串中的任何值绑定到具有匹配名称的属性。

也就是说,这不是通常做的事情; 它是[HttpPost]方法,您可以看到执行的模型绑定,因为两个操作的接口需要以某种方式不同。 您可以通过回发到不同的操作名称来解决此问题,但您仍可能在模型的(部分)加载上触发模型validation错误,这对用户来说确实很混乱。

只有端点的方法签名中的类成员仅包含标量属性时,Shyju的答案才有效。 但是如果你有嵌套类呢? 我们假设您的ViewModel类如下所示:

 public class ViewModel { public string Name { get; set; } public string Title { get; set; } public Address MyAddress { get; set; } } 

Address类看起来像这样:

 public class Address { public string Line1 { get; set; } public string Line2 { get; set; } } 

现在让我们说GET请求是通过AJAX完成的,你在JavaScript中做了类似的事情:

 var address = { Line1: "123 Nowhere St.", Line2: "Apt. B5" } var getRequestData = { Name: "Joe", Title: "Manager", MyAddress: address } var uriString = $.param(getRequestData); //the parameters for the GET request $.get("/ViewResult?" + uriString, function (data) { /*callback function*/ }); 

尽管JavaScript中address对象的形状与端点方法签名中的C# Address类完全匹配,但Line1Line2子属性不会绑定。 他们的价值观将null

有两种解决方法。

解决方法1:

第一种是在命名GET请求中的参数而不是嵌套的JavaScript对象时使用点表示法。 使用此方法,AJAX中的GET请求数据如下所示:

 var getRequestData = { Name: "Joe", Title: "Manager", MyAddress.Line1: "123 Nowhere St.", MyAddress.Line2: "Apt. B5" } 

MVC模型绑定将知道如何执行此操作,只要所有属性名称都匹配(它们区分大小写,所以要小心)。

如果你没有使用AJAX,只提交一个简单的HTML表单,那就更容易了。 只需使用相同的点表示法命名输入元素。 使用诸如TextBoxFor()类的辅助方法,Razor语法非常简单,但这是纯HTML中的一个示例:

 

解决方法2:

另一种方法是简单地使用POST请求而不是GET。 请注意,执行POST请求而不是实际更改服务器端的某些数据是技术上不好的做法,但这是一个选项。

您可以通过将PostMethod属性设置为get来将表单发布到get。 如果表单的输入字段与任何接受的ViewModel匹配,那么它们将被填充。 这些匹配由输入中的name字段确定( – > public string MatchedField { get; set; } )。

你应该做的是从post传递表单,然后重定向到post post的get。 此模式是最佳实践,称为Post-Redirect-Get模式。

我会反对这种做法。 使用POST的最佳解决方案,因为如果您使用GET,一旦您从步骤3单击回到步骤2并且浏览器缓存不可用,您将对旧版本的ViewModel执行操作。 你有没有想要使用GET的特殊原因?

我不能建议使用QueryString传递值。 您可以使用以下方法之一:此代码将呈现给定模型的局部视图。确保将视图添加到视图中。 您的视图应放在Shared文件夹中

 public ActionResult myaction(ViewModel model) { return PartialView("anotherView", model); } 

另一种做同样事情的方法:

  public ActionResult myaction(ViewModel model) { return View("someAnotherView", model); } 

如果您的视图不在同一个控制器中,请使用视图名称的路径,如"../Controller/viewName"

还有一种不同的方法可以通过使用TempData来完成:

 public ActionResult myaction(ViewModel model) { TempData["model"] = model; return RedirectToAction("someAnotherView"); } 

但您应该使用如下所示的代码在视图中访问您的数据:

  @{ ViewModel model=(ViewModel)TempData["model"]; } 

希望上面的一个有帮助..

问候

对于Web API 2:

 [HttpGet] public ActionResult Get([FromUri]ViewModel model) { // Do stuff return View("ViewName", model); }