JSON WebAPI 2 ODATA 3 C# 项目中 URI 类型的序列化
JSON Serialization of URI Type in WebAPI 2 ODATA 3 C# Project
我在我的 WebAPI 2 项目的 ODATA 3 控制器中看到 C# URI 类型序列化为 JSON 作为不包含域的段数组。我已经尝试了所有我能想到的来改变它(包括摆弄序列化设置,甚至尝试使用合同序列化程序而不是 JSON.Net)。似乎没有什么能改变这种行为。请注意,我没有使用 .Net Core。这是一个代码示例,浓缩为一个片段。
namespace WebApplication1.Controllers
{
public class MyObject
{
public Uri Url { get; set; }
public string Name { get; set; }
public string ID { get; set; }
}
public class MyObjectsController : ODataController
{
private static ODataValidationSettings _validationSettings = new ODataValidationSettings();
public IHttpActionResult GetMyObjects(ODataQueryOptions<MyObject> queryOptions)
{
try
{
queryOptions.Validate(_validationSettings);
return Ok<IEnumerable<MyObject>>(new List<MyObject>() { new MyObject() { ID="asdf", Name="123rwe", Url = new Uri("http://www.webapp.com/sites/page.html") } });
}
catch (ODataException ex)
{
return BadRequest(ex.Message);
}
}
}
}
这会在浏览器中生成以下 JSON:
{
"odata.metadata":"http://localhost:51607/odata/$metadata#MyObjects","value":[
{
"Url":{
"Segments":[
"/","sites/","page.html"
]
},"Name":"123rwe","ID":"asdf"
}
]
}
这就是我想要的(不将 Url 属性 更改为字符串):
{
"odata.metadata":"http://localhost:51607/odata/$metadata#MyObjects","value":[
{
"Url":"http://www.webapp.com/sites/page.html","Name":"123rwe","ID":"asdf"
}
]
}
有什么想法吗?
更新:
进一步的研究表明,WebAPI ODATA 中 URI 类型的序列化行为由 odataentityreferencelink 和 odataentityreferencelinkserializer 类 控制。具体来说,URI 类型似乎被转换为 odataentityreferencelink 类型,然后以我上面发布的方式序列化(作为不包括根域的段数组)。我仍然需要知道如何更改此行为,但是这两个 类 的文档并没有帮助。最后,我已经确认此问题并非特定于 JSON 输出格式。 XML/Atom 和 JSON 的序列化行为是相同的:URI 被分解成一个段数组。
MS Premier 支持提供了最终答案,我将在下面分享。
- 没有直接 JSON 序列化 URI 类型的选项,通常它会像您在代码中观察到的那样被分解成段数组
- 正常情况下域名会被淘汰
- 您可以选择的选项是创建一个自定义 URI 转换器,该转换器派生自 JSONConverter,它是 Newtonsoft.Json 命名空间
的一部分
我在我的 WebAPI 2 项目的 ODATA 3 控制器中看到 C# URI 类型序列化为 JSON 作为不包含域的段数组。我已经尝试了所有我能想到的来改变它(包括摆弄序列化设置,甚至尝试使用合同序列化程序而不是 JSON.Net)。似乎没有什么能改变这种行为。请注意,我没有使用 .Net Core。这是一个代码示例,浓缩为一个片段。
namespace WebApplication1.Controllers
{
public class MyObject
{
public Uri Url { get; set; }
public string Name { get; set; }
public string ID { get; set; }
}
public class MyObjectsController : ODataController
{
private static ODataValidationSettings _validationSettings = new ODataValidationSettings();
public IHttpActionResult GetMyObjects(ODataQueryOptions<MyObject> queryOptions)
{
try
{
queryOptions.Validate(_validationSettings);
return Ok<IEnumerable<MyObject>>(new List<MyObject>() { new MyObject() { ID="asdf", Name="123rwe", Url = new Uri("http://www.webapp.com/sites/page.html") } });
}
catch (ODataException ex)
{
return BadRequest(ex.Message);
}
}
}
}
这会在浏览器中生成以下 JSON:
{
"odata.metadata":"http://localhost:51607/odata/$metadata#MyObjects","value":[
{
"Url":{
"Segments":[
"/","sites/","page.html"
]
},"Name":"123rwe","ID":"asdf"
}
]
}
这就是我想要的(不将 Url 属性 更改为字符串):
{
"odata.metadata":"http://localhost:51607/odata/$metadata#MyObjects","value":[
{
"Url":"http://www.webapp.com/sites/page.html","Name":"123rwe","ID":"asdf"
}
]
}
有什么想法吗?
更新: 进一步的研究表明,WebAPI ODATA 中 URI 类型的序列化行为由 odataentityreferencelink 和 odataentityreferencelinkserializer 类 控制。具体来说,URI 类型似乎被转换为 odataentityreferencelink 类型,然后以我上面发布的方式序列化(作为不包括根域的段数组)。我仍然需要知道如何更改此行为,但是这两个 类 的文档并没有帮助。最后,我已经确认此问题并非特定于 JSON 输出格式。 XML/Atom 和 JSON 的序列化行为是相同的:URI 被分解成一个段数组。
MS Premier 支持提供了最终答案,我将在下面分享。
- 没有直接 JSON 序列化 URI 类型的选项,通常它会像您在代码中观察到的那样被分解成段数组
- 正常情况下域名会被淘汰
- 您可以选择的选项是创建一个自定义 URI 转换器,该转换器派生自 JSONConverter,它是 Newtonsoft.Json 命名空间 的一部分