如何使用剃刀页面在ASP.Net Core上将对象从一个页面传递到另一个页面?

时间:2017-10-16 14:23:54

标签: c# razor asp.net-core

我正在使用带有剃刀页面的Asp.net核心2.0开发Web应用程序。我正在创建一个包含一些数据的对象,并希望将该对象发送到另一个页面。

其实我这样做:

var customObject = new{
   //some values
};
return RedirectToPage("NewPage", customObject);

我看到url具有我发送的对象的值,但是我无法找到如何获取该值(在NewPage实例中)。

有人知道如何在剃刀页面之间共享对象吗?这是实现它的正确方法吗?还是有另一种更好的方法吗?

提前致谢

5 个答案:

答案 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将对象从一页传递到另一页。

  1. 模型类。

    public class Car
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public string Model { get; set; }
        public string Description { get; set; }
    }
    
  2. 汽车-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" }
        };
    }
    
  3. 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>
    
  4. 详细信息-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();
        }
    }
    
  5. 详细信息-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();
}

您可以在IndexModelCustomModel之间交换数据,例如。设置为

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(更实用)