如果没有自定义,我可以在 MVC 3 中做这样的事情吗?
[HttpGet]
public ViewResult MyAction(ViewModel model)
{
// Do stuff
return View("ViewName", model);
}
我这样做的原因是作为工作流程的一部分在不同页面之间传递数据。(即当用户完成步骤 1 中需要的内容时,将表单数据传递到步骤 2...)
如果没有自定义,我可以在 MVC 3 中做这样的事情吗?
[HttpGet]
public ViewResult MyAction(ViewModel model)
{
// Do stuff
return View("ViewName", model);
}
我这样做的原因是作为工作流程的一部分在不同页面之间传递数据。(即当用户完成步骤 1 中需要的内容时,将表单数据传递到步骤 2...)
只要您具有与模型类的属性名称相同的参数名称,它就会起作用
假设你的课是这样的
public class ViewModel
{
public string Name { set;get;}
public string Loc{ set;get;}
}
您可以像这样执行获取请求
MyAction?Name=jon&Loc=America
只有当端点方法签名中的类成员仅包含标量属性时,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*/ });
即使address
JavaScript 中对象的形状Address
与端点方法签名中的 C# 类完全匹配, theLine1
和Line2
子属性也不会绑定。他们的价值观将通过null
.
有两种解决方法。
第一种是在命名 GET 请求中的参数时使用点表示法,而不是嵌套的 JavaScript 对象。使用此方法,AJAX 中的 GET 请求数据将如下所示:
var getRequestData = {
Name: "Joe",
Title: "Manager",
MyAddress.Line1: "123 Nowhere St.",
MyAddress.Line2: "Apt. B5"
}
MVC 模型绑定将知道如何执行此操作,只要您的所有属性名称都匹配(它们区分大小写,所以要小心)。
如果您不使用 AJAX,而只是简单的 HTML 表单提交,那就更容易了。只需使用相同的点符号命名输入元素。Razor 语法使用 帮助方法使这变得非常容易TextBoxFor()
,但这里有一个纯 HTML 的示例:
<form method="get" action="/ViewResult">
<input type="text" name="Name" />
<input type="text" name="Title" />
<input type="text" name="MyAddress.Line1" />
<input type="text" name="MyAddress.Line2" />
<button type="submit">Submit GET request</button>
</form>
解决此问题的另一种方法是简单地使用 POST 请求而不是 GET。请注意,在不打算实际更改服务器端的某些数据的情况下执行 POST 请求在技术上是不好的做法,但这是一种选择。
你能行的; 它会自动将查询字符串中的任何值绑定到具有匹配名称的属性。
也就是说,这不是通常会做的事情。这是[HttpPost]
您看到模型绑定执行的方法,因为两个操作的接口需要以某种方式不同。您可以通过回发到不同的操作名称来解决这个问题,但是您仍然可能在模型的(部分)加载时触发模型验证错误,这会让用户感到非常困惑。
对于 Web API 2:
[HttpGet]
public ActionResult Get([FromUri]ViewModel model)
{
// Do stuff
return View("ViewName", model);
}
您可以通过将PostMethod
属性设置为 get 将表单发布到 get。如果表单的输入字段与任何接受匹配,ViewModel
则它们将被填写。这些匹配由name
输入 ( <input name="MatchedField">
-> public string MatchedField { get; set; }
) 中的字段确定。
您应该做的是从帖子传递表单,然后重定向到从帖子操作中获取。此模式是最佳实践,称为 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"];
}
希望以上之一有帮助..
问候