【问题标题】:Passing a model object to a RedirectToAction without polluting the URL?将模型对象传递给 RedirectToAction 而不污染 URL?
【发布时间】:2012-10-22 21:29:46
【问题描述】:

这是我想要做的:

public ActionResult Index()
{
    return View();
}

[HttpPost]
public ActionResult Index(ContactModel model)
{
    if (ModelState.IsValid)
    {
        // Send email using Model information.

        return RedirectToAction("Gracias", model);
    }

    return View(model);
}

public ActionResult Gracias(ContactModel model)
{
    return View(model);
}

所有三个动作方法都在同一个控制器中。基本上,用户在联系表单中输入了一些数据,我想使用他们在 Model 对象中的名称将他们重定向到感谢页面。

正如代码一样,它可以工作,但 URL 与 GET 变量一起传递。不理想。

http://localhost:7807/Contacto/Gracias?Nombre=Sergio&Apellidos=Tapia&Correo=opiasdf&Telefono=oinqwef&Direccion=oinqef&Pais=oinqwef&Mensaje=oinqwef

有什么建议吗?

【问题讨论】:

    标签: c# asp.net-mvc-3 model controller


    【解决方案1】:

    听起来像是TempData 的解决方案!

    [HttpPost]
    public ActionResult Index(ContactModel model)
    {
      if (ModelState.IsValid)
      {
        // Send email using Model information.
        TempData["model"] = model;
        return RedirectToAction("Gracias");
      }
    
      return View(model);
    }
    
    public ActionResult Gracias()
    {
      ContactModel model = (ContactModel)TempData["model"];
      return View(model);
    }
    

    【讨论】:

    • 我不知道您可以将复杂类型保存到 TempData 字典中。直到。谢谢!
    • 只要它们是可序列化的!! TempData 存储在 session 中,它只允许 Serializable 对象/类。
    • 临时数据当然可以在这里工作,但为什么不直接从 Index 显示“Gracias”视图(模型已经在范围内)。您还为自己节省了一次服务器往返,这本质上是一个无用的重定向。
    • 首先,OP询问如何使用RedirectToAction。其次,正如我在您的回答中提到的,URL 不是/Gracias,而是/Index,所以这取决于 OP 希望 URL 的样子。
    • 好点我没想到显示的 URL 真的很重要。如果是这样,那么 TempData 是最好的解决方案
    【解决方案2】:

    而不是做

    return RedirectToAction("Gracias", model);
    

    你可以的

    [HttpPost]
    public ActionResult Index(ContactModel model)
    {
        if (ModelState.IsValid)
        {
            // Send email using Model information.
    
            return View("Gracias", model);
        }
    
        return View(model);
    }
    

    并删除您的 Gracias 控制器操作。使用上面的“Gracias”视图将与您的 ContactModel 模型一起显示。

    如果它使用相同的模型并且是工作流程的锁定步骤的一部分,我认为不需要单独的控制器操作。 "一个成功的 POST to Index 将始终导致显示 Gracias 视图"

    您也可以将模型存储在 TempData 中(类似于 1 次请求会话状态),但我认为在您的情况下这样做没有任何意义,因为它只会使事情复杂化

    想法?

    【讨论】:

    • 网址看起来像http://localhost:7807/Contacto/Index,如果可以接受,这是最简单的方法。
    • 是的,这是不可接受的,这就是我没有走这条路的原因。
    • 现在只希望有人不要在其他时间点击“localhost:7807/Contacto/Gracias”(或者如果他们点击后退按钮并且页面没有被缓存),因为将会返回一个视图空字段,甚至可能是一个例外,具体取决于您的视图。考虑到您可能真的不希望显示另一个 URL。
    • 我会检查 TempData 是否为空,如果是则重定向。
    【解决方案3】:

    快速回答是不要传递整个模型,而是传递一些标识符,您可以使用它从存储库中检索模型:

    [HttpPost]
    public ActionResult Index(ContactModel model)
    {
        if (ModelState.IsValid)
        {
            // Send email using Model information.
    
            return RedirectToAction("Gracias", model.ID);
        }
    
        return View(model);
    }
    
    public ActionResult Gracias(int contactID)
    {
        ContactModel model = new ContractRepository().GetContact(contactID);
        return View(model);
    }
    

    【讨论】:

    • 这不像你想象的那样工作。如果我在 HttpPost Index() 方法中传入更新的模型,所有这些更改都会丢失,因为方法 Gracias() 中的所有值都来自数据库,而不是用户。
    猜你喜欢
    • 2012-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-05
    • 1970-01-01
    • 2011-08-02
    • 1970-01-01
    • 2018-04-17
    相关资源
    最近更新 更多