【问题标题】:How do I include a model with a RedirectToAction?如何使用 RedirectToAction 包含模型?
【发布时间】:2012-06-26 14:08:32
【问题描述】:

在下面的RedirectToAction 中,我想传递一个viewmodel。如何将模型传递给重定向?

我设置了一个断点来检查模型的值,以验证模型是否正确创建。这是正确的,但生成的视图不包含模型属性中的值。

//
// model created up here...
//
return RedirectToAction("actionName", "controllerName", model);

ASP.NET MVC 4 RC

【问题讨论】:

  • 我采用了这样的简单方法 => return View("actionName", model);

标签: asp.net-mvc


【解决方案1】:

RedirectToAction 向客户端浏览器返回 302 响应,因此浏览器将向浏览器响应的 location 标头值中的 url 发出新的 GET 请求。

如果您尝试将简单的精益平面视图模型传递给第二种操作方法,您可以使用this overloadRedirectToAction 方法。

protected internal RedirectToRouteResult RedirectToAction(
    string actionName,
    string controllerName,
    object routeValues
)

RedirectToAction 会将传递的对象(r​​outeValues)转换为查询字符串,并将其附加到 url(从我们传递的前 2 个参数生成),并将生成的 url 嵌入到响应的 location 标头中.

假设你的视图模型是这样的

public class StoreVm
{
    public int StoreId { get; set; }
    public string Name { get; set; }
    public string Code { set; get; } 
}

而你在你的第一个动作方法中,你可以像这样将 this 的对象传递给RedirectToAction 方法

var m = new Store { StoreId =101, Name = "Kroger", Code = "KRO"};
return RedirectToAction("Details","Store", m);

此代码将向浏览器发送 302 响应,位置标头值为

Store/Details?StoreId=101&Name=Kroger&Code=KRO

假设您的 Details 操作方法的参数是 StoreVm 类型,则查询字符串参数值将正确映射到参数的属性。

public ActionResult Details(StoreVm model)
{
  // model.Name & model.Id will have values mapped from the request querystring
  // to do  : Return something. 
}

以上内容适用于传递小型平面视图模型。但是如果你想传递一个复杂的对象,你应该尝试遵循 PRG 模式。

PRG 模式

PRG 代表 POST - REDIRECT - GET。使用这种方法,您将发出一个在查询字符串中具有唯一 id 的重定向响应,第二个 GET 操作方法可以使用该响应再次查询资源并将某些内容返回给视图。

int newStoreId=101;
return RedirectToAction("Details", "Store", new { storeId=newStoreId} );

这将创建 URL Store/Details?storeId=101 在您的 Details GET 操作中,使用传入的 storeId,您将从某处(从服务或查询数据库等)获取/构建 StoreVm 对象

public ActionResult Details(string storeId)
{
   // from the storeId value, get the entity/object/resource
   var store = yourRepo.GetStore(storeId);
   if(store!=null)
   {
      // Map the the view model
      var storeVm = new StoreVm { Id=storeId, Name=store.Name,Code=store.Code};
      return View(storeVm);
   }
   return View("StoreNotFound"); // view to render when we get invalid store id
}

临时数据

遵循PRG pattern 是处理此用例的更好解决方案。但是,如果您不想这样做并且真的想在 Stateless HTTP 请求中传递一些复杂的数据,则可以使用一些临时存储机制,例如 TempData

TempData["NewCustomer"] = model;
return RedirectToAction("Index", "Users");

并在您的GET Action 方法中再次阅读它。

public ActionResult Index()
{      
  var model=TempData["NewCustomer"] as Customer
  return View(model);
}

TempData 在后台使用Session 对象来存储数据。但是一旦数据被读取,数据就会终止。

Rachel 写了一篇不错的博客 post 解释何时使用 TempData /ViewData。值得一读。

在 Asp.Net Core 中使用 TempData 将模型数据传递给重定向请求

在 Asp.Net 核心中,您不能在 TempData 中传递复杂类型。您可以传递简单的类型,例如 stringintGuid 等。

如果您绝对想通过 TempData 传递复杂类型的对象,您有 2 个选项。

1) 将您的对象序列化为字符串并将其传递。

这是一个使用 Json.NET 将对象序列化为字符串的示例

var s = Newtonsoft.Json.JsonConvert.SerializeObject(createUserVm);
TempData["newuser"] = s;
return RedirectToAction("Index", "Users");

现在在您的 Index 操作方法中,从 TempData 读取此值并将其反序列化为您的 CreateUserViewModel 类对象。

public IActionResult Index()
{
   if (TempData["newuser"] is string s)
   {
       var newUser = JsonConvert.DeserializeObject<CreateUserViewModel>(s);
       // use newUser object now as needed
   }
   // to do : return something
}

2) 将简单类型的字典设置为 TempData

var d = new Dictionary<string, string>
{
    ["FullName"] = rvm.FullName,
    ["Email"] = rvm.Email;
};
TempData["MyModelDict"] = d;
return RedirectToAction("Index", "Users");

稍后再读

public IActionResult Index()
{
   if (TempData["MyModelDict"] is Dictionary<string,string> dict)
   {
      var name = dict["Name"];
      var email =  dict["Email"];
   }
   // to do : return something
}

【讨论】:

    【解决方案2】:

    另一种方法是将其存储在会话中。

    var s = JsonConvert.SerializeObject(myView);
    HttpContext.Session.SetString("myView", s);
    

    然后把它找回来

    string s = HttpContext.Session.GetString("myView");
    myView = JsonConvert.DeserializeObject<MyView>(s);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-04-04
      • 1970-01-01
      • 2018-06-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-12
      • 1970-01-01
      相关资源
      最近更新 更多