关于c#:. NET Core MVC中的控制器之间传输数据

Transferring data between controllers in .NET Core MVC

作为我应用程序中的一个特定示例,我想将http://mybooking.com/{hotelName}/{roomNr}处的房间信息(由酒店名称和房间名称组成)传递到我的http://mybooking.com/reservation处的预订控制器上,想知道这样做的最佳实践是什么。

更具体地说,在Room页面(位于http://mybooking.com/{hotelName}/{roomNr})中,当用户单击名为"预订此房间"的按钮时,他/她将被重定向到Reservation页面。因此,我想知道将hotelNameroomNrRoom页保存到Reservation页的最合适的方法。

我尝试通过像http://mybooking.com/reservation/{hotelName}/{roomNr}这样的URL传递它,但是我认为这不是最佳解决方案,因为我只能用此控制器的特定索引方法来访问hotelName和roomNr:

1
2
3
4
5
6
//ReservationController
[HttpGet("/Reservation/{hotelName}/{roomNr}")]
public IActionResult Index(string hotelName, int roomNr)
{
    //hotelName and roomNr can only be accessed here
}

对于控制器或服务中的其他方法,我确实也需要这些信息,并且我想知道它是否适用于当前实现。

对此案有何建议?


您的情况是这样的:您在网站上拥有可供用户查看的不同酒店和房间,并且具有多个页面的"预订"或"结帐"流程,用户可以在其中进行预订一个房间。

当用户要预订房间时,您想在整个结帐过程中记住他们的酒店和房间标识符,这样您就知道他们要预订哪个酒店的房间。

您不为此使用会话或TempData(在ASP.NET MVC <= 5和ASP.NET Core <2.0中,默认情况下以前将其保存在会话中,但是现在在cookie中),因为会话和cookie是在标签之间共享。因此,在这种情况下,用户将预订错误的房间:

  • 用户查看房间1,单击"预订此房间"。房间1的数据已保存在会话中。用户通过结帐直到最后一步,但尚未完成。
  • 用户打开一个新选项卡,查看2号房间进行比较,单击"预订此房间"以查看条件,付款明细等等。
  • 用户决定仍然要房间1,返回到结帐标签并完成他们的订单。
  • 因为第二次"预订此房间"单击已在会话中填充了房间2的详细信息,房间2是将要预订的房间。

您不希望这样做,因为您的用户不希望这样做。您应该做的是在结帐过程中将酒店和房间标识符传递给每个页面。

您是使用隐藏的表单字段和POST操作还是通过查询字符串和GET操作来完成此操作。


没有看到您拥有什么样的代码,就很难看到您在做什么。通常,如果您要访问网址http://mybooking.com/{hotelName}/{roomName}

在该Controller上,您将知道这些详细信息并能够将其呈现到视图上。从此视图中,如果您有一个"保留此房间"按钮,则该按钮将位于表单中。在此表格中,您将获得有关酒店名称和房间名称的信息,可能以Ids的形式出现,从而使它们完全唯一。当用户单击该按钮时,您会将ID发布到ReservationController,然后可以在其视图上使用此信息。

例如类似

/ {hotelName} / {roomName}

1
2
3
4
5
<form action="/reservation" method="post">
<input type="number" name="hotelId" value="{hotelId}" class="hidden" />
<input type="number" name="roomId" value="{roomId}" class="hidden" />
<button type="submit">Reserve Room</button>
</form>

ReservationController需要具有一个采用HttpPost并具有参数hotelIdroomId

的方法。

类似

的东西

1
2
3
4
5
6
[HttpPost]
public IActionResult Index(int hotelId, int roomId){
   // do something with the ids
   // stick them in a ViewBag
   Return View();
}


在两个控制器之间传输数据的一种非常简单的方法是使用TempData

假设您正在处理http://mybooking.com/{hotelName}/{roomName}中重定向到http://mybooking.com/reservation的HTTPPost,则可以使用

1
2
TempData["hotelName"] ="a";
TempData["roomName"] ="b";

在调用RedirectToAction之前。

http://mybooking.com/reservation的控制器方法中,您可以再次访问TempData

您可以在此处阅读有关TempData的更多信息:

ASP.NET Core exposes the Razor Pages TempData or Controller TempData.
This property stores data until it's read in another request.
Keep(String) and Peek(string) methods can be used to examine the data
without deletion at the end of the request. Keep() marks all items in
the dictionary for retention. TempData is particularly useful for
redirection when data is required for more than a single request.
TempData is implemented by TempData providers using either cookies or
session state.