I\'m developing a web application using Asp.net core 2.0 with razor pages. I\'m creating an object with some data and want to send that object to another page.
Actua
You can use the TempData decorator. It is available as a decorator or as a dictionary and its purpose is to keep an object between requests. In the background, the value is stored in a cookie or in the user session, at your choice. You can see more details about its use in the links below:
TempData at Microsoft Documentation
TempData in Learn Razor Pages (more practical)
I don't know if that might help you or it is good practice for MVVM flavours like Razor, but inside ASP.NET Core API projects I often use custom global DI'ed services, like
public void ConfigureServices(IServiceCollection services)
{
...
services.AddSingleton<IMyService, MyService>();
...
services.AddMvc();
}
You can exchange data between your IndexModel
and a CustomModel
eg. by setting it like
public class CustomModel : PageModel
{
public IMyService _myService;
public CustomModel(IMyService myService)
{
_myService = myService;
}
public async Task<IActionResult> OnPostAsync(...)
{
...
_myService.SetDataOrSometing(...);
...
return RedirectToPage();
}
}
and retrieving it like
public class IndexModel : PageModel
{
public IMyService _myService;
public IndexModel(IMyService myService)
{
_myService = myService;
}
public void OnGet()
{
var data = _myService.GetDataOrSomething();
}
}
From here you can also use an ObserveableCollection and register events to get the updates down to your PageModels.
IMHO this is a way to pass objects from one page to another with a clean separation of concerns.
Pass object from one page to another through Anchor Tag Helper.
Model class.
public class Car
{
public int ID { get; set; }
public string Name { get; set; }
public string Model { get; set; }
public string Description { get; set; }
}
Cars - PageModel.
public class CarsModel : PageModel
{
public List<Car> Cars { get; private set; } = new List<Car> {
new Car{ ID = 1, Name = "Car1", Model = "M1", Description = "Some description" },
new Car{ ID = 2, Name = "Car2", Model = "M2", Description = "Some description" },
new Car{ ID = 3, Name = "Car3", Model = "M3", Description = "Some description" },
new Car{ ID = 4, Name = "Car4", Model = "M4", Description = "Some description" }
};
}
Cars - RazorPage(source of the pass-object) -> display all items(in our case cars) from the list of 'CarsModel'. In the 'Anchor Tag Helper' use 'asp-all-route-data' attribute, which is initialized with dictionary name as string(in our case 'dictCars').
@page
@using Newtonsoft.Json
@model CarsModel
@{
ViewData["Title"] = "Cars";
}
<table>
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.Cars[0].Name)
</th>
<th>
@Html.DisplayNameFor(model => model.Cars[0].Model)
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var car in Model.Cars)
{
Dictionary<string, string> dictCars =
new Dictionary<string, string> { { "passedObject", JsonConvert.SerializeObject(car) } };
<tr>
<td>
@Html.DisplayFor(modelItem => car.Name)
</td>
<td>
@Html.DisplayFor(modelItem => car.Model)
</td>
<td>
<a asp-page="./Details" asp-all-route-data="dictCars">Details</a>
</td>
</tr>
}
</tbody>
</table>
Details - PageModel(destination of the pass-object).
public class DetailsModel : PageModel
{
public Car Car { get; set; }
public IActionResult OnGet(string passedObject)
{
Car = JsonConvert.DeserializeObject<Car>(passedObject);
if (Car == null)
{
return NotFound();
}
return Page();
}
}
Details - RazorPage.
@page
@model DetailsModel
@{
ViewData["Title"] = "Car Details";
}
<h2>Details</h2>
<div>
<h4>Car</h4>
<hr />
<dl class="dl-horizontal">
<dt>
@Html.DisplayNameFor(model => model.Car.Name)
</dt>
<dd>
@Html.DisplayFor(model => model.Car.Name)
</dd>
<dt>
@Html.DisplayNameFor(model => model.Car.Model)
</dt>
<dd>
@Html.DisplayFor(model => model.Car.Model)
</dd>
<dt>
@Html.DisplayNameFor(model => model.Car.Description)
</dt>
<dd>
@Html.DisplayFor(model => model.Car.Description)
</dd>
</dl>
</div>
The key here is that you need to pass an anonymous object whose property names match the routing constraints defined in the Razor Page.
For example, if you define an id
(optional) routing constraint in the Razor Page:
@page "{id?}"
To redirect to that view passing a specific id
, just do:
return RedirectToPage("PageName", new { id = 3 });
If you just one to redirect to the current page (but passing a specific id
), just do:
return RedirectToPage(new { id = 3 });
If you just pass the number without the anonymous object it won't work.
You can pass parameters to specified handlers in the page model class, like this:
return RedirectToPage("Orders", "SingleOrder", new {orderId = order.Id});
Where the page model class method has this signature:
public void OnGetSingleOrder(int orderId)
If you are passing an object, you can pass the object directly, but in my experience any child objects are not populated.