【问题标题】:Is returning different view with object bad practice in ASP.net MVC 5?在 ASP.net MVC 5 中返回不同的视图与对象不好的做法?
【发布时间】:2017-04-29 23:21:12
【问题描述】:

我需要在 ASP.net MVC 5 应用程序中的 ActionMethods 和 Views 之间传递对象。

我将它用于多页面注册 - 以及多页面支付。

这是不好的做法吗?我还没有看到在不同控制器之间传递对象的好方法。

代码:

public ActionResult Join1()
{
    //
    return View("Join2", MyObject);
}

[HttpPost]
public ActionResult Join2(MyObject MyObj)
{
    //manipulate object
    //return
}

这似乎是一种有效的方法——尽管我没有看到很多人这样做。我根本没有看到在动作方法之间传递对象。

这种方法是否存在缺陷,一种在视图之间传递模型的更好方法 - 或者每个 ActionMethod 是否应该坚持使用 TempData 而不是对象传递简单数据?

为什么我没有看到任何示例项目做这样的事情?

我已经看到很多 return RedirectToAction("act"); 了 - 但在 URI 中获取和传递对象是有限制的 - 我不希望用户能够操纵或看到正在传递的数据。

谢谢。

【问题讨论】:

  • 我根据需要这样做。在您认为PRG 合适的地方使用RedirectToAction

标签: asp.net-mvc asp.net-mvc-5


【解决方案1】:

除非我误解了描述,否则您的代码并没有像您认为的那样做。第一个return View("Join2", MyObject); 语句没有执行第二个ActionMethod,它只是将您的数据传递到恰好与第二个方法具有相同名称的视图中。因此,//manipulate object 隐含的代码在 View 被渲染并发回给用户之前不会运行。

假设 View 文件 Join2.cshtml 存在,并且它包含默认的 @using (Html.BeginForm()),那么提交表单的用户将导致执行 Join2 Action 并使用操纵的数据呈现相同的视图 - 当然,除非,您添加另一个命名不同视图的return View() 语句。

你没有看到太多的原因是 MVC 约定是有一个与 ActionMethod 命名相同的 View,这使得代码稍微简单一些,也更容易让其他 ASP.NET 开发人员理解,因为它是他们期望看到的。

如果您希望每个 View 呈现的表单在回发时执行不同的 ActionMethod,则可以在 View 代码中执行此操作,其中 Html.BeginForm()several overloads 允许您这样做,例如在Join.cshtml 你可以写:

@using (Html.BeginForm("Join2", "JoinController"))
{
    // form fields and stuff
}
// Produces the following form element
// <form action="/JoinController/Join2" action="post">

要解决您问题的最后一部分,“我不希望用户能够操纵或查看正在传递的数据”,很抱歉,但您提出的代码并不能阻止这一点:用户可以 查看网络表单中的数据,在它被发回Join2方法之前;他们可以通过将包含他们想要的任何数据的 HTTP POST 发送回Join2 方法来操作数据。

如果您绝对肯定需要在Join() 中实际执行Join2(),然后再将任何内容传回给用户,那么您可以像调用任何其他 C# 方法一样调用它:

var myResult = Join2(MyObject);

然后您就有了一个 ActionResult 对象,您可以对其进行操作或直接返回给浏览器。但是为什么你会想要这样做,我无法理解。

【讨论】:

  • 谢谢。我如何做到这一点非常灵活——我正处于设计阶段——所以我可以随心所欲地改变它。如何将对象从一个 ActionMethod 传递到另一个?
  • 刚刚添加了最后一节,展示了如何像在 C# 中调用其他方法一样调用该方法。但是我建议如果您需要这样做,您的设计可能存在缺陷:Action Method 的全部目的是直接响应用户的请求。
  • 是的,我同意 - 我要求一种更传统的方式来做到这一点 - 出于某种原因,我在网上找不到太多。
  • 从需求的角度来看,这取决于您要实现的目标。如果目标是引导用户浏览多页表单,同时收集更多数据,那么使用Html.BeginForm("NextActionName", "ControllerName") 就是这样做的方法。如果您不想在页面之间将已经输入的数据返回给用户,例如作为隐藏的表单字段,或者如果您想添加一些用户不应该看到的持久的“秘密”数据,那么可以将其存储在 Session 对象中,或者创建一个数据库记录并给出每个后续页面视图的 ID。
  • 如果您在不同的 ActionMethods 之间传递数据而不使用数据库,那么我的做法是一个不错的选择?
猜你喜欢
  • 1970-01-01
  • 2017-06-03
  • 1970-01-01
  • 1970-01-01
  • 2023-03-07
  • 1970-01-01
  • 2020-04-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多