如何包含具有 RedirectToAction 的模型? [英] How do I include a model with a RedirectToAction?

查看:19
本文介绍了如何包含具有 RedirectToAction 的模型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In the RedirectToAction below, I'd like to pass a viewmodel. How do I pass the model to the redirect?

我设置了一个断点来检查模型的值以验证模型是否正确创建.这是正确的,但结果视图不包含在模型属性中找到的值.

I set a breakpoint to check the values of model to verify the model is created correctly. It is correct but the resulting view does not contain the values found in the model properties.

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

ASP.NET MVC 4 RC

ASP.NET MVC 4 RC

推荐答案

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

RedirectToAction returns a 302 response to the client browser and thus the browser will make a new GET request to the url in the location header value of the response came to the browser.

如果您尝试将简单的精益平面视图模型传递给第二种操作方法,您可以使用 这个重载<RedirectToAction 方法的/a>.

If you are trying to pass a simple lean-flat view model to the second action method, you can use this overload of the RedirectToAction method.

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

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

The RedirectToAction will convert the object passed(routeValues) to a query string and append that to the url(generated from the first 2 parameters we passed) and will embed the resulting url in the location header of the response.

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

Let's assume your view model is like this

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

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

And you in your first action method, you can pass an object of this to the RedirectToAction method like this

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

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

This code will send a 302 response to the browser with location header value as

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

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

Assuming your Details action method's parameter is of type StoreVm, the querystring param values will be properly mapped to the properties of the parameter.

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

以上将适用于传递小的平面精益视图模型.但是如果你想传递一个复杂的对象,你应该尽量遵循PRG模式.

The above will work for passing small flat-lean view model. But if you want to pass a complex object, you should try to follow the PRG pattern.

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

PRG stands for POST - REDIRECT - GET. With this approach, you will issue a redirect response with a unique id in the querystring, using which the second GET action method can query the resource again and return something to the view.

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

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

This will create the url Store/Details?storeId=101 and in your Details GET action, using the storeId passed in, you will get/build the StoreVm object from somewhere (from a service or querying the database etc)

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 模式 是处理此用例的更好解决方案.但是,如果您不想这样做并且真的想在 Stateless HTTP 请求之间传递一些复杂的数据,则可以使用一些临时存储机制,例如 TempData

TempData

Following the PRG pattern is a better solution to handle this use case. But if you don't want to do that and really want to pass some complex data across Stateless HTTP requests, you may use some temporary storage mechanism like TempData

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

并再次在您的 GET Action 方法中读取它.

And read it in your GET Action method again.

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

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

TempData uses Session object behind the scene to store the data. But once the data is read the data is terminated.

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

Rachel has written a nice blog post explaining when to use TempData /ViewData. Worth to read.

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

In Asp.Net core, you cannot pass complex types in TempData. You can pass simple types like string, int, Guid etc.

如果你绝对想通过 TempData 传递一个复杂类型的对象,你有两个选择.

If you absolutely want to pass a complex type object via TempData, you have 2 options.

1) 将对象序列化为字符串并传递.

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

Here is a sample using Json.NET to serialize the object to a string

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

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

Now in your Index action method, read this value from the TempData and deserialize it to your CreateUserViewModel class object.

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
}

这篇关于如何包含具有 RedirectToAction 的模型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆