【问题标题】:Return XML From Web Api从 Web Api 返回 XML
【发布时间】:2018-07-18 00:46:10
【问题描述】:

我已经阅读了数小时,并尝试了许多不同的解决方案,我在 SO 和其他地方找到了但仍然无法使其正常工作。

情况是,我编写了一个 web api rest 服务来通过 COM 向 3rd 方应用程序提供接口。它现在已经生产了几个月,并且工作完美无瑕。一个新的消费者要求我提供 XML 响应,直到现在它完全可以很好地使用 JSON。 无论我尝试什么,我都无法使用 Postman 进行测试得到 XML 响应。 在 Post man 中,我将内容类型和接受标头标记都设置为“application/xml”

所以我的控制器很简单

public class SampleController : ApiController
{
    [HttpGet]
    [Route("api/getobject")]
    public HttpResponseMessage GetByGSTNumber(string token, string key)
    {
        DataConnection connection = null; new DataConnection();//Set up COM reference
        DataObject dataObj = null;
        try
        {
            connection = new DataConnection();
            connection.login(token);
            dataObj = new DataObject(connection);
            Request.CreateResponse(HttpStatusCode.OK, dataObj);
        }
        catch (Exception ex)
        {
            return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex);
        }
        finally
        {
            if (connection != null) { Request.RegisterForDispose(connection); }
            if (dataObj != null) { Request.RegisterForDispose(dataObj); }
        }
    }
}

我的数据对象的定义,再次不要想的太复杂。它确实在后台进行了一些解析以将非 CLR 类型转换为 CLR 类型。

public class DataObject : IDisposable
{
    internal DataConnection dbConnection;
    internal dynamic _dataRecord;
    public string Key
    {
        get { return _dataRecord.KeyField.ToString(); }
    }

    public string Property1
    {
        get { return _dataRecord.Property1Feild.ToString(); }
    }

    public DataObject(DataConnection connection)
    {
        dbConnection = connection;
    }

    public void OpenRecord(string key)
    {
        if (!_dataRecord.Seek(key))
        {
            throw new Exception("Record not found");
        }

    }

    #region IDisposable Support
}

所以到目前为止我尝试的是改变

return Request.CreateResponse(HttpStatusCode.OK, dataObj);
//Returns JSON even if specifying XML in request

return Request.CreateResponse(HttpStatusCode.OK, dataObj "application/xml");
// returns <ExceptionMessage>Could not find a formatter matching the media type 'application/xml' that can write an instance of 'DataObject'.</ExceptionMessage>

我已经用 [DataContract] 修饰了我的数据对象,并用 [DataMember] 标签修饰了属性,但这并没有导致任何变化。

我创建了一个无参数构造函数,它让我得到了这个,但 xml 中没有属性/值

我尝试在我的 Global.asax 文件中设置 XML 序列化器,但这没有明显的效果。 我错过了什么?

更新 包括应用程序开始,我尝试了不同的 UseXMLSerializer = true/false 组合以及上述所有更改

    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
        GlobalConfiguration.Configure(WebApiConfig.Register);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);

        var xml = GlobalConfiguration.Configuration.Formatters.XmlFormatter;
        xml.UseXmlSerializer = true;
    }

我还尝试在我的数据对象上放置一个 XML 序列化方法并更改我的创建响应调用

public string XMLSerialize()
    {
        XmlSerializer xsSubmit = new XmlSerializer(typeof(DataObject));
        using (var sww = new StringWriter())
        {
            using (XmlWriter writer = XmlWriter.Create(sww))
            {
                xsSubmit.Serialize(writer, this);
                return sww.ToString(); // Your XML
            }
        }
    }

return Request.CreateResponse(HttpStatusCode.OK, creditor.XMLSerialize(), "application/xml");

这会导致 生成 XML 文档时出错。 System.InvalidOperationException 除了例外,我不能 100% 确定这会产生格式正确的结果

更新 已将我的业务类的属性更改为有一个空设置器,现在在我的响应中获取带有属性的 XML。 Visual Studio 抱怨空设置器但编译,我猜这不是常态。

    public string Key
    {
        get { return _dataRecord.KeyField.ToString(); }
        set {} VS give me a wiggly green line on this but no info
    } 

【问题讨论】:

  • "我已经尝试在我的 Global.asax 文件中设置 XML 序列化程序" -> 你的意思是你已经添加了格式化程序? (尽管它应该默认存在,除非有人明确删除它)
  • 对不起,应该更具体。 var xml = GlobalConfiguration.Configuration.Formatters.XmlFormatter; xml.UseXmlSerializer = true;
  • 能否给 API 方法打断点,并告诉我们在 API 方法被触发时Accept 标头是什么?
  • 另外,XmlSerializer 将忽略 KeyProperty1,因为它们没有设置器(但 DataContractSerializer 没有)。

标签: c# xml asp.net-web-api serialization


【解决方案1】:

对于所有帮助过的人。万分感谢。 感谢 Steve16351 给了我提示,让我朝着正确的方向前进。

所以问题出在我定义 DataObject 类的方式上。我需要做两处改变。

首先是一个无参数的构造函数。 其次,我需要指定属性设置器。最初并不认为我需要 setter,因为我永远不需要使用此类发布数据,因为它的基础数据源是只读的。

【讨论】:

    猜你喜欢
    • 2020-04-05
    • 1970-01-01
    • 1970-01-01
    • 2013-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-05
    • 1970-01-01
    相关资源
    最近更新 更多