ASP.NET Core生成sitemap.xml,如何返回XML数据?记录一下踩的坑,使用ABP的朋友一定要看一下
先添加两个实体
[XmlType("url")]
public class UrlDto
{
public string loc { get; set; }
public string priority { get; set; }
public string lastmod { get; set; }
public string changefreq { get; set; }
}
[XmlRoot(Namespace = "http://www.sitemaps.org/schemas/sitemap/0.9")]
[XmlType("urlset")]
public class Urlset
{
[XmlElement("url")]
public List<UrlDto> Urls { get; set; } = new List<UrlDto>();
}
再根据自己的想法添加数据即可
public async Task<Urlset> GetUrlsetAsync(string url)
{
return await _cacheManager.GetCache(SitemapCacheNames.CacheSitemap)
.GetAsync("Admin", async k =>
{
var articleIds = await _articleRepository
.GetAll()
.OrderByDescending(p => p.CreationTime)
.Select(p => p.Id)
.ToListAsync();
var typeIds = await _articleTypeRepository
.GetAll()
.Select(p => p.Id)
.ToListAsync();
var tagNames = await _articleTagRepository
.GetAll()
.Select(p => p.Name)
.ToListAsync();
Urlset urlset = new Urlset();
urlset.Urls.Add(new UrlDto() { loc = url, lastmod = DateTime.Now.ToShortDateString(), changefreq = "weekly", priority = "1.00" });
foreach (var item in typeIds)
{
urlset.Urls.Add(new UrlDto() { loc = $"{url}/Article/Type_{item}.html", changefreq = "weekly", priority = "1.00" });
}
foreach (var item in articleIds)
{
urlset.Urls.Add(new UrlDto() { loc = $"{url}/Article/Details_{item}.html", changefreq = "daily", priority = "0.90" });
}
foreach (var item in tagNames)
{
urlset.Urls.Add(new UrlDto() { loc = $"{url}/Article/Tag_{item}.html", changefreq = "daily", priority = "0.80" });
}
return urlset;
}) as Urlset;
}
接下来创建控制器
[Route("")]
[ApiController]
public class SitemapController : BlogControllerBase
{
private readonly ISitemapAppService _sitemapAppService;
public SitemapController(ISitemapAppService sitemapAppService)
{
_sitemapAppService = sitemapAppService;
}
[DontWrapResult]
[HttpGet("sitemap.{format}"), FormatFilter]
public async Task<Urlset> GetSitemap()
{
return await _sitemapAppService.GetUrlsetAsync($"https://{Request.Host}");
}
}
这里需要注意一下,如果有用ABP的朋友,这里的[HttpGet("sitemap.{format}"), FormatFilter]最好改成[HttpGet("sitemap.xml")]
如果不改的话,会导致使用不了动态WEBAPI【有更好办法的朋友请评论告诉我】
最后在Startup.cs添加配置了
services.AddMvc(
options =>
{
options.RespectBrowserAcceptHeader = true;
options.OutputFormatters.Add(new XmlSerializerOutputFormatter());
options.FormatterMappings.SetMediaTypeMappingForFormat("xml", Microsoft.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/xml"));
options.FormatterMappings.SetMediaTypeMappingForFormat("config", Microsoft.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/xml"));
options.FormatterMappings.SetMediaTypeMappingForFormat("js", Microsoft.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json"));
})
.AddXmlSerializerFormatters()
.AddXmlDataContractSerializerFormatters()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
UrlDto和Urlset两个实体一定要有无参构造函数,否则会识别不了,导致返回的数据是空的,血的教训,记录一下
下面是效果图