【问题标题】:WebAPI to Return XML返回 XML 的 WebAPI
【发布时间】:2012-07-24 14:39:11
【问题描述】:

我希望我的 WEB API 方法将 XML 对象返回给调用应用程序。目前它只是将 XML 作为字符串对象返回。这是不可以吗?如果是这样,你如何告诉 webapi get 方法它正在返回一个 XML 类型的对象?

谢谢

编辑:Get 方法的一个例子:

[AcceptVerbs("GET")]
public HttpResponseMessage Get(int tenantID, string dataType, string ActionName)
{
   List<string> SQLResult = MyWebSite_DataProvidor.DB.spReturnXMLData
            ("SELECT * FROM vwContactListing FOR XML AUTO, ELEMENTS").ToList();
   string AllResults = "";
   for (int i = 0; i < SQLResult.Count - 1; i++)
   {
       AllResults += SQLResult[i];
   }
    string sSyncData = "<?xml version=\"1.0\"?> " + AllResults;
    HttpResponseMessage response = new HttpResponseMessage();
    response.Content = new StringContent(sSyncData);
    return response;          
}

它有点 hacky,因为我仍处于原型设计阶段。当我能证明它是可行的时候会重构。

【问题讨论】:

    标签: asp.net asp.net-mvc asp.net-web-api


    【解决方案1】:

    您应该简单地返回您的对象,而不必关心它是 XML 还是 JSON。从 web api 请求 JSON 或 XML 是客户端的责任。例如,如果您使用 Internet Explorer 进行调用,则请求的默认格式为 Json,而 Web API 将返回 Json。但是如果你通过谷歌浏览器发出请求,默认的请求格式是 XML,你会得到 XML。

    如果您使用Fiddler 发出请求,则可以将 Accept 标头指定为 Json 或 XML。

    Accept: application/xml
    

    你可能想看这篇文章:Content Negotiation in ASP.NET MVC4 Web API Beta – Part 1

    编辑:根据您使用代码编辑的问题:

    字符串的简单返回列表,而不是将其转换为 XML。尝试使用 Fiddler。

    public List<string> Get(int tenantID, string dataType, string ActionName)
        {
           List<string> SQLResult = MyWebSite_DataProvidor.DB.spReturnXMLData("SELECT * FROM vwContactListing FOR XML AUTO, ELEMENTS").ToList();
           return SQLResult;
         }
    

    例如,如果您的列表是这样的:

    List<string> list = new List<string>();
    list.Add("Test1");
    list.Add("Test2");
    list.Add("Test3");
    return list;
    

    如果你指定Accept: application/xml,输出将是:

    <ArrayOfstring xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
      <string>Test1</string>
      <string>Test2</string>
      <string>Test3</string>
    </ArrayOfstring>
    

    如果您在请求中指定“接受:应用程序/json”,那么输出将是:

    [
      "Test1",
      "Test2",
      "Test3"
    ]
    

    所以让客户端请求内容类型,而不是您发送自定义的 xml。

    【讨论】:

    • 所以目前我在 API get 方法中自定义构建 XML 几乎是一个连接字符串,而不是返回该字符串。那么除此之外什么都不需要做?
    • @Raven,您能否在您的问题中发布您的方法签名或相关 C# 代码的一部分?
    • 刚刚在帖子中添加了示例
    • 从存储过程返回的列表不是我想要返回的。当从 SQL Server 生成的返回 XML 大于这么多字符时,存储过程会返回一个列表。 list 只是从 SQL Server 返回的整个 XML 字符串的一部分。所以将 this 作为对象返回将是一个问题。
    • 我不确定您要返回什么,关键是Web api不应该关心返回的是XML还是JSON,应该是客户端的责任
    【解决方案2】:

    如果您返回一个可序列化的对象,WebAPI 将根据您的客户端发送的 Accept 标头自动发送 JSON 或 XML。

    如果你返回一个字符串,你会得到一个字符串。

    【讨论】:

    • 大家好,该方法返回的数据是动态的。情况 A. 正在返回一个实体列表。情况 B. 可能是 2 个或更多实体/类的组合列表。我希望它是动态的,但欺骗 webapi 以返回 xml(如果也可以返回 JSON 格式,那就太酷了,但 XML 是主要的必需品)
    • 然后创建一个可以包含你想要的数据的对象并返回。
    • 确保你在对象上指定了 [Serializable()],我最初错过了这个。
    【解决方案3】:

    如果您不希望控制器决定返回对象类型,则应将方法返回类型设置为System.Net.Http.HttpResponseMessage,并使用以下代码返回 XML。

    public HttpResponseMessage Authenticate()
    {
      //process the request 
      .........
    
      string XML="<note><body>Message content</body></note>";
      return new HttpResponseMessage() 
      { 
        Content = new StringContent(XML, Encoding.UTF8, "application/xml") 
      };
    }
    

    这是始终从 Web API 返回 XML 的最快方式。

    【讨论】:

    • 人们经常回答是聪明的。我希望答案简单直接地解决手头的问题。我有带 XML 的字符串。我想返回 XML。答对了!感谢您的回答。
    • 旁注:不要像我一样想知道为什么当您尝试使用新的 StringContent 对象返回 Request.CreateResponse() 时它不起作用。确保您返回的是 new HttpResponseMessage()
    • 这对我不起作用。我在浏览器中得到这个 - 知道为什么吗?:StatusCode:200,ReasonPhrase:'OK',版本:1.1,内容:System.Net.Http.StringContent,标题:{ Content-Type:application / xml;字符集=utf-8 }
    • 哇,在不同的代码上花了两个多星期之后,我发现了这个。上帝救了我的命。
    【解决方案4】:

    这是与 IHttpActionResult 返回类型兼容的另一种方式。在这种情况下,我要求它使用 XML 序列化程序(可选)而不是数据协定序列化程序,我使用 return ResponseMessage( 以便获得与 IHttpActionResult 兼容的返回:

    return ResponseMessage(new HttpResponseMessage(HttpStatusCode.OK)
           {
               Content = new ObjectContent<SomeType>(objectToSerialize, 
                  new System.Net.Http.Formatting.XmlMediaTypeFormatter { 
                      UseXmlSerializer = true 
                  })
           });
    

    【讨论】:

    • 这正是我正在寻找的方式。谢谢AaronLS
    • 很好的答案,谢谢。确保 SomeType 有一个默认构造函数,否则你会得到一个无用的错误 "... 配置的格式化程序 'System.Web.Http.Tracing.Tracers.XmlMediaTypeFormatterTracer' 无法写入类型的对象..."我>
    • 你可以写Content(System.Net.HttpStatusCode.OK, model, Configuration.Formatters.XmlFormatter)
    【解决方案5】:

    在我的 netcore 2.2 项目中,我使用以下代码:

    [HttpGet]
    [Route( "something" )]
    public IActionResult GetSomething()
    {
        string payload = "Something";
    
        OkObjectResult result = Ok( payload );
    
        // currently result.Formatters is empty but we'd like to ensure it will be so in the future
        result.Formatters.Clear();
    
        // force response as xml
        result.Formatters.Add( new Microsoft.AspNetCore.Mvc.Formatters.XmlSerializerOutputFormatter() );
    
        return result;
    }
    

    它只强制控制器中的一个操作返回一个 xml,而不影响其他操作。此外,此代码不包含 HttpResponseMessage 或 StringContent 或 ObjectContent ,它们是一次性对象,因此应适当处理(如果您使用任何提醒您的代码分析器,这尤其是一个问题)。

    更进一步,您可以使用如下方便的扩展:

    public static class ObjectResultExtensions
    {
        public static T ForceResultAsXml<T>( this T result )
            where T : ObjectResult
        {
            result.Formatters.Clear();
            result.Formatters.Add( new Microsoft.AspNetCore.Mvc.Formatters.XmlSerializerOutputFormatter() );
    
            return result;
        }
    }
    

    你的代码会变成这样:

    [HttpGet]
    [Route( "something" )]
    public IActionResult GetSomething()
    {
        string payload = "Something";
    
        return Ok( payload ).ForceResultAsXml();
    }
    

    此外,此解决方案看起来像是一种强制返回为 xml 的明确而干净的方法,并且很容易添加到您现有的代码中。

    附:我使用完全限定名称 Microsoft.AspNetCore.Mvc.Formatters.XmlSerializerOutputFormatter 只是为了避免歧义。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-06
      • 1970-01-01
      • 1970-01-01
      • 2017-08-08
      • 1970-01-01
      相关资源
      最近更新 更多