将数据从控制器传递到视图,再传递回控制器,再传递回视图
我是 ASP.NET MVC 新手。在使用传统 ASP.NET 模型这么长时间之后,我花了一些时间来理解这个模型。
我正在通过 NerdDinner 来了解事情是如何运作的。
所以,我有一个需要通过几个视图传递的对象。类似于文章 NerdDinner 步骤 6:ViewData 和 ViewModel。
我第一次保留从 Get 到 Post 的数据,然后将其放入 TempData 并将其传递给另一个操作(AnotherAction)。一旦我在 Get 上获取数据,我就无法在 Post 上保留它。
这是我的代码:
public class DinnerFormViewModel
{
public Dinner Dinner { get; private set; }
public DinnerFormViewModel(Dinner dinner)
{
Dinner = dinner;
}
}
public class DinnersController : Controller
{
public ActionResult Action()
{
Dinner dinner = new Dinner();
return View(new DinnerFormViewModel(dinner));
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Action(Dinner dinner, FormCollection collection)
{
try
{
// Some code
TempData["Dinner"] = dinner;
return RedirectToAction("AnotherAction");
}
catch
{
return View();
}
}
public ActionResult AnotherAction()
{
Dinner dinner = (Dinner)TempData["Dinner"]; // Got my dinner object
return View(new DinnerFormViewModel(dinner));
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult AnotherAction(Dinner dinner, FormCollection collection)
{
// Lost my dinner object, dinner comes in as null
}
}
I'm new to ASP.NET MVC. After working with traditional ASP.NET model for so long, it's taking some time for me to get to understand this model.
I am going through NerdDinner to understand how things work.
So, I have an object that needs to be passed through couple of views. Similar to the article NerdDinner Step 6: ViewData and ViewModel.
I retain the data from Get to Post for the first time, then I put it in TempData and pass it to another action (AnotherAction). Once I get my data on Get I cannot retain it on Post.
Here's my code:
public class DinnerFormViewModel
{
public Dinner Dinner { get; private set; }
public DinnerFormViewModel(Dinner dinner)
{
Dinner = dinner;
}
}
public class DinnersController : Controller
{
public ActionResult Action()
{
Dinner dinner = new Dinner();
return View(new DinnerFormViewModel(dinner));
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Action(Dinner dinner, FormCollection collection)
{
try
{
// Some code
TempData["Dinner"] = dinner;
return RedirectToAction("AnotherAction");
}
catch
{
return View();
}
}
public ActionResult AnotherAction()
{
Dinner dinner = (Dinner)TempData["Dinner"]; // Got my dinner object
return View(new DinnerFormViewModel(dinner));
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult AnotherAction(Dinner dinner, FormCollection collection)
{
// Lost my dinner object, dinner comes in as null
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
要获得您期望的格式,您可能必须在从各种视图收集信息时填充一些隐藏字段。
另外,使用模型绑定可以使代码看起来更好一些,并避免在某些地方使用 TempData:
因此,在 AnotherAction 视图中,您会看到类似这样的内容:
上面的示例中没有用户友好性,但您明白了。
To get the format that you're expecting you may have to populate some hidden fields as you collect the information from various views.
Also, using model binding you could make your code look at bit better and avoid TempData in places:
So in the AnotherAction view you would have something like:
There is no user friendliness in the above example but you get the point.
根据这篇博客文章 TempData仅适用于1个请求设定后。
以下是该帖子的引用:
因此,根据我看到的代码,您可以在从
AnotherAction
获取时从 TempData 获取晚餐,这是您在Action
上设置它后的第一个请求。然而,查看代码并没有看到AnotherAction
的视图代码,不清楚如何将数据传递到AnotherAction
的帖子。晚餐实例不会出现在该请求的 TempData 中,因为它是您在 TempData 中设置它之后的第二个请求。如果您没有在AntoherAction
视图上设置正确的表单标签,则框架将没有正确的表单值来实例化帖子中的晚餐对象。因此,您必须在第一个
AnotherAction
调用中使用晚餐实例重置 TempData,然后在后AnotherAction
中从 TempData 中检索晚餐,或者您可以按照dm 的建议并在您的视图中使用隐藏字段。IMO,您应该使用 DM 方式来执行此操作,并避免使用 TempData。
编辑添加了在 AnotherAction 中重置 TempData 以在帖子中访问它的示例。
模型:
控制器:
操作视图:
AnotherAction 视图:
According to this blog post TempData is only around for 1 single request after its set.
Here is a quote from the post:
So given the code that I'm seeing, you can get the dinner from TempData on the get from
AnotherAction
which is the first request after you set it onAction
. However looking at the code and not seeing the code for view forAnotherAction
it is unclear how you are passing the data to the post forAnotherAction
. The dinner instance is not going to be in TempData for that request because it's the second request after you set it in TempData. And if you do not have the proper form tags set on theAntoherAction
view the framework will not have the proper form values to instantiate a dinner object in the post.So either you'll have to reset TempData with the dinner instance it the first
AnotherAction
call and then retrieve the dinner out of TempData in the postAnotherAction
, or you can follow the advice of dm and use hidden fields in your view.IMO, you should use DMs way of doing this and avoid using TempData.
Edit Added example of reseting the TempData in AnotherAction to get access to it in the post.
Model:
Controller:
Action View:
AnotherAction View:
您无法将原始 C# 对象从视图传递到控制器。
在 ASP.NET MVC 中,当操作采用对象作为参数时,ASP.NET MVC 会查看所有 POST/GET 数据并查找与参数对象上的属性名称一致的值。
仅当您使用与晚餐对象的属性(位置、日期等)相对应的表单字段发布到操作,或者将该信息放入 GET URL 中时(Dinners/SomeAction?location=chicago& ;date=12/1/2009 等)
如果您绝对不能使用隐藏字段(如 DM 建议),那么会话可能是您唯一的选择。
You can't pass raw C# objects from Views to Controllers.
In ASP.NET MVC, when an action takes an object for a parameter, ASP.NET MVC looks at all the POST/GET data and looks for values which coincide with property names on the parameter object.
myDinner object will be populated ONLY if you post to the action with form fields that correspond to the Dinner object's properties (location, date, etc.) or if you were to place that information in a GET URL (Dinners/SomeAction?location=chicago&date=12/1/2009 etc.)
If you absolutely can't use hidden fields (As DM suggested), then Sessions is probably your only option.
你应该从存储库得到晚餐。您的操作应该类似于:
GET 操作也可以从存储库中获取,因此您可以仅传递 id。
编辑
如果你想创建向导风格的页面,你可以将之前输入的数据存储在Session对象中。
存储在 Session 中的数据通过请求持续存在。
You should get dinner from repository. You action should be like:
GET actions can also take from repository, so you can pass only id.
EDIT
If you want to create wizard style page, you can store previously entered data in Session object.
Data stored in Session persist through requests.