asp.net-mvc 如何包含具有 RedirectToAction 的模型?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11209191/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 02:03:30  来源:igfitidea点击:

How do I include a model with a RedirectToAction?

asp.net-mvc

提问by user1469655

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

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

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

回答by Shyju

RedirectToActionreturns 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向客户端浏览器返回 302 响应,因此浏览器将对到达浏览器的响应的位置标头值中的 url 发出新的 GET 请求。

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

如果你想通过一个简单的贫平面视图模式到第二操作方法,您可以使用此重载的的RedirectToAction方法。

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

The RedirectToActionwill 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 locationheader of the response.

RedirectToAction将对象传递(routeValues)转换成一个查询字符串和它添加到URL,并且将嵌入在所得到的URL(从我们通过第一2个参数生成)位置的响应的报头中。

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

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

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

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

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

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

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

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

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

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

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 模式。

PRG Pattern

PRG 模式

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.

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

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

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

这将创建 url,Store/Details?storeId=101并在您的 DetailsGET操作中,使用传入的 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
}

TempData

临时数据

Following the PRG patternis 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 HTTPrequests, you may use some temporary storage mechanism like TempData

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

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

And read it in your GETAction method again.

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

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

TempDatauses Sessionobject behind the scene to store the data. But once the data is read the data is terminated.

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

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

Rachel 写了一篇很好的博客文章,解释了何时使用 TempData /ViewData。值得一读。

Using TempData to pass model data to a redirect request in Asp.Net Core

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

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

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

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

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

1) Serialize your object to a string and pass that.

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

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

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

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

Now in your Indexaction method, read this value from the TempData and deserialize it to your CreateUserViewModelclass object.

现在,在您的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) Set a dictionary of simple types to TempData

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

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

and read it later

稍后阅读

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