0

I need to move this object around the application without losing it. At first, I just used a static class to do it, which was simple, fast and effective. Though, It's been brought to my attention that a static object can be accessed by anyone from anywhere. So, as that's a serious security risk, I've been trying to find another way do it. I've made an ajax request to do what needed to be done in the code behind (which, in this case, would be to book a new room in a hotel). All good. The thing is, I want to bring it back again to the client-side, to the model or something, to have it present for when I need to book another room. As of now, I click the "book" button and it adds a room but as soon as it goes back to the client-side the object is lost. So, I serialized it on the server-side and returned it to the server-side. But then I can't access it in the razor code.

I don't know if this can be done (this way, at least). But there has to be another way, since many websites have to make a sale, for instance, and switch pages and keep all the information. If possible, I want to avoid having to go to the database all the time to do this. I want to keep this in memory.

So, to show the code:

<button type="reset" class="btn btn-info center-block" onclick='BookRoom(
      @Html.Raw(Json.Serialize(Model)),                                                
      "@Repository.RoomTypeList[i].UUID",
      "@Repository.RoomTypeList[i].PossibleRateTypes[j].UUID",
      "checkIn",
      "checkOut");'>
       Book
</button>

<script type="text/javascript">
    function AjaxRooms(URL, method, contentType, request, dataType, successRespMsg, successRespObj) {
        $.ajax({
            url: URL,
            method: method,
            contentType: contentType,
            data: JSON.stringify(request),
            dataType: dataType,
            success: function (resp) {
                debugger
                alert(resp[successRespMsg]);
                var aux = JSON.parse(resp[successRespObj]);

                // Here is where I want to access the object from javascript to razor, in order to keep it in memory

            },
            error: function (error) {
                alert(error);
            }
        })
    }

function BookRoom(model, roomUUID, rateUUID, checkIn, checkOut) {
    AjaxRooms('Home/Book?ro=' + roomUUID + '&ra=' + rateUUID + '&ci=' + document.getElementById(checkIn).value + '&co=' + document.getElementById(checkOut).value,
            'post', 'application/ json', model, 'json', 'msg', 'obj');    
}
</script>



public class Reservation
{
    public DateTime CheckIn { get; set; }
    public DateTime CheckOut { get; set; }

    public List<RoomType> BookedRooms { get; set; } = new List<RoomType>();
}

    public IActionResult Book([FromBody]Reservation reservation)
    {
        var roomUUID = HttpContext.Request.Query["ro"].ToString();
        var rateUUID = HttpContext.Request.Query["ra"].ToString();
        var checkIn = HttpContext.Request.Query["ci"].ToString();
        var checkOut = HttpContext.Request.Query["co"].ToString();

        try
        {
            if (checkIn == "" || checkOut == "")
                return Json(new { msg = "You have to select a Check In and a Check Out date.", obj = JsonConvert.SerializeObject(reservation) });
            else if (roomUUID != "" || rateUUID != "")
            {
                // Adds a new room (with the specified rate) to the list
                var roomType = Repository.DeepClone(Repository.RoomTypeList)
                    .FirstOrDefault(r => r.UUID == roomUUID);

                roomType.PossibleRateTypes = new List<RateType>() { roomType.PossibleRateTypes.FirstOrDefault(rt => rt.UUID == rateUUID) };

                reservation.BookedRooms.Add(roomType);
                reservation.CheckIn = Convert.ToDateTime(checkIn);
                reservation.CheckOut = Convert.ToDateTime(checkOut);

                return Json(new { msg = "Added to cart.", obj = JsonConvert.SerializeObject(reservation) });
            }
            else
                return Json(new { msg = "We couldn't add it to cart. Please try again.", obj = JsonConvert.SerializeObject(reservation) });

        }
        catch (Exception ex)
        {
            return Json(new { msg = "An error has occurred. Please try again later or contact and administrator.", obj = JsonConvert.SerializeObject(reservation) });
        }
    }

I've been doing it like this but you can propose another, better way, to do it. I'm all ears.

taiko
  • 458
  • 6
  • 22
  • 1
    Have you considered using local/session storage in the browser? That would be one way to keep the data in memory when the user jumps from page to page on your site. – Daryl Dec 13 '17 at 16:53
  • You save json instead of accessing the model as the object? Hm... Might work. Would the process be the same as what I'm doing? Ajax request to do the processing on the server-side and return the json and then, if I understood you right, I can save it in storage. Do you think that would work? – taiko Dec 13 '17 at 17:00
  • Small note: local storage is not supported by all browsers. If you want full cross-browser support you will need to use server side session state and the post and get via ajax. – SpruceMoose Dec 14 '17 at 09:18
  • @CalC not all versions, perhaps, but yet says [here](https://www.w3schools.com/jsref/prop_win_localstorage.asp) that it is supported by all the main browsers. I even tested right now on Internet Explorer and even it can handle it. If IE can handle any one can! :D – taiko Dec 14 '17 at 10:30
  • 1
    Depends on the version of IE, but yeah, most if not all of the latest browsers can. – SpruceMoose Dec 14 '17 at 10:31
  • @Daryl, thanks for the tip. Didn't remember about this one, as it is not common for me to use. But it works very smoothly for the purposes I want. If you want to put that into an answer so I can accept it, you're good. Also, I maintained everything the way you is. The difference is I saved it (the json that I get from c#) in the localStorage in the 'AjaxRooms', function, on the ajax function's success. – taiko Dec 14 '17 at 10:35
  • 1
    @CalC, as the project is very open yet (as in not fixed ideas), this is good enough for what I intend it to. If, in the future, comething better comes along, great. If not, this is good stuff. :) – taiko Dec 14 '17 at 10:36
  • Glad you found a workable solution. Only other thing to note when you move forward with the project is that a user could have manually disabled local storage for some reason. – SpruceMoose Dec 14 '17 at 10:46
  • Didn't know it could be done. Well, if that happens where do you turn to? – taiko Dec 14 '17 at 10:57
  • Looks like there is a post here that addresses this: https://stackoverflow.com/questions/16427636/check-if-localstorage-is-available – Daryl Dec 14 '17 at 17:53
  • Are there any security concerns that the user can change this data? – Erik Philips Dec 14 '17 at 18:04
  • Oh, I see. I can set an item on the localStorage and just check if it exists. Nice. Although, I don't think it's going to be an issue right now. Maybe later in the project. But thanks for the info, anyway. :) – taiko Dec 15 '17 at 23:37
  • @ErikPhilips, how's so? Are you asking if there is sensitive information? If so, no. It's just the room's info, just to be able to id the rooms chosen in real time (to always stay on the client-side until I must have to go to the server-side, for some reason), just so the app can run more fluently. – taiko Dec 15 '17 at 23:40

1 Answers1

1

Have you considered using local/session storage in the browser? That would be one way to keep the data in memory when the user jumps from page to page on your site.

Daryl
  • 610
  • 1
  • 7
  • 17
  • As I said before, thanks for the tip. This is a nice and clean way to keep non-sensitive information and not worry about data getting lost when jumping between pages. :) – taiko Dec 15 '17 at 23:44