Passing a variable from [HttpPost] method to [HttpGet] method

不羁岁月 提交于 2020-01-01 14:21:52

问题


I am redirecting the view from [HttpPost] method to [HttpGet] method. I have gotten it to work, but want to know if this is the best way to do this.

Here is my code:

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

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:


There are basically 3 techniques in ASP.NET MVC to implement the PRG pattern.

  • TempData

Using TempData is indeed one way of passing information for a single redirect. The drawback I see with this approach is that if the user hits F5 on the final redirected page he will no longer be able to fetch the data as it will be removed from TempData for subsequent requests:

[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); 
}
  • Query string parameters

Another approach if you don't have many data to send is to send them as query string parameters, like this:

[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); 
}
  • Persistence

Yet another approach and IMHO the best consists into persisting this model into some data store (like a database or something and then when you want to redirect to the GET action send only an id allowing for it to fetch the model from wherever you persisted it). Here's the pattern:

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

Each method has its pros and cons. Up to you to choose which one suits best to your scenario.




回答2:


If you are inserting this data into a database then you should redirect them to a controller action that has this data in the route:

/Students/View/1

You can then write code in the controller to retrieve the data back from the database for display:

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



回答3:


One of the overrides of RedirectToAction() looks like that:

RedirectToAction(string actionName, object routeValues)

You can use this one as:

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

Hope that works.




回答4:


This is the classic Post-Redirect-Get pattern (PRG) and it looks fine but I would add one bit of code. In the DisplayStudent method check if your TempData variables are not null otherwise do a redirect to some default Index action. This is in case a user presses F5 to refresh the page.

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


来源:https://stackoverflow.com/questions/6686267/passing-a-variable-from-httppost-method-to-httpget-method

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!