挂钩 OData 的 $metadata 响应并将其从 XML 转换为 JSON
Posted
技术标签:
【中文标题】挂钩 OData 的 $metadata 响应并将其从 XML 转换为 JSON【英文标题】:Hook OData's $metadata response and convert it from XML to JSON 【发布时间】:2017-05-02 09:33:03 【问题描述】:Get OData $metadata in JSON format 的回答指出 OData 默认无法将元数据返回为 JSON。
但是是否有可能捕获或挂钩它对$metadata
URL 的响应,然后在将其发送到客户端之前将其动态转换为 JSON?
我想像这样的伪代码:
[HttpGet]
[ODataRoute("$metadata")]
public string GetMetadataAsJson()
string xml = GetOdataMetadataAsXML();
string json = ConvertToJson(xml);
return json;
不过,我不知道如何正确实现它,尤其是我不确定如何将标准 OData 响应作为字符串获取,以及如何挂钩 $metadata
URL。
【问题讨论】:
一种选择是编写一个 HttpModule。挂钩预期的 URL,从 app/json 到 app/xml 的传入更改请求类型,用 XDoc.Load->JSon.ConvertObject->Output 流替换响应流。 @MarvinSmit 我什至无法连接$metadata
端点,[ODataRoute("$metadata")]
对此不起作用。问题是 $metadata
更像是一个可以应用于许多不同 URL 的参数,我必须将它们全部挂钩。
更复杂的选择是: 为负责 $metadata 生成的 ODataMediaTypeFormatter 编写一个装饰器。然后使用一些反射来让 OData 路由允许 app/json 进行 $metadata 请求(默认情况下它会导致路由失败)。然后在装饰器上重载“WriteToStreamAsyncProxy”以执行与上述相同的技巧(写入 XML,将 XML 转换为 JSON,输出 JSON)。最后用修饰版本替换 OData 启动中的格式化程序。
我不明白这种东西有什么用? CSDL xml 和 json 之间没有可能的等价性(例如,那个 json 会是什么样的?你会如何处理 XML 命名空间?)。无论如何,没有标准客户端能够理解它,所以,为什么不创建另一个特定的路由,例如 /$jsonmetadata 或其他什么,并在自定义客户端中使用该路由?
这仍然困扰着我 ;) 你不应该尝试拦截标准的conventional $metadata 路由,这会破坏 OData 客户端工具,但是没有什么能阻止您创建自己的未绑定操作来实现保存。
【参考方案1】:
Newtonsoft 支持 Json 部分结账https://www.newtonsoft.com/json/help/html/ConvertXmlToJson.htm
所以 Json 部分的实际解决方案将非常简单,只要你有你的 XML
[HttpGet]
[ODataRoute("$metadata")]
public string GetMetadataAsJson()
string xml = GetOdataMetadataAsXML();
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
string json = JsonConvert.SerializeXmlNode(doc);
return json;
此外,您可能应该首先检查是否例如例如,使用此代码设置格式查询
[HttpGet]
[ODataRoute("$metadata")]
public string GetMetadataAsJson([FromQuery(Name="Format")]string format)
string metaResult = GetOdataMetadataAsXML();
if(format.Equals("json",StringComparison.OrdinalIgnoreCase))
XmlDocument metaDoc = new XmlDocument();
doc.LoadXml(metaResult);
metaResult = JsonConvert.SerializeXmlNode(doc);
return metaResult;
【讨论】:
以上是关于挂钩 OData 的 $metadata 响应并将其从 XML 转换为 JSON的主要内容,如果未能解决你的问题,请参考以下文章
我们可以使用OData客户端为syncfusion网格创建我们的请求但是使用正常响应(Reqular WebAPI)
.Net Core 1.1 上的 OData v4 缺少 /$metadata
ASP.NET.Core允许在设置RequireAuthenticatedUser()时匿名访问OData $ metadata