在<link>元素上使用Razor 2编写RSS失败

Dre*_*kes 12 .net asp.net-mvc razor asp.net-mvc-4 razor-2

我昨天升级到了MVC 4,刚刚发现了升级引入的bug.

我有一个用于生成RSS提要的Razor视图.它有一些这样的标记(简化):

<item>
    <title>@post.BlogPost.Title</title> 
    <link>@Url.BlogPost(post.BlogPost, isAbsolute: true)</link>
</item>
Run Code Online (Sandbox Code Playgroud)

在Razor第二版中,对HTML5 void元素特殊支持.这种空白元素是自闭合的,并且没有结束标记.

不幸的是,<link>是一个这样的元素.

这意味着上面的Razor标记不再有效,并且在运行时失败.删除结束</link>标记会删除解析器错误,但意味着它不再是有效的RSS.

那么,有没有办法解决这个问题,或者Razor是否真的适合生成HTML5?

Oak*_*nja 11

我这样做:

<item>
   <title>
      @post.BlogPost.Title
   </title>

   @Html.Raw("<link>")
      @Url.BlogPost(post.BlogPost, isAbsolute: true)
   @Html.Raw("</link>")
</item>
Run Code Online (Sandbox Code Playgroud)

生成的源代码如下所示:

<item>
    <title>
        Google
    </title>

     <link>
         http://www.google.se
    </link>
</item>
Run Code Online (Sandbox Code Playgroud)


Dre*_*kes 1

这个问题的简短回答似乎是,Razor 与版本 2 一样,与 HTML 绑定在一起,而排除了 XML。我向一位开发人员寻求了确认,希望他能回来。

我最终更改了方法以使用 Linq to XML 和自定义ActionResult,绕过 Razor 甚至任何视图引擎:

[HttpGet]
[OutputCache(Duration = 300)]
public ActionResult Feed()
{
    var result = new XmlActionResult(
        new XDocument(
            new XElement("rss",
                new XAttribute("version", "2.0"),
                new XElement("channel",
                    new XElement("title", "My Blog")
                    // snip
                )
            )
        )
    );

    result.MimeType = "application/rss+xml";

    return result;
}
Run Code Online (Sandbox Code Playgroud)

这需要以下定制ActionResult

public sealed class XmlActionResult : ActionResult
{
    private readonly XDocument _document;

    public Formatting Formatting { get; set; }
    public string MimeType { get; set; }

    public XmlActionResult([NotNull] XDocument document)
    {
        if (document == null)
            throw new ArgumentNullException("document");

        _document = document;

        // Default values
        MimeType = "text/xml";
        Formatting = Formatting.None;
    }

    public override void ExecuteResult(ControllerContext context)
    {
        context.HttpContext.Response.Clear();
        context.HttpContext.Response.ContentType = MimeType;

        using (var writer = new XmlTextWriter(context.HttpContext.Response.OutputStream, Encoding.UTF8) { Formatting = Formatting })
            _document.WriteTo(writer);
    }
}
Run Code Online (Sandbox Code Playgroud)