.NET 6 Razor Pages SEO Friendly URL

axzmvihb  于 2023-04-08  发布在  .NET
关注(0)|答案(3)|浏览(135)

我试图创建SEO友好的URL的使用.NET 6和剃刀页(不是MVC).从剃刀页面视图:

<a asp-page="/Post" asp-route-id="9">Test Link</a>

我链接到相应的页面处理程序:

[BindProperty]
public PostViewModel? Post { get; set; }

public async Task<IActionResult> OnGetAsync(int id)
{
    Post = new PostViewModel();
    Post = await _postService.GetPostAsync(id);

    return Page();
}

页面处理程序将通过id参数获取帖子。在页面模型PostViewModel中,有CategoryTopicUrlTitle的属性。我想使用这些属性来生成一个SEO友好的URL,如:

https:/wwww.mysite.com/post/{id}/{category}/{topic}/{urltitle}

我不确定如何将这些属性值获取到URL?

yrdbyhpb

yrdbyhpb1#

试试这个代码:
在Razor页面视图中:

<a asp-page="/Post" asp-route-id="@Post.Id" asp-route-category="@Post.Category" asp-route-topic="@Post.Topic" asp-route-urltitle="@Post.UrlTitle">Test Link</a>

更新OnGetAsync方法以接受以下附加路由参数:

public async Task<IActionResult> OnGetAsync(int id, string category, string topic, string urltitle)
{
    Post = new PostViewModel();
    Post = await _postService.GetPostAsync(id);

    if (category != Post.Category || topic != Post.Topic || urltitle != Post.UrlTitle)
    {
        return NotFound();
    }

    return Page();
}

然后使用endpoints.MapRazorPages方法转到Startup类的Configure方法:

app.UseEndpoints(endpoints =>
{
    endpoints.MapRazorPages();
    endpoints.MapControllerRoute(
        name: "post",
        pattern: "/post/{id}/{category}/{topic}/{urltitle}",
        defaults: new { controller = "Post", action = "Index" }
    );
});

在这里,pattern参数指定要匹配的URL模式,defaults参数指定要用于此路由的默认控制器和操作。您还需要创建一个对应的PostControllerIndex操作来处理请求。

fcy6dtqo

fcy6dtqo2#

在您的post页面(.cshtml文件)顶部添加:

@page "{id}/{category}/{topic}/{urltitle}"

在您的首页页面模型(.cshtml.cs文件)中添加:

public List<PostViewModel> Posts { get; set; }

public async Task<IActionResult> OnGetAsync()
{
    Posts = await _postService.GetPostsAsync();

    return Page();
}

然后在您的主页页面中使用以下命令创建链接:

@foreach (var post in Model.Posts)
{
    <a asp-page="/Post"
       asp-route-id="@post.Id"
       asp-route-category="@post.Category"
       asp-route-topic="@post.Topic"
       asp-route-urltitle="@post.UrlTitle">@post.Description</a>
}

检查路由模板

rxztt3cl

rxztt3cl3#

在Asp.net核心Razor页面中,要设置友好URL,我们可以通过.cshtml页面中的@page指令覆盖路由模板,如下所示:

@page "/Post/{id?}/{category?}/{topic?}/{urlTitle?}"

或者,我们可以像这样配置剃刀页面约定:

builder.Services
    .AddRazorPages()
    .AddRazorPagesOptions(options =>
    {
        options.Conventions.AddPageRoute("/Post", "Post/{id?}/{category?}/{topic?}/{urlTitle?}");
    });

第一次命中方法时,只有id存在,然后填充视图模型,但是当第二次命中方法时,只有id,category,topic和urltitle属性被填充,其余的都是空的?
之后,在“索引”页中,可以使用以下超链接访问Get处理程序:

@*href ="/Post/9"*@
<a asp-page="/Post" asp-route-id="9">Test Link</a>

@*href ="/Post/9/C1/T1/U1"*@
<a asp-page="/Post" asp-route-id="9" asp-route-category="C1" asp-route-topic="T1" asp-route-urltitle="U1">Test Link</a>

对于category、topic或urltitle参数,如果你想使用textbox编辑它们,你可以使用JavaScript根据参数构建请求url。代码如下:

@page "/Post/{id?}/{category?}/{topic?}/{urlTitle?}"
@model RazorWebApp.Pages.PostModel
@*<a asp-page="/Post" asp-route-id="9">Test Link</a>*@

<h2>Test Post page</h2>

<form method="get" asp-route-id="@Model?.Post?.Id">
    <p>
        <input type="hidden" id="txtId" asp-for="Post.Id" />
        Category: <input type="text" id="txtcategory" asp-for="Post.Category"  />
        Topic: <input type="text" id="txttopic" asp-for="Post.Topic"  />
        Url Title: <input type="text" id="txturltitle" asp-for="Post.UrlTitle"/>

        <input type="submit" value="Test Link (Submit Button)" />

        <a asp-page="/Post" asp-route-id="@Model?.Post?.Id" 
        asp-route-category="@Model?.Post?.Category" 
        asp-route-topic="@Model?.Post?.Topic" 
        asp-route-urltitle="@Model?.Post?.UrlTitle"
        onclick="return HyperLinkClick(this);"
        >Test Link (Hyperlink)</a>
    </p>
</form>

@section Scripts{
   <script>
        function HyperLinkClick(e) {
           event.preventDefault();
            var id = document.getElementById("txtId").value === "" ? "null" : parseInt(document.getElementById("txtId").value);
            var category = document.getElementById("txtcategory").value === "" ? "null" : document.getElementById("txtcategory").value;
            var topic = document.getElementById("txttopic").value === "" ? "null" : document.getElementById("txttopic").value;
            var urltitle = document.getElementById("txturltitle").value === "" ? "null" : document.getElementById("txturltitle").value;

            if (category != "null" && topic != "null" && urltitle != "null"){ 
                window.location.href = "/Post/"+ id + "/" + category + "/" + topic + "/" + urltitle;
            }
       }
   </script> 
}

结果如下:

更新

category、topic和urltitle值存储在数据库中,而不是作为用户输入表单
在这种情况下,您可以修改Post页面代码如下:

public class PostModel : PageModel
{
    //[BindProperty]
    [BindProperty(SupportsGet = true)]
    public PostViewModel? Post { get; set; }

    public async Task<IActionResult> OnGetAsync(int id)
    {

        //find the post based on the id.
        if (id==9)
        {
            //Post = await _postService.GetPostAsync(id);
            Post = new PostViewModel() { 
                Id = id, Category="C1", 
                Topic="T1", UrlTitle="U1" };
        }

        return Page();
    }
}

Post.cshtml页面:

@page "/Post/{id?}/{category?}/{topic?}/{urlTitle?}"
@model RazorWebApp.Pages.PostModel
@*<a asp-page="/Post" asp-route-id="9">Test Link</a>*@

<h2>Test Post page</h2>

<a asp-page="/Post" asp-route-id="@Model?.Post?.Id"
   asp-route-category="@Model?.Post?.Category"
   asp-route-topic="@Model?.Post?.Topic"
   asp-route-urltitle="@Model?.Post?.UrlTitle"
   onclick="return HyperLinkClick(this);">Test Link (Hyperlink)</a>

那么,结果如下:请注意左下角超链接的url。

相关问题