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

gsa*_*ana 12 c# razor asp.net-core

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

其实我这样做:

var customObject = new{
   //some values
};
return RedirectToPage("NewPage", customObject);
Run Code Online (Sandbox Code Playgroud)

我看到url具有我正在发送的对象的值,但我找不到如何获取该值(在NewPage实例中).

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

提前致谢

hil*_*tuk 30

您可以将参数传递给页面模型类中的指定处理程序,如下所示:

return RedirectToPage("Orders", "SingleOrder", new {orderId = order.Id});
Run Code Online (Sandbox Code Playgroud)

页面模型类方法具有此签名的位置:

public void OnGetSingleOrder(int orderId)
Run Code Online (Sandbox Code Playgroud)

如果要传递对象,则可以直接传递对象,但根据我的经验,不会填充任何子对象.

  • 我同意。这是正确的答案。我已经使用多个键值对对其进行了测试,每次它都非常有效。您可能还想考虑使用[会话状态](https://www.learnrazorpages.com/razor-pages/session-state)。 (2认同)
  • 这是描述它的页面:https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.razorpages.pagebase.redirecttopage?view=aspnetcore-2.2#Microsoft_AspNetCore_Mvc_RazorPages_PageBase_RedirectToPage_System_String_System_String_System_Object_System_String_ (2认同)

Ted*_*Ted 7

通过 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; }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  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" }
        };
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 汽车 - RazorPage(传递对象的来源)-> 显示“CarsModel”列表中的所有项目(在我们的例子中是汽车)。在“Anchor Tag Helper”中使用“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>
    
    Run Code Online (Sandbox Code Playgroud)
  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();
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  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>
    
    Run Code Online (Sandbox Code Playgroud)


Edu*_*dez 6

这里的关键是您需要传递一个匿名对象,该对象的属性名称与“剃刀页面”中定义的路由约束条件相匹配。

例如,如果您id在“剃刀页面”中定义了(可选)路由约束:

@page "{id?}"

要通过传递特定的重定向到该视图id,只需执行以下操作:

return RedirectToPage("PageName", new { id = 3 });
Run Code Online (Sandbox Code Playgroud)

如果您只是一个重定向到当前页面(但传递了id),则请执行以下操作:

return RedirectToPage(new { id = 3 });
Run Code Online (Sandbox Code Playgroud)

如果您仅传递不带匿名对象的数字,则它将无效。


Ric*_*uio 6

您可以使用 TempData 装饰器。它可以用作装饰器或字典,其目的是在请求之间保留对象。在后台,该值存储在 cookie 中或用户会话中,具体由您选择。您可以在以下链接中查看有关其使用的更多详细信息:

Microsoft 文档中的
TempData Learn Razor 页面中的 TempData(更实用)


mar*_*ine 0

我不知道这是否对您有帮助,或者对于像 Razor 这样的 MVVM 风格来说这是一个很好的实践,但是在 ASP.NET Core API 项目中,我经常使用自定义的全局 DI'ed 服务,例如

public void ConfigureServices(IServiceCollection services)
{
    ...

    services.AddSingleton<IMyService, MyService>();

    ...

     services.AddMvc();
}
Run Code Online (Sandbox Code Playgroud)

IndexModel您可以在您和例如之间交换数据CustomModel。通过将其设置为

public class CustomModel : PageModel
{
   public IMyService _myService;

   public CustomModel(IMyService myService)
   {
       _myService = myService;
   }

   public async Task<IActionResult> OnPostAsync(...)
   {
        ...

        _myService.SetDataOrSometing(...);

        ...

        return RedirectToPage();
   }
}
Run Code Online (Sandbox Code Playgroud)

并像这样检索它

public class IndexModel : PageModel
{
    public IMyService _myService;

    public IndexModel(IMyService myService)
    {
        _myService = myService;
    }

    public void OnGet()
    {
        var data = _myService.GetDataOrSomething();
    }
}
Run Code Online (Sandbox Code Playgroud)

从这里您还可以使用 ObserveableCollection 并注册事件来获取 PageModel 的更新。

恕我直言,这是一种将对象从一个页面传递到另一个页面的方法,并且可以清楚地分离关注点。

  • 您如何知道哪个客户端将哪些数据放在那里?当且仅当一个客户端正在使用该系统时,才没有问题。您可以在生命周期内使用 IMemoryCache。这个答案中定义的方法不是一个好的做法。 (16认同)
  • 同意:hillstuk 给出了在 ASP.Net Core MVC Razor 视图之间传递数据的[“正确答案”](/sf/answers/3330427131/) 具体来说: 1) 定义视图模型。它可以是 POCO。将其放入“模型”文件夹中。2) 在视图的参数列表中声明视图模型。3) 在 `RedirectToPage()` 调用中创建一个匿名实例。 (2认同)