zoukankan      html  css  js  c++  java
  • 如何在ASP.NET Core 2.0中使用Razor页面

    如何在ASP.NET Core 2.0中使用Razor页面

     DotNetCore 2017-11-22 14:49

    问题

    如何在ASP.NET Core 2.0中使用Razor页面

    创建一个空的项目并修改Startup.cs文件以为MVC添加服务和中间件。

    1. publicvoid ConfigureServices(

    2. IServiceCollection services)

    3. {

    4. services.AddSingleton<IMovieService, MovieService>();

    5. services.AddMvc();

    6. }

    7. publicvoid Configure(

    8. IApplicationBuilder app,

    9. IHostingEnvironment env)

    10. {

    11. app.UseMvc();

    12. }

    添加一个服务和域模型(IMovieService的实现只是示例源代码中的内存列表),

    1. publicclass Movie

    2. {

    3. publicint Id { get; set; }

    4. public string Title { get; set; }

    5. publicint ReleaseYear { get; set; }

    6. public string Summary { get; set; }

    7. }

    8. publicinterface IMovieService

    9. {

    10. List<Movie> GetMovies();

    11. Movie GetMovie(int id);

    12. void AddMovie(Movie item);

    13. void UpdateMovie(Movie item);

    14. void DeleteMovie(int id);

    15. bool MovieExists(int id);

    16. }

    添加输入和输出模型(通过属性绑定接收和发送数据)。

    1. publicclass MovieInputModel

    2. {

    3. publicint Id { get; set; }

    4. [Required]

    5. public string Title { get; set; }

    6. publicint ReleaseYear { get; set; }

    7. public string Summary { get; set; }

    8. }

    9. publicclass MovieOutputModel

    10. {

    11. publicint Id { get; set; }

    12. public string Title { get; set; }

    13. publicint ReleaseYear { get; set; }

    14. public string Summary { get; set; }

    15. public DateTime LastReadAt { get; set; }

    16. }

    添加一个名为Pages的文件夹,并为其添加Index,_Layout,_ViewImports和_ViewStart页面。这些页面与MVC没有区别。另外,为您的CRUD页面添加一个文件夹Movies。

    添加4个新的RazorPage项目到电影文件夹 - 称为索引,创建,编辑和删除。这些将添加.cshtml和.cshtml.cs文件。

    这些页面中的每一个都将通过构造器注入来注入我们的 IMovieService ,例如,

    1. private readonly IMovieService service;

    2. public IndexModel(IMovieService service)

    3. {

    4. this.service = service;

    5. }

    修改Index.cshtml。

    1. @page

    2. @model IndexModel

    3. @{

    4. }

    5. <strong>Movie Listing</strong>

    6. <div>

    7. <a asp-page="/Index">Home</a> |

    8. <a asp-page="./Create">Add New</a>

    9. </div>

    10. <table>

    11. <thead>

    12. <tr>

    13. <th>Title</th>

    14. <th>Year</th>

    15. <th></th>

    16. <th></th>

    17. <th></th>

    18. </tr>

    19. </thead>

    20. <tbody>

    21. @foreach (var item in Model.Movies)

    22. {

    23. <tr>

    24. <td>@item.Title</td>

    25. <td>@item.ReleaseYear</td>

    26. <td><a asp-page="./Edit" asp-route-id="@item.Id">Edit</a></td>

    27. <td><a asp-page="./Delete" asp-route-id="@item.Id">Delete</a></td>

    28. </tr>

    29. }

    30. </tbody>

    31. </table>

    修改Index.cshtml.cs。

    1. public List<MovieOutputModel> Movies { get; set; }

    2. publicvoid OnGet()

    3. {

    4. this.Movies = this.service.GetMovies()

    5. .Select(item => new MovieOutputModel

    6. {

    7. Id = item.Id,

    8. Title = item.Title,

    9. ReleaseYear = item.ReleaseYear,

    10. Summary = item.Summary,

    11. LastReadAt = DateTime.Now

    12. })

    13. .ToList();

    14. }

    修改Create.cshtml。

    1. @page

    2. @model CreateModel

    3. @{

    4. }

    5. <strong>New Movie</strong>

    6. <form method="post">

    7. <div asp-validation-summary="All"></div>

    8. <label asp-for="Movie.Id"></label>

    9. <input asp-for="Movie.Id" /><br />

    10. <label asp-for="Movie.Title"></label>

    11. <input asp-for="Movie.Title" />

    12. <span asp-validation-for="Movie.Title"></span><br />

    13. <label asp-for="Movie.ReleaseYear"></label>

    14. <input asp-for="Movie.ReleaseYear" /><br />

    15. <label asp-for="Movie.Summary"></label>

    16. <textarea asp-for="Movie.Summary"></textarea><br />

    17. <button type="submit">Save</button>

    18. <a asp-page="./Index">Cancel</a>

    19. </form>

    修改Create.cshtml.cs。

    1. [BindProperty]

    2. public MovieInputModel Movie { get; set; }

    3. publicvoid OnGet()

    4. {

    5. this.Movie = new MovieInputModel();

    6. }

    7. public IActionResult OnPost()

    8. {

    9. if (!ModelState.IsValid)

    10. return Page();

    11. var model = new Movie

    12. {

    13. Id = this.Movie.Id,

    14. Title = this.Movie.Title,

    15. ReleaseYear = this.Movie.ReleaseYear,

    16. Summary = this.Movie.Summary

    17. };

    18. service.AddMovie(model);

    19. return RedirectToPage("./Index");

    20. }

    修改Edit.cshtml。

    1. @page "{id:int}"

    2. @model EditModel

    3. @{

    4. }

    5. <strong>Edit Movie - @Model.Movie.Title</strong>

    6. <form method="post">

    7. <div asp-validation-summary="All"></div>

    8. <input type="hidden" asp-for="Movie.Id" />

    9. <label asp-for="Movie.Title"></label>

    10. <input asp-for="Movie.Title" />

    11. <span asp-validation-for="Movie.Title"></span><br />

    12. <label asp-for="Movie.ReleaseYear"></label>

    13. <input asp-for="Movie.ReleaseYear" /><br />

    14. <label asp-for="Movie.Summary"></label>

    15. <textarea asp-for="Movie.Summary"></textarea><br />

    16. <button type="submit">Save</button>

    17. <a asp-page="./Index">Cancel</a>

    18. </form>

    修改Edit.cshtml.cs。

    1. [BindProperty]

    2. public MovieInputModel Movie { get; set; }

    3. public IActionResult OnGet(int id)

    4. {

    5. var model = this.service.GetMovie(id);

    6. if (model == null)

    7. return RedirectToPage("./Index");

    8. this.Movie = new MovieInputModel

    9. {

    10. Id = model.Id,

    11. Title = model.Title,

    12. ReleaseYear = model.ReleaseYear,

    13. Summary = model.Summary

    14. };

    15. return Page();

    16. }

    17. public IActionResult OnPost()

    18. {

    19. if (!ModelState.IsValid)

    20. return Page();

    21. var model = new Movie

    22. {

    23. Id = this.Movie.Id,

    24. Title = this.Movie.Title,

    25. ReleaseYear = this.Movie.ReleaseYear,

    26. Summary = this.Movie.Summary

    27. };

    28. service.UpdateMovie(model);

    29. return RedirectToPage("./Index");

    30. }

    修改Delete.cshtml。

    1. @page "{id:int}"

    2. @model DeleteModel

    3. @{

    4. }

    5. <strong>Delete Movie</strong>

    6. <p>Are you sure you want to delete <strong>@Model.Title</strong>?</p>

    7. <form method="post">

    8. <input type="hidden" asp-for="Id" />

    9. <button type="submit">Yes</button>

    10. <a asp-page="./Index">No</a>

    11. </form>

    修改Delete.cshtml.cs。

    1. [BindProperty]

    2. publicint Id { get; set; }

    3. public string Title { get; set; }

    4. public IActionResult OnGet(int id)

    5. {

    6. var model = this.service.GetMovie(id);

    7. if (model == null)

    8. return RedirectToPage("./Index");

    9. this.Id = model.Id;

    10. this.Title = model.Title;

    11. return Page();

    12. }

    13. public IActionResult OnPost()

    14. {

    15. if (!service.MovieExists(this.Id))

    16. return RedirectToPage("./Index");

    17. service.DeleteMovie(this.Id);

    18. return RedirectToPage("./Index");

    19. }

    运行并浏览到/电影。

    点击时,首先编辑(注意网址是/ Movies / Edit / 1),

    点击删除(注意URL将是/电影/删除/ 3),

    注意

    你可以下载源代码来玩它。

    讨论

    在ASP.NET Core 2.0中引入了Razor页面,可以更快地构建简单的Web应用程序,并且是使用各种ASP.NET Core概念(如Razor,Layout Pages和Tag Helper等)的好方法。

    Razor Pages使用 ASP.NET Core MVC ,但是编程模型不一样。与MVC不同,控制器,模型和视图是体系结构的不同组成部分,在Razor Pages中,这些概念被集中到一个页面模型的页面中。

    页面模型

    我喜欢将Page Model视为Controller和Models的组合。他们就像控制器,因为他们收到的HTTP请求,像一个模型,因为他们拥有视图的数据/属性。

    对于.cshtml文件充当Page Model,它必须包含@page指令的第一行。.cshtml.cs(代码隐藏)类继承自PageModel抽象类。按照惯例,代码隐藏类有 模型 附加到页面的名称,例如索引页的代码隐藏是IndexModel。

    路由

    路由到页面取决于它们在您的项目目录结构中位于Pages文件夹下的位置(默认情况下)。如果URL中没有指定页面,则使用默认的索引。

    在我们的示例中,我们导航到URL / Movies以查看位于我们的解决方案中的/ Pages / Movies / Index的页面。类似地,URL / Movies / Edit映射到/ Pages / Movies / Edit页面。

    ASP.NET Core 2.0引入了用于生成URL的新构造,

    • Page()方法

    • asp页面标签助手

    • PageModel基类的RedirectToPage()方法

    请注意,以/开头的URL是绝对路径并指向Pages文件夹。我们也可以使用与./或../相关的URL,或者简单的省略/。为了更好地理解,这里是从Page / Movies / Delete导航到各种URL时发生的情况,

    我们可以将路由约束指定为@page指令的一部分,以指示运行时期望路由参数,或者丢失404(未找到)。在我们的编辑页面中,我们使用约束 -

    1. @page “{id:int}”

    如果您希望使用不同于Pages的名称作为根文件夹,则可以通过配置页面选项来实现。

    1. services.AddMvc()

    2. .AddRazorPagesOptions(options =>

    3. {

    4. options.RootDirectory = "/MyPages";

    5. });

    处理程序

    如前所述,页面接收HTTP请求(即充当MVC世界中的Action),并由 处理程序方法处理。 这些处理程序返回IActionResult并使用On [verb]的约定命名。最常用的是OnGet()和OnPost()。对于异步,您可以将Async附加到名称,但是这是可选的。

    PageModel基类具有RedirectToPage()方法(返回RedirectToPageResult)导航到其他页面和Page()方法(返回PageResult)返回当前页面。请注意,如果处理程序方法的返回类型为void,则运行时将返回PageResult。

    为了让HTTP动词拥有多个处理器方法,我们可以使用 asp-page-handler属性来使用 命名处理器方法。这里指定的名字应该在页面类中使用约定On [动词] [处理程序]。让我们添加一个链接到我们的电影列表删除电影,

    1. <td>

    2. <a asp-page="./Index"

    3. asp-page-handler="delete"

    4. asp-route-id="@item.Id">Delete</a>

    5. </td>

    在页面模型类中添加一个方法来处理这个请求(注意它的名字和参数),

    1. public IActionResult OnGetDelete(int id)

    2. {

    3. if (!service.MovieExists(id))

    4. return RedirectToPage("./Index");

    5. service.DeleteMovie(id);

    6. return RedirectToPage("./Index");

    7. }

    将鼠标移到删除链接上,您会注意到像/ Movies?id = 1&handler = delete这样的URL。如果您希望用URL段替换查询参数,则将以下路由约束添加到@page指令,生成的URL将为/ Movies / delete / 1,

    1. @page "{handler?}/{id:int?}"

    捆绑

    页面上的@model指令指向页面模型类,因为如前所述,该类充当Razor页面的模型。这适用于读取属性,但为了在发布数据时填充它们(即,当使用除GET之外的动词时),我们需要使用属性[BindProperty]来标记要使用模型绑定的属性。

  • 相关阅读:
    刷题总结——疫情控制(NOIP2012提高组)
    刷题总结——竞赛得分(ssoj)
    刷题总结——货车运输
    刷题总结——火柴排队(NOIP2013)
    刷题总结——烽火传递(单调队列+dp)
    刷题总结——道路覆盖(ssoj)
    刷题总结——过河(NOIP2015)
    刷题总结——子串(NOIP2015提高组)
    linux shell 学习笔记--文件测试符
    linux shell 学习笔记--比较操作
  • 原文地址:https://www.cnblogs.com/tianfengcc/p/7879214.html
Copyright © 2011-2022 走看看