1
public class HomeController : Controller
{
    public ActionResult SitemapXML()
    {
        return new XmlSiteMapResult();
    }
}

如何在没有 BOM 的情况下生成编码 utf-8 的站点地图?

4

1 回答 1

0

创建一个类来覆盖 XmlSiteMapResult 的默认行为,以便它排除 BOM。

public class MyXmlSiteMapResult : XmlSiteMapResult
{

    /// <summary>
    /// Maximal number of links per sitemap file.
    /// </summary>
    /// <remarks>
    /// This number should be 50000 in theory, see http://www.sitemaps.org/protocol.php#sitemapIndex_sitemap.
    /// Since sitemap files can be maximal 10MB per file and calculating the total sitemap size would degrade performance,
    /// an average cap of 35000 has been chosen.
    /// </remarks>
    private const int MaxNumberOfLinksPerFile = 35000;

    protected override void ExecuteSitemapIndexResult(ControllerContext context, IEnumerable<SiteMapNode> flattenedHierarchy, long flattenedHierarchyCount)
    {
        // Count the number of pages
        double numPages = Math.Ceiling((double)flattenedHierarchyCount / MaxNumberOfLinksPerFile);

        // Output content type
        context.HttpContext.Response.ContentType = "text/xml";

        // Generate sitemap sitemapindex
        var sitemapIndex = new XElement(Ns + "sitemapindex");
        sitemapIndex.Add(GenerateSiteMapIndexElements(Convert.ToInt32(numPages), Url, SiteMapUrlTemplate).ToArray());

        // Generate sitemap
        var xmlSiteMap = new XDocument(
            new XDeclaration("1.0", "utf-8", "true"),
            sitemapIndex);

        // Specify to emit XML with no BOM
        var settings = new XmlWriterSettings();
        settings.Encoding = new System.Text.UTF8Encoding(false);

        // Write XML
        using (Stream outputStream = RetrieveOutputStream(context))
        {
            using (var writer = XmlWriter.Create(outputStream, settings))
            {
                xmlSiteMap.WriteTo(writer);
            }
            outputStream.Flush();
        }
    }

    protected override void ExecuteSitemapResult(ControllerContext context, IEnumerable<SiteMapNode> flattenedHierarchy, long flattenedHierarchyCount, int page)
    {

        // Output content type
        context.HttpContext.Response.ContentType = "text/xml";

        // Generate URL set
        var urlSet = new XElement(Ns + "urlset");
        urlSet.Add(GenerateUrlElements(
            flattenedHierarchy.Skip((page - 1)* MaxNumberOfLinksPerFile)
                .Take(MaxNumberOfLinksPerFile), Url).ToArray());

        // Generate sitemap
        var xmlSiteMap = new XDocument(
            new XDeclaration("1.0", "utf-8", "true"),
            urlSet);

        // Specify to emit XML with no BOM
        var settings = new XmlWriterSettings();
        settings.Encoding = new System.Text.UTF8Encoding(false);

        // Write XML
        using (Stream outputStream = RetrieveOutputStream(context))
        {
            using (var writer = XmlWriter.Create(outputStream, settings))
            {
                xmlSiteMap.WriteTo(writer);
            }
            outputStream.Flush();
        }
    }
}

然后返回您的自定义类。

public class HomeController : Controller
{
    public ActionResult SitemapXML()
    {
        return new MyXmlSiteMapResult();
    }
}

注意:此示例假设您使用的是 MvcSiteMapProvider v3,因为在 v4 中,XmlSiteMapResult 类不再具有默认构造函数(在 v4 中,您必须使用 XmlSiteMapResultFactory 来获取 XmlSiteMapResult 的实例,因此您还需要覆盖 XmlSiteMapResultFactory 以返回您的自定义类的实例)。

参考:如何使用 C# 从 XmlTextWriter 中删除 BOM?

于 2013-09-27T06:57:19.190 回答