我正在尝试解决一个错误,其中我在http://captainobvio.us上生成的所有RSS feed都会在Internet Explorer(版本8和9)中产生以下错误:



问题在于,通过HTTP header 发送的实际编码类型与文档中声明的编码类型不同。这是将供稿的输出写入HTML的代码:

public ContentResult Index()
        {
            var feed = _syndication.SyndicateIdeas(_repository.GetIdeas(0,15).Ideas);

            var sb = new StringBuilder();
            using (var writer = XmlWriter.Create(sb, new XmlWriterSettings { Encoding = Encoding.UTF8, NewLineHandling = NewLineHandling.Entitize, NewLineOnAttributes = true, Indent = true}))
            {
                feed.SaveAsRss20(writer);
                writer.Close();
            }

            return Content(sb.ToString(), "application/rss+xml", Encoding.UTF8);
        }

这是在.NET 4.0中使用System.ServiceModel.Syndication实际构建提要的代码:
var feed = new SyndicationFeed("CaptainObvio.us - Recent Ideas",
                                          "The most recent ideas posted by the Community on CaptainObvio.us", new Uri("http://captainobvio.us/"), "CaptainObvio.us", new DateTimeOffset(ideas[0].DatePosted), items)
                           {
                               Generator = "CaptainObvio.us - http://captainobvio.us/"
                           };

            return feed;

我想做的是将XML文档更改为读取utf-8而不是utf-16。我还检查了Encoding命名空间,看是否有UTF16选项(这样我可以更正HTTP header 而不是XML文档)并且找不到。

有没有简单的方法可以直接从System.ServiceModel.Syndication更改XML文档上的编码属性?解决此问题的最简单方法是什么?

最佳答案

发生这种情况的原因是因为您要将StringBuilder传递给XmlWriter构造函数。 .NET中的字符串是unicode,因此XmlWriter假定使用utf-16,并且您无法进行修改。

因此,您可以使用流而不是字符串生成器,然后可以通过以下设置控制编码:

var settings = new XmlWriterSettings
{
    Encoding = Encoding.UTF8,
    NewLineHandling = NewLineHandling.Entitize,
    NewLineOnAttributes = true,
    Indent = true
};
using (var stream = new MemoryStream())
using (var writer = XmlWriter.Create(stream, settings))
{
    feed.SaveAsRss20(writer);
    writer.Flush();
    return File(stream.ToArray(), "application/rss+xml; charset=utf-8");
}

所有这些都说是一个更好,更多的MVCish,我建议您使用的解决方案是编写一个SyndicationResult:
public class SyndicationResult : ActionResult
{
    private readonly SyndicationFeed _feed;
    public SyndicationResult(SyndicationFeed feed)
    {
        if (feed == null)
        {
            throw new HttpException(401, "Not found");
        }
        _feed = feed;
    }

    public override void ExecuteResult(ControllerContext context)
    {
        var settings = new XmlWriterSettings
        {
            Encoding = Encoding.UTF8,
            NewLineHandling = NewLineHandling.Entitize,
            NewLineOnAttributes = true,
            Indent = true
        };

        var response = context.HttpContext.Response;
        response.ContentType = "application/rss+xml; charset=utf-8";
        using (var writer = XmlWriter.Create(response.OutputStream, settings))
        {
            _feed.SaveAsRss20(writer);
        }
    }
}

并在您的 Controller Action 中简单地返回此结果,以使您不会因管道代码而使您的 Controller Action 困惑:
public ActionResult Index()
{
    var ideas = _repository.GetIdeas(0, 15).Ideas;
    var feed = _syndication.SyndicateIdeas(ideas);
    return new SyndicationResult(feed);
}

关于.net - .NET ServiceModel.Syndication-更改RSS Feed上的编码,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5452878/

10-12 00:36
查看更多