作为ActionResult从控制器的操作中返回XML?

Ken*_*all 136 .net xml asp.net asp.net-mvc

从ASP.NET MVC中的控制器操作返回XML的最佳方法是什么?返回JSON有一种很好的方法,但不适用于XML.我是否真的需要通过View路由XML,还是应该采用Response.Write-it的非最佳实践方式?

Pet*_*etr 128

return this.Content(xmlString, "text/xml");
Run Code Online (Sandbox Code Playgroud)

  • @Quandary,好的我会重申一点:当你可以通过使用流来避免分配/收集/内存异常时,创建字符串是浪费的,_unless_你正在研究出现错误的11年历史的计算系统. (5认同)
  • 哇,这确实对我有帮助,但我才刚刚开始修补 MVC 的东西。 (2认同)
  • @Drew Noakes:不,不是.如果直接写入HttpContext.Response.Output流,您将在基于WinXP的服务器上获得YSOD.它似乎在Vista +上修复,如果你在Windows 7上开发并部署到Windows XP(Server 2003?),这尤其成问题.如果这样做,您需要先写入内存流,然后将内存流复制到输出流... (2认同)

Luk*_*ith 113

使用MVCContrib的XmlResult Action.

这里参考的是他们的代码:

public class XmlResult : ActionResult
{
    private object objectToSerialize;

    /// <summary>
    /// Initializes a new instance of the <see cref="XmlResult"/> class.
    /// </summary>
    /// <param name="objectToSerialize">The object to serialize to XML.</param>
    public XmlResult(object objectToSerialize)
    {
        this.objectToSerialize = objectToSerialize;
    }

    /// <summary>
    /// Gets the object to be serialized to XML.
    /// </summary>
    public object ObjectToSerialize
    {
        get { return this.objectToSerialize; }
    }

    /// <summary>
    /// Serialises the object that was passed into the constructor to XML and writes the corresponding XML to the result stream.
    /// </summary>
    /// <param name="context">The controller context for the current request.</param>
    public override void ExecuteResult(ControllerContext context)
    {
        if (this.objectToSerialize != null)
        {
            context.HttpContext.Response.Clear();
            var xs = new System.Xml.Serialization.XmlSerializer(this.objectToSerialize.GetType());
            context.HttpContext.Response.ContentType = "text/xml";
            xs.Serialize(context.HttpContext.Response.Output, this.objectToSerialize);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这里的课程直接来自MVC Contrib项目.不确定这是否符合滚动自己的条件. (12认同)
  • @pcampbel,我更喜欢在我的项目根目录中为每种类创建单独的文件夹:结果,过滤器,路由等. (7认同)
  • 如果你遵循ASP.NET MVC约定,你会把这个类放在哪里?控制器文件夹?也许你放置ViewModels的地方一样? (3认同)

Dre*_*kes 31

如果您使用优秀的Linq-to-XML框架构建XML,那么这种方法将会很有帮助.

XDocument在动作方法中创建了一个.

public ActionResult MyXmlAction()
{
    // Create your own XDocument according to your requirements
    var xml = new XDocument(
        new XElement("root",
            new XAttribute("version", "2.0"),
            new XElement("child", "Hello World!")));

    return new XmlActionResult(xml);
}
Run Code Online (Sandbox Code Playgroud)

这个可重用的自定义ActionResult为您序列化XML.

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

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

    public XmlActionResult(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)

您可以指定MIME类型(例如application/rss+xml)以及是否需要缩进输出.这两个属性都有合理的默认值.

如果您需要UTF8以外的编码,那么为此添加属性也很简单.


小智 24

如果您只想通过请求返回xml,并且您拥有xml"chunk",那么您可以这样做(作为控制器中的操作):

public string Xml()
{
    Response.ContentType = "text/xml";
    return yourXmlChunk;
}
Run Code Online (Sandbox Code Playgroud)


Mah*_*deh 17

MVC Contrib中有一个XmlResult(以及更多).请访问http://www.codeplex.com/MVCContrib


小智 5

我最近不得不为一个 Sitecore 项目执行此操作,该项目使用一种方法从 Sitecore 项目及其子项创建 XmlDocument,并将其从控制器 ActionResult 作为文件返回。我的解决方案:

public virtual ActionResult ReturnXml()
{
    return File(Encoding.UTF8.GetBytes(GenerateXmlFeed().OuterXml), "text/xml");
}
Run Code Online (Sandbox Code Playgroud)