Search code examples
wcfodata

Odata Parsing $metadata


I'm Hosting an OData Service which exposes certain tables and properties from my DB.

I can Request the Metadata for the DB using the [hosturl]?$metadata property. which return the table names and columns in XML format.

I was wondering if there is a built in OData class to parse this, so that I can grab out the Tables, and Columns or do I have to do It manually?


Solution

  • So I figured out a way to do it, you will also need the class from @Vagif's post which you can find here:

    http://odata.jenspinney.com/2013/02/creating-an-iedmmodel-from-a-metadata-document/

    This is a simple funciton to grab out the properties, It could be optimized to cache the tables names etc but this is more for testing purposes.

        private static IEdmModel GetODataEdmModel()
        {
            IEdmModel edmModel = null;
            string FullUrl = "http://localhost:4684/BDBWcfService.svc/$metadata/";
    
    
            var request = WebRequest.CreateHttp(FullUrl);
            var metadataMessage =
                new ClientHttpResponseMessage((HttpWebResponse)request.GetResponse());
            using (var messageReader = new ODataMessageReader(metadataMessage))
            {
                edmModel = messageReader.ReadMetadataDocument();
            }
            return edmModel;
        }
    
        public ActionResult ODataGetProperties(string TableName)
        {
            DataModel = (DataModel == null) ? GetODataEdmModel() : DataModel;
    
            //gets a mapping of the tables names
            var TableNames = DataModel.SchemaElements.OfType<IEdmEntityContainer>().Single().Elements.OfType<IEdmEntitySet>().ToDictionary(k => k.Name, v => v.ElementType.Name);
    
            string TypeName = string.Empty;
            if (TableNames.TryGetValue(TableName, out TypeName))
            {
                //uses the type name to look up the properties
                var data = DataModel.SchemaElements.OfType<IEdmEntityType>().Where(k => k.Name == TypeName).Select(v => new
                {
                    NavigationProperties = v.NavigationProperties().Select(p => p.Name).ToList(),
                    Properties = v.Properties().Select(p => p.Name).ToList(),
                }).FirstOrDefault();
    
                var JSSerializer = new JavaScriptSerializer();
                var json = JSSerializer.Serialize(data);
                return Json(data, JsonRequestBehavior.AllowGet);
    
            }
            return new HttpStatusCodeResult(HttpStatusCode.NotFound, "The Requested Table was not found please refine your query");
        }