【问题标题】:Passing a variable from [HttpPost] method to [HttpGet] method将变量从 [HttpPost] 方法传递给 [HttpGet] 方法
【发布时间】: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>

【问题讨论】:

    标签: asp.net-mvc http-post http-get http-redirect


    【解决方案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);
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-04-20
          • 1970-01-01
          • 1970-01-01
          • 2012-02-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多