8

如果没有自定义,我可以在 MVC 3 中做这样的事情吗?

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

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

4

7 回答 7

10

只要您具有与模型类的属性名称相同的参数名称,它就会起作用

假设你的课是这样的

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

您可以像这样执行获取请求

MyAction?Name=jon&Loc=America
于 2012-08-15T19:39:30.920 回答
2

只有当端点方法签名中的类成员仅包含标量属性时,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*/ });

即使addressJavaScript 中对象的形状Address与端点方法签名中的 C# 类完全匹配, theLine1Line2子属性也不会绑定。他们的价值观将通过null.

有两种解决方法。

解决方法 1:

第一种是在命名 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>

解决方法 2:

解决此问题的另一种方法是简单地使用 POST 请求而不是 GET。请注意,在不打算实际更改服务器端的某些数据的情况下执行 POST 请求在技术上是不好的做法,但这是一种选择。

于 2016-12-19T20:45:10.857 回答
1

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

也就是说,这不是通常会做的事情。这是[HttpPost]您看到模型绑定执行的方法,因为两个操作的接口需要以某种方式不同。您可以通过回发到不同的操作名称来解决这个问题,但是您仍然可能在模型的(部分)加载时触发模型验证错误,这会让用户感到非常困惑。

于 2012-08-15T19:35:03.537 回答
1

对于 Web API 2:

[HttpGet]
public ActionResult Get([FromUri]ViewModel model)
{
    // Do stuff
    return View("ViewName", model);
}
于 2015-11-27T15:41:39.003 回答
0

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

您应该做的是从帖子传递表单,然后重定向到从帖子操作中获取。此模式是最佳实践,称为 Post-Redirect-Get 模式。

于 2012-08-15T19:34:04.843 回答
0

我建议不要使用这种方法。仅使用 POST 的最佳解决方案,因为如果您使用 GET,一旦您从第 3 步单击返回到第 2 步并且浏览器缓存不可用,您将在旧版本的ViewModel. 您想使用 GET 有什么特别的原因吗?

于 2012-08-15T19:37:57.653 回答
0

我不能建议使用 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"];

    }

希望以上之一有帮助..

问候

于 2012-08-15T22:07:56.910 回答