ODATA WebService, get $metadata C#

雨燕双飞 提交于 2019-12-06 06:38:22

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
}

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.");
    }
}

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);

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));
}
Vitek Karas MSFT

You can request the metadata as a plain XML using HttpWebRequest for example. If you need to parse it, you can use EdmLib (Microsoft.Data.Edm.dll) which can be found on NuGet or even better ODataLib (Microsoft.Data.OData.dll) also on Nuget which has ODataMessageReader.ReadMetadataDocument specifically designed to read these (it still returns the EDM object model for it, it just deals with the EDMX wrapper and versioning for you).

user1498646

Thanks, it work just fine.

Just like this:

// Create a request for the URL. 
WebRequest request = WebRequest.Create("http://localhost:7048/DynamicsNAV70/OData/$metadata");

//set the credentials.
request.Credentials = CredentialCache.DefaultCredentials;

// Get the response.
WebResponse response = request.GetResponse();

// Get the stream containing content returned by the server.
Stream dataStream = response.GetResponseStream();

// Open the stream using a StreamReader for easy access.
StreamReader reader = new StreamReader(dataStream);

// Read the content.
string responseFromServer = reader.ReadToEnd();

XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(new StringReader(responseFromServer));

// Clean up the streams and the response.
reader.Close();
response.Close();

After this, just parse the data like a xml file.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!