所以我试着用Blazor(而不是WebAssembly(玩了一段时间,但一直使用Redirects和Headers响应。
Post.cs:
public class PostService
{
public List<Post> posts = new List<Post>()
{
new Post { ID = 1, Title = "First title", Text = "first text", Date = DateTime.Now, Author = "JohnDoe", Category = "Good" },
new Post { ID = 2, Title = "Second title", Text = "second text", Date = DateTime.Now, Author = "JohnDoe", Category = "Nice" }
};
public Task<List<Post>> GetPosts()
{
return Task.FromResult(posts);
}
public Task<Post> GetPost(int id)
{
Post post = posts.Where(x => x.ID == id).FirstOrDefault();
return Task.FromResult(post);
}
}
BlogPost.razor:
@page "/post/{ID:int}"
@using ExampleBlog.Data;
@inject PostService PostClassService
@inject NavigationManager _navigationManager
@if (post == null)
{
<p>Loading</p>
}
else
{
@post.Text
}
@code {
[Parameter]
public int ID { get; set; }
public Post post { get; set; }
public bool found { get; set; } = true;
protected override async Task OnInitializedAsync()
{
post = await PostClassService.GetPost(ID);
if (post == null)
{
found = false;
}
}
protected override void OnAfterRender(bool firstRender)
{
if (firstRender)
{
if (!found)
{
_navigationManager.NavigateTo("404");
}
}
}
}
帖子显示,一切都很好。如果ID正确,则显示文本,并在浏览器中正确重定向到404。
问题是服务器标头返回:
curl -i --insecure https://localhost:44332/post/1
HTTP/2 200
它是可以的,工作得很好,但如果我将尝试到达不存在的实体:
curl -i --insecure https://localhost:44332/post/1234
HTTP/2 200
我需要返回404服务器端,这样搜索引擎等才能正确识别所有内容。
它没有返回未找到,因为它实际上正在查找页面路由签名Post(int)
。试着在那里设置一个断点。
你需要像这样的东西
public Task<Post> GetPost(int id)
{
Post post = posts.Where(x => x.ID == id).FirstOrDefault();
if (post == null)
{
return NotFound();
}
else
{
return Task.FromResult(post);
}
}
所以我发现坏的解决方法,效果很好。
protected override async Task OnInitializedAsync()
{
post = await PostClassService.GetPost(ID);
if (post == null)
{
found = false;
#if !DEBUG
_navigationManager.NavigateTo("404");
#endif
}
#需要调试,因为blazor错误在调试时会引发NavigationManager异常。
并更改Startup.cs 中的端点
app.UseEndpoints(endpoints =>
{
endpoints.MapBlazorHub();
endpoints.MapFallbackToPage("/_Host");
endpoints.MapGet("/404", async context =>
{
context.Response.StatusCode = 404;
await context.Response.WriteAsync("404 not found");
});
});
如果我在发行版中运行它,一切都很好(除了它返回的404未找到的空白页(
curl -i --insecure https://localhost:44332/post/1
HTTP/2 200
curl -i --insecure https://localhost:44332/post/1234
HTTP/2 302
content-type: text/html; charset=utf-8
location: https://localhost:44332/404