ODATA WebService,获取$ metadata C# [英] ODATA WebService, get $metadata C#
问题描述
我有一个公开此$metadata
的WebService:
I have a WebService that expose this $metadata
:
<?xml version="1.0" encoding="UTF-8" standalone="true"?>
<edmx:Edmx xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx" Version="1.0"> > <edmx:DataServices m:DataServiceVersion="1.0"
xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
<Schema xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
xmlns="http://schemas.microsoft.com/ado/2007/05/edm"
xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"
Namespace="NAV">
<EntityType Name="PAsset">
<Key> <PropertyRef Name="No"/> </Key> <Property Name="No" Nullable="false" Type="Edm.String"/> <Property Name="Description"
Nullable="true" Type="Edm.String"/> <Property Name="Inactive"
Nullable="false" Type="Edm.Boolean"/> <Property Name="Insured"
Nullable="false" Type="Edm.Boolean"/> </EntityType>
<EntityType Name="PAssetsDepreciationBook">
<EntityType Name="PBankAPostGrp">
<EntityType Name="PCompany">
<EntityType Name="PCustomer">
是否可以通过C#应用程序获取此$metadata
中的信息?
Is possible get the information in this $metadata
in a C# aplication?
我有一个引用服务的应用程序正在运行,并且我正在使用一些代码:
I Have a Application with a reference to the Service working, and some code i'm using:
uriString = String.Format("PAssetsDepreciationBook?$ filter = FA_No eq '{0}',cliente);
uriString = String.Format("PAssetsDepreciationBook?$filter=FA_No eq '{0}'",cliente);
contex =新的ServiceReference1.NAV(新的Uri(serviceEndPoint)); contex.Credentials = CredentialCache.DefaultCredentials;
contex = new ServiceReference1.NAV(new Uri(serviceEndPoint)); contex.Credentials = CredentialCache.DefaultCredentials;
var客户= contex.Execute(新Uri(uriString,UriKind.Relative));
var customers = contex.Execute(new Uri(uriString, UriKind.Relative));
foreach(客户中的var c) { 结果=结果+ c.Acquisition_Cost; } 返回结果;
foreach (var c in customers) { result = result + c.Acquisition_Cost; } return result;
这工作正常,但获取$metadata
无效.
This works fine, but to get $metadata
doesn't.
推荐答案
已经有(大多数)代码可以做到这一点.它涉及到 ODataMessageReader.ReadMetadataDocument()调用:
There is already code (mostly) to do this. It involves the ODataMessageReader.ReadMetadataDocument() call:
var request = WebRequest.CreateHttp(baseUrl + "$metadata");
var metadataMessage =
new ClientHttpResponseMessage((HttpWebResponse)request.GetResponse());
using (var messageReader = new ODataMessageReader(metadataMessage))
{
IEdmModel edmModel = messageReader.ReadMetadataDocument();
// Do stuff with edmModel here
}
您需要ClientHttpResponseMessage类,但这很简单(来自 ODataLib101 ):
You need the ClientHttpResponseMessage class but that is simple (from ODataLib101):
public class ClientHttpResponseMessage : IODataResponseMessage
{
private readonly HttpWebResponse webResponse;
public ClientHttpResponseMessage(HttpWebResponse webResponse)
{
if (webResponse == null)
throw new ArgumentNullException("webResponse");
this.webResponse = webResponse;
}
public IEnumerable<KeyValuePair<string, string>> Headers
{
get
{
return this.webResponse.Headers.AllKeys.Select(
headerName => new KeyValuePair<string, string>(
headerName, this.webResponse.Headers.Get(headerName)));
}
}
public int StatusCode
{
get { return (int)this.webResponse.StatusCode; }
set
{
throw new InvalidOperationException(
"The HTTP response is read-only, status code can't be modified on it.");
}
}
public Stream GetStream()
{
return this.webResponse.GetResponseStream();
}
public string GetHeader(string headerName)
{
if (headerName == null)
throw new ArgumentNullException("headerName");
return this.webResponse.Headers.Get(headerName);
}
public void SetHeader(string headerName, string headerValue)
{
throw new InvalidOperationException(
"The HTTP response is read-only, headers can't be modified on it.");
}
}
使用IEdmModel,您可以访问元数据中的所有信息,以进行诸如构建类型为->控制器名称的字典之类的事情:
With the IEdmModel, you can access all the information in the metadata to do things like build a dictionary of type->controller name:
Dictionary<type, string> typeControllerMap =
edmModel.SchemaElements.OfType<IEdmEntityContainer>()
.Single()
.Elements.OfType<IEdmEntitySet>()
.Select(es => new { t = FindType(es.ElementType.FullName()), n = es.Name })
.Where(tn => tn.t != null)
.ToDictionary(tn => tn.t, tn => tn.n);
上面LINQ链中间的 FindType()调用只是在所有程序集中搜索给定类型名称的类型:
The FindType() call in the middle of the LINQ chain above simply searches all assemblies for a type given the type name:
private static Type FindType(string fullName)
{
return
AppDomain.CurrentDomain.GetAssemblies()
.Where(a => !a.IsDynamic)
.SelectMany(a => a.GetTypes())
.FirstOrDefault(t => t.FullName.Equals(fullName));
}
这篇关于ODATA WebService,获取$ metadata C#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!