从[HttpPost]方法传递变量到[HttpGet]方法

4

我正在将视图从[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>
4个回答

8

ASP.NET MVC基本上有三种技术来实现PRG模式

  • TempData

使用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
@Daniel Lee,重定向到一个使用[HttpPost]属性装饰的操作? - Darin Dimitrov
不,绝对不是。重定向到一个默认的Index操作,返回学生列表。我已经更新了下面的答案以展示我的意思。 - Daniel Lee

2
如果您要将这些数据插入数据库,则应将其重定向到具有此数据的控制器操作中的路由:
/Students/View/1

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

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

0

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(); 
}

希望能够正常工作。

0

这是经典的Post-Redirect-Get模式(PRG),看起来很好,但我会添加一些代码。在DisplayStudent方法中,检查您的TempData变量是否为null,否则重定向到某个默认的Index操作。这是为了防止用户按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);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接