Linh Bui
Linh Bui

Reputation: 25

Transferring data between controllers in .NET Core MVC

As a specific example within my application, I would like to have the information of the room (which is a combination of hotel name and room name) at http://mybooking.com/{hotelName}/{roomNr} passed onto my reservation controller at http://mybooking.com/reservation, and I really wonder what would be the best practice for doing it.

To be more specific, within the Room page (at http://mybooking.com/{hotelName}/{roomNr}), when user clicks on a button called "Book this room", he/she will be redirected to Reservation page. Thus, I want to know the most appropriate way to preserve the hotelName and roomNr from Room page to Reservation page.

I tried passing it through the URL like http://mybooking.com/reservation/{hotelName}/{roomNr}, but I believe this isn't the best solution, since I can only then access to the hotelName and roomNr in the specific index method of this controller:

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

I do need this piece of information for other methods within the controller or the service as well, and I wonder if it is applicable with the current implementation.

Any suggestion on this case?

Upvotes: 0

Views: 1443

Answers (3)

CodeCaster
CodeCaster

Reputation: 151674

Your scenario is this: you have different hotels and rooms on your site which users can view, and you have a "reservation" or "checkout" process that exists of mutiple pages, where a user can book such a room.

When a user wants to book a room, you want to remember their hotel and room identifiers throughout the entire checkout process, so you know which room in which hotel they want to book.

You do not use sessions or TempData (which in ASP.NET MVC <= 5 and ASP.NET Core < 2.0 used to be saved in the session by default, but now in cookies) for this, because sessions and cookies are shared across tabs. So in this scenario, the user will book the wrong room:

  • User looks at room 1, clicks "Book this room". The data of room 1 is saved in the session. User goes through the checkout until the last step, but does not finish yet.
  • User opens a new tab, looks at room 2 to compare, clicks "Book this room" to view the conditions, payment details, whatever.
  • User decides they want room 1 anyway, goes back to the checkout tab and finishes their order.
  • Because the second "Book this room" click has now filled the session with the details of room 2, which is the room that will be booked.

You do not want this, because your user does not want this. What you should do, is pass the hotel and room identifiers to each page in the checkout process.

Whether you do this using hidden form fields and POST actions, or through the query string and GET actions is up to you.

Upvotes: 4

citronas
citronas

Reputation: 19365

A very simple way of transferring data between two controllers is to use TempData

Assuming that you are handling a HTTPPost in http://mybooking.com/{hotelName}/{roomName} which redirects to http://mybooking.com/reservation, you can use

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

before calling RedirectToAction.

In the controller method of http://mybooking.com/reservation you can access TempData again.

You can read more about TempData here:

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.

Upvotes: 0

Tim B James
Tim B James

Reputation: 20364

Without seeing what sort of code you have, it's sort of difficult to see what you are doing. Generally though, if you were to hit the url http://mybooking.com/{hotelName}/{roomName}

On that Controller you would know these details and be able to render them out onto the View. From this View, if you have a button which is "Reserve this Room", the button would be within a Form. Within this Form you would have the information about the hotel name and room name, probably in the form of Ids so that they are fully unique. When the user clicks the button, you are posting the Ids to the ReservationController which can then use this information on it's view.

e.g. something like

/{hotelName}/{roomName}

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

The ReservationController would need to have a method that takes a HttpPost and has the arguments hotelId and roomId

Something like

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

Upvotes: 2

Related Questions