将变量从 [HttpPost] 方法传递给 [HttpGet] 方法

Posted

技术标签:

【中文标题】将变量从 [HttpPost] 方法传递给 [HttpGet] 方法【英文标题】:Passing a variable from [HttpPost] method to [HttpGet] method 【发布时间】:2011-10-04 21:39:30 【问题描述】:

我将视图从 [HttpPost] 方法重定向到 [HttpGet] 方法。我已经让它工作了,但想知道这是否是最好的方法。

这是我的代码:

[HttpPost] 
public ActionResult SubmitStudent()
 
StudentViewModel model = TempData["model"] as StudentResponseViewModel; 

TempData["id"] = model.Id; 
TempData["name"] = model.Name; 

return RedirectToAction("DisplayStudent"); 


[HttpGet] 
public ActionResult DisplayStudent() 
 
ViewData["id"] = TempData["id"]; 
ViewData["name"] = TempData["name"]; 

return View(); 

查看:

<%@ Page 
Language="C#"
Inherits="System.Web.Mvc.ViewPage"
 %> 
<html>
 <head runat="server"> 
<title>DisplayStudent</title> 
</head> 
<body> 
<div> 
<%= ViewData["id"]%> <br /> 
<%= ViewData["name"]%> 
</div> 
</body> 
</html>

【问题讨论】:

【参考方案1】:

在 ASP.NET MVC 中基本上有 3 种技术来实现PRG pattern。

临时数据

使用TempData 确实是为单个重定向传递信息的一种方式。我看到这种方法的缺点是,如果用户在最终重定向页面上按 F5,他将不再能够获取数据,因为后续请求将从 TempData 中删除数据:

[HttpPost] 
public ActionResult SubmitStudent(StudentResponseViewModel model)
 
    if (!ModelState.IsValid)
    
        // The user did some mistakes when filling the form => redisplay it
        return View(model);
    

    // TODO: the model is valid => do some processing on it

    TempData["model"] = model;
    return RedirectToAction("DisplayStudent");


[HttpGet] 
public ActionResult DisplayStudent() 
 
    var model = TempData["model"] as StudentResponseViewModel;
    return View(model); 

查询字符串参数

如果您没有很多数据要发送,另一种方法是将它们作为查询字符串参数发送,如下所示:

[HttpPost] 
public ActionResult SubmitStudent(StudentResponseViewModel model)
 
    if (!ModelState.IsValid)
    
        // The user did some mistakes when filling the form => redisplay it
        return View(model);
    

    // TODO: the model is valid => do some processing on it

    // redirect by passing the properties of the model as query string parameters
    return RedirectToAction("DisplayStudent", new 
    
        Id = model.Id,
        Name = model.Name
    );


[HttpGet] 
public ActionResult DisplayStudent(StudentResponseViewModel model) 
 
    return View(model); 

持久性

另一种方法,恕我直言,最好的方法是将这个模型持久化到某个数据存储中(比如数据库或其他东西,然后当你想重定向到 GET 操作时,只发送一个 id 允许它从你的任何地方获取模型坚持下去)。这是模式:

[HttpPost] 
public ActionResult SubmitStudent(StudentResponseViewModel model)
 
    if (!ModelState.IsValid)
    
        // The user did some mistakes when filling the form => redisplay it
        return View(model);
    

    // TODO: the model is valid => do some processing on it

    // persist the model
    int id = PersistTheModel(model);

    // redirect by passing the properties of the model as query string parameters
    return RedirectToAction("DisplayStudent", new  Id = id );


[HttpGet] 
public ActionResult DisplayStudent(int id) 
 
    StudentResponseViewModel model = FetchTheModelFromSomewhere(id);
    return View(model); 

每种方法都有其优点和缺点。由您来选择最适合您的场景。

【讨论】:

对于 TempData 的 F5 问题,您只需检查它是否不为空,否则重定向到 Index。不是真的问题... @Daniel Lee,重定向到用[HttpPost] 属性装饰的动作? 不,绝对不是。重定向到返回学生列表的默认索引操作。我在下面更新了我的答案以说明我的意思。【参考方案2】:

如果您将此数据插入数据库,则应将它们重定向到在路由中包含此数据的控制器操作:

/Students/View/1

然后您可以在控制器中编写代码以从数据库中检索数据以进行显示:

public ActionResult View(int id) 
    // retrieve from the database
    // create your view model
    return View(model);

【讨论】:

【参考方案3】:

RedirectToAction() 的覆盖之一如下所示:

RedirectToAction(string actionName, object routeValues)

您可以将其用作:

[HttpPost] 
public ActionResult SubmitStudent()
 
StudentViewModel model = TempData["model"] as StudentResponseViewModel; 

return RedirectToAction("DisplayStudent", new id = model.ID, name = model.Name); 


[HttpGet] 
public ActionResult DisplayStudent(string id, string name) 
 
ViewData["id"] = TempData["id"]; 
ViewData["name"] = TempData["name"]; 

return View(); 

希望有效。

【讨论】:

【参考方案4】:

这是经典的Post-Redirect-Get 模式(PRG),它看起来不错,但我会添加一点代码。在 DisplayStudent 方法中检查您的 TempData 变量是否不为空,否则重定向到某些默认索引操作。这是为了防止用户按 F5 刷新页面。

public ActionResult DisplayStudent() 
 
    if(TempData["model"] == null)
    
        return RedirectToAction("Index");
    

    var model = (StudentResponseViewModel)TempData["model"];
    return View(model); 


public ViewResult Index()

    IEnumerable<StudentResponseViewModel> students = GetAllStudents();
    return View(students);

【讨论】:

以上是关于将变量从 [HttpPost] 方法传递给 [HttpGet] 方法的主要内容,如果未能解决你的问题,请参考以下文章

将 KnockoutJS 可观察数组传递给 HTTP Post 控制器方法的 AJax 调用失败

使用 Ajax 方法将变量传递给 python

将变量传递给main方法java

从 UIViewController 将变量传递给自定义 UITableViewCell

Roblox HttpPost

如何将课程传递给服务器