我正在使用带有剃刀页面的Asp.net核心2.0开发Web应用程序。我正在创建一个包含一些数据的对象,并希望将该对象发送到另一个页面。
其实我这样做:
var customObject = new{
//some values
};
return RedirectToPage("NewPage", customObject);
我看到url具有我发送的对象的值,但是我无法找到如何获取该值(在NewPage实例中)。
有人知道如何在剃刀页面之间共享对象吗?这是实现它的正确方法吗?还是有另一种更好的方法吗?
提前致谢
答案 0 :(得分:19)
您可以将参数传递给页面模型类中的指定处理程序,如下所示:
return RedirectToPage("Orders", "SingleOrder", new {orderId = order.Id});
页面模型类方法具有此签名:
public void OnGetSingleOrder(int orderId)
如果要传递对象,则可以直接传递对象,但根据我的经验,不会填充任何子对象。
答案 1 :(得分:3)
此处的关键是您需要传递一个匿名对象,该对象的属性名称与“剃刀页面”中定义的路由约束条件相匹配。
例如,如果您在“剃刀页面”中定义了id
(可选)路由约束:
@page "{id?}"
要通过特定的id
重定向到该视图,只需执行以下操作:
return RedirectToPage("PageName", new { id = 3 });
如果您只是一个重定向到当前页面(但传递了特定的id
),请执行以下操作:
return RedirectToPage(new { id = 3 });
如果仅传递不带匿名对象的数字,则将无效。
答案 2 :(得分:2)
通过Anchor Tag Helper将对象从一页传递到另一页。
模型类。
public class Car
{
public int ID { get; set; }
public string Name { get; set; }
public string Model { get; set; }
public string Description { get; set; }
}
汽车-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( 传递对象的来源 )->显示“ CarsModel”列表中的所有项(在我们的情况下为car)。在“锚标记帮助器”中,使用“ asp-all-route-data”属性,该属性以字典名称作为字符串初始化(在我们的示例中为“ 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>
详细信息-PageModel(
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();
}
}
详细信息-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>
答案 3 :(得分:1)
我不知道这对你是否有帮助,或者对于像Razor这样的MVVM风格是一个好习惯,但在ASP.NET Core API项目中,我经常使用自定义全局DI'ed服务,比如
public void ConfigureServices(IServiceCollection services)
{
...
services.AddSingleton<IMyService, MyService>();
...
services.AddMvc();
}
您可以在IndexModel
和CustomModel
之间交换数据,例如。设置为
public class CustomModel : PageModel
{
public IMyService _myService;
public CustomModel(IMyService myService)
{
_myService = myService;
}
public async Task<IActionResult> OnPostAsync(...)
{
...
_myService.SetDataOrSometing(...);
...
return RedirectToPage();
}
}
并像
一样检索它public class IndexModel : PageModel
{
public IMyService _myService;
public IndexModel(IMyService myService)
{
_myService = myService;
}
public void OnGet()
{
var data = _myService.GetDataOrSomething();
}
}
从这里,您还可以使用ObserveableCollection并注册事件以将更新下载到您的PageModel。
恕我直言,这是一种将对象从一个页面传递到另一个页面的方法,可以清晰地分离关注点。
答案 4 :(得分:0)
您可以使用TempData装饰器。它可以用作装饰器或字典,其目的是在请求之间保留对象。您可以在后台将值存储在Cookie或用户会话中。您可以在以下链接中查看有关其使用的更多详细信息:
TempData at Microsoft Documentation
TempData in Learn Razor Pages(更实用)