0

So I have this issue that I am not unable to solve the way I think it's supposed to be solved.

I have an ASP.NET Core 2.1 Razor pages project. The code is pasted below and my problem is the following:

On the index page, I have a search form. The city name I enter in the search form gets used in the SearchResults OnPost method.

The OnPost redirects to OnGet which retrieves some results from the database based on the city passed in from the search form. From my understanding, TempData should be able to retain the value for the city passed in from the form, however, whenever I try to read TempData["CityFromForm"] in the OnGet method, the TempData dictionary is empty, even though that in the OnPost method I used the TempData.Keep method.

My current solution for this is using in memory cache to store the city value and pass it to the method that fetches the data from the database, but I would like to know why the TempData approach is not working.

On the index page on that project, there is a search from in which I enter a city for which I want to search the data, like so:

@model SearchDataViewModel

<form asp-page="/Search/SearchResults" method="post" class="col s6">
    <div class="row">

        <div class="input-field col s12">
            <input placeholder="Please enter a city" type="text" name="City" class="validate autocomplete" id="autocomplete-input" autocomplete="off" />
            <label for="City">City</label>
        </div>
    </div>

    <div class="row">
        <div class="input-field col s6">
            <input id="StartDate" name="StartDate" type="text" class="datepicker datepicker-calendar-container">
            <label for="StartDate">Start date</label>
        </div>
        <div class="input-field col s6">
            <input id="EndDate" name="EndDate" class="datepicker datepicker-calendar-container" />
            <label for="EndDate">End date</label>
        </div>
    </div>
    <input type="submit" hidden />
</form>

What matters in that form is the city. That form gets sent to the SearchResults razor page.

SearchResults.cshtml.cs

    public IActionResult OnPost()
    {
        //  Cache search form values to persist between post-redirect-get.
        var cacheEntry = Request.Form["City"];
        _cache.Set<string>("City", cacheEntry);

        TempData["CityFromFrom"] = Request.Form["City"].ToString();
        TempData.Keep("CityFromForm");

        return RedirectToPage();
    }


    // TODO: Find a better way to persist data between onPost and OnGet
    public async Task OnGet(string city)
    {
        City = _cache.Get<string>("City");

        var temp = TempData["CityFromForm"];

        // Here I'd like to pass the TempData["CityFromForm"] but it's null.
        await GetSearchResults(City); // this method just gets data from the database

    }

2 Answers2

0

TempData keys are prefixed by "TempDataProperty-". So if you have a key named "City", you access it via TempData["TempDataProperty-City"].

See https://www.learnrazorpages.com/razor-pages/tempdata

You also have a typo in the line where you assign the tempdata value: TempData["CityFromFrom"] should be TempData["CityFromForm"], I suspect.

Mike Brind
  • 28,238
  • 6
  • 56
  • 88
  • Thanks for joining the discussion. Sadly, I went to that guide and used the TempData["TempDataProperty-xxx"] but without success. TempDataDictionary count is one while in OnPost method, as soon as it goes to the OnGet method, temp data count is 0, even though TempData.Keep() was used. –  Oct 28 '18 at 21:17
0

So here is what I came up with, basically I get a city string from the search form. In the OnPost method I redirect to page where I add a route value which OnGet method can use.

In SearchResults.cshtml I added a @page "{city?}"

The url ends up looking like: https://localhost:44302/Search/SearchResults?searchCity={city}

In SearchResults.cshtml.cs

    public async Task OnGet()
    {
        City = HttpContext.Request.Query["searchCity"];
        PetGuardians = await GetSearchResults(City);
    }

    public IActionResult OnPost(string city)
    {
        return RedirectToPage(new { searchCity = city });
    }