【发布时间】: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将忽略Key和Property1,因为它们没有设置器(但DataContractSerializer没有)。
标签: c# xml asp.net-web-api serialization