fix(seo): proper 500 handler + safe JSON-LD escaping
Add UseExceptionHandler(/error) so unhandled exceptions return a proper HTML 500 instead of a raw response Googlebot was logging as a server error in Search Console. Replace manual quote-only escaping in blog JSON-LD with a J() helper that uses JsonSerializer so newlines, backslashes, and all other control characters are safely escaped. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -8,6 +8,8 @@
|
|||||||
var articleType = ViewData["ArticleType"]?.ToString() ?? "MedicalWebPage";
|
var articleType = ViewData["ArticleType"]?.ToString() ?? "MedicalWebPage";
|
||||||
var pubDate = post.PublishedAt?.ToString("yyyy-MM-ddTHH:mm:ssZ") ?? "";
|
var pubDate = post.PublishedAt?.ToString("yyyy-MM-ddTHH:mm:ssZ") ?? "";
|
||||||
var updDate = post.UpdatedAt.ToString("yyyy-MM-ddTHH:mm:ssZ");
|
var updDate = post.UpdatedAt.ToString("yyyy-MM-ddTHH:mm:ssZ");
|
||||||
|
// Escape a string for safe embedding inside a JSON string literal.
|
||||||
|
static string J(string? s) => System.Text.Json.JsonSerializer.Serialize(s ?? "")[1..^1];
|
||||||
}
|
}
|
||||||
|
|
||||||
@section Head {
|
@section Head {
|
||||||
@@ -32,13 +34,13 @@
|
|||||||
<script type="application/ld+json">
|
<script type="application/ld+json">
|
||||||
{
|
{
|
||||||
"@@context": "https://schema.org",
|
"@@context": "https://schema.org",
|
||||||
"@@type": "@articleType",
|
"@@type": "@J(articleType)",
|
||||||
"headline": "@post.Title.Replace("\"","\\\"") ",
|
"headline": "@J(post.Title)",
|
||||||
"description": "@(ViewData["MetaDesc"]?.ToString()?.Replace("\"","\\\""))",
|
"description": "@J(ViewData["MetaDesc"]?.ToString())",
|
||||||
"author": { "@@type": "Person", "name": "@post.Author" },
|
"author": { "@@type": "Person", "name": "@J(post.Author)" },
|
||||||
"publisher": {
|
"publisher": {
|
||||||
"@@type": "Organization",
|
"@@type": "Organization",
|
||||||
"name": "@ViewData["SiteName"]",
|
"name": "@J(ViewData["SiteName"]?.ToString())",
|
||||||
"url": "@baseUrl"
|
"url": "@baseUrl"
|
||||||
},
|
},
|
||||||
"datePublished": "@pubDate",
|
"datePublished": "@pubDate",
|
||||||
|
|||||||
@@ -57,6 +57,10 @@ builder.Services.ConfigureHttpJsonOptions(opts =>
|
|||||||
// ── Build ─────────────────────────────────────────────────────────────────────
|
// ── Build ─────────────────────────────────────────────────────────────────────
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
|
|
||||||
|
// In production return a clean 500 page rather than an unhandled exception dump
|
||||||
|
// (Googlebot seeing raw 5xx responses causes GSC "Server error" indexing failures).
|
||||||
|
if (!app.Environment.IsDevelopment())
|
||||||
|
app.UseExceptionHandler("/error");
|
||||||
|
|
||||||
app.UseCors();
|
app.UseCors();
|
||||||
app.UseDefaultFiles(); // serves /admin/index.html for /admin/ (wwwroot/index.html deleted → no conflict with Razor Pages)
|
app.UseDefaultFiles(); // serves /admin/index.html for /admin/ (wwwroot/index.html deleted → no conflict with Razor Pages)
|
||||||
@@ -839,6 +843,20 @@ app.MapGet("/api/seo/stats", async (AppDbContext db) =>
|
|||||||
return Results.Ok(new { total, views, topPosts, noMeta });
|
return Results.Ok(new { total, views, topPosts, noMeta });
|
||||||
}).RequireAuthorization();
|
}).RequireAuthorization();
|
||||||
|
|
||||||
|
// Generic error page — returns 500 with a minimal HTML body so Googlebot
|
||||||
|
// gets a proper HTTP 500 (not a connection-reset) and retries cleanly.
|
||||||
|
app.Map("/error", (HttpContext ctx) =>
|
||||||
|
{
|
||||||
|
ctx.Response.StatusCode = 500;
|
||||||
|
ctx.Response.ContentType = "text/html; charset=utf-8";
|
||||||
|
return ctx.Response.WriteAsync(
|
||||||
|
"<!DOCTYPE html><html lang='fa'><head><meta charset='utf-8'>" +
|
||||||
|
"<title>خطای سرور</title></head><body dir='rtl'>" +
|
||||||
|
"<h1>خطای موقت سرور</h1>" +
|
||||||
|
"<p>مشکلی پیش آمده. لطفاً دقایقی دیگر مجدداً تلاش کنید.</p>" +
|
||||||
|
"</body></html>");
|
||||||
|
});
|
||||||
|
|
||||||
app.MapRazorPages();
|
app.MapRazorPages();
|
||||||
app.Run();
|
app.Run();
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user