locked
OData Having difficulty building a simple OData service. RRS feed

  • Question

  • User1645911105 posted

    Trying to build an OData service based on the Entity Relations in OData v4 Using ASP.NET Web API 2.2

    I did get this tutorial running.

    Now want to build with one of my tables.

    Model:

    namespace QBOData.Models
    {
        using System.ComponentModel.DataAnnotations;
        using System.ComponentModel.DataAnnotations.Schema;
        using System.Data.Entity.Spatial;
    
        [Table("People")]
        public partial class Person
        {
            //public Person()
            //{
            //    PIndexes = new HashSet<PIndex>();
            //}
            [Key]
            public int Id { get; set; }
    
            [Required]
            public string LName { get; set; }
    
            public string FName { get; set; }
    
            public string MName { get; set; }
    
            public string Suffix { get; set; }
    
            public string Biography { get; set; }
    
            //public virtual ICollection<PIndex> PIndexes { get; set; }
    
        }
    }
    



    Model Context:

        class QBOContext : DbContext
        {
            public QBOContext() : base("name=QBO")
            {
            }
    
            public DbSet<Person> People { get; set;  }
        }

    Seeded the Db with

     

            protected override void Seed(QBOData.Models.QBOContext context)
            {
                //  This method will be called after migrating to the latest version.
    
                context.People.AddOrUpdate(
                    p => p.Id,
                    new Person { Id = 1, LName = "Turabian", FName = "Kate", MName = "L.", Suffix = "", Biography = "" },
                    new Person { Id = 2, LName = "Gonzalez", FName = "Justo", MName = "L", Suffix = "", Biography = "" },
                    new Person { Id = 3, LName = "Augustine", FName = "", MName = "", Suffix = "", Biography = "" },
                    new Person { Id = 4, LName = "Delete Me", FName = "", MName = "", Suffix = "", Biography = "" },
                    new Person { Id = 5, LName = "Delete Me", FName = "", MName = "", Suffix = "", Biography = "" },
                    new Person { Id = 6, LName = "Edwards", FName = "Jonathan", MName = "", Suffix = "", Biography = "" },
                    new Person { Id = 7, LName = "Noll", FName = "Mark", MName = "A.", Suffix = "", Biography = "" }
                    );
    
            }
    



    The Database is updated and correct.

    ---

    When attempting to run

    namespace QBOData
    {
        public static class WebApiConfig
        {
            public static void Register(HttpConfiguration config)
            {
                // Web API configuration and services
    
                // Web API routes
                config.MapHttpAttributeRoutes();
    
                config.Routes.MapHttpRoute(
                    name: "DefaultApi",
                    routeTemplate: "api/{controller}/{id}",
                    defaults: new { id = RouteParameter.Optional }
                );
    
                // OData Routing
                ODataModelBuilder builder = new ODataModelBuilder();
                builder.EntitySet<Person>("People");
                config.MapODataServiceRoute(
                    routeName: "ODataRoute",
                    routePrefix: "odata",
                    model: builder.GetEdmModel()); <<== Exception "The entity 'Person' does not have a key defined."
                
            }
        }
    }

    Please note the exception in the above code section.

    I have tried to add the key as 

    builder.EntitySet<Person>("People").EntityType.HasKey(p => p.Id);

    This did not work either.

    Need A tutorial that I can use for a base.

    Thanks for the help

    Wednesday, June 1, 2016 4:05 PM

Answers

  • User36583972 posted

    Hi jl.rey,

    I have made a sample on my side. I found the error code. You should change your code like the below

     public static class WebApiConfig
        {
            public static void Register(HttpConfiguration config)
            {
                
                // Web API configuration and services
    
                // Web API routes
                config.MapHttpAttributeRoutes();
    
                config.Routes.MapHttpRoute(
                    name: "DefaultApi",
                    routeTemplate: "api/{controller}/{id}",
                    defaults: new { id = RouteParameter.Optional }
                );
    
               // ODataModelBuilder builder = new ODataModelBuilder();
                ODataModelBuilder builder = new ODataConventionModelBuilder();
                builder.EntitySet<Person>("People");
                config.MapODataServiceRoute(
                    routeName: "ODataRoute",
                    routePrefix: "odata",
                    model: builder.GetEdmModel());
    
            }
        }

    Best Regards,

    Yohann Lu

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, June 7, 2016 10:00 AM

All replies

  • User36583972 posted

    Hi jl.rey,

    From your description, you can try the following suggestions.

    1: May be the problem is that Person has no keys defined in the DB model rather than the OData EDM model. Try the following code.

     class QBOContext : DbContext
        {
            public QBOContext() : base("name=QBO")
            {
            }
            public DbSet<Person> People { get; set;  }
            protected override void OnModelCreating(DbModelBuilder mb)
            {
               mb.Entity<Person>().HasKey(p => p.Id);
            }
        }

    2: Take full control of the model by using the ODataModelBuilder class, here you explicitly add EntityTypes, Properties, Keys.

                var products = builder.EntitySet<Category>("Category");
                var product = products.EntityType;
                product.HasKey(p => p.Id);
                product.Property(p => p.Name);

    You can refer the following tutorials.

    1: Web API OData V4 Lessons Learned:

    https://blogs.msdn.microsoft.com/davidhardin/2014/12/17/web-api-odata-v4-lessons-learned/

    2: OData support in ASP.NET Web API:

    https://blogs.msdn.microsoft.com/alexj/2012/08/15/odata-support-in-asp-net-web-api/

    Best Regards,

    Yohann Lu

    Thursday, June 2, 2016 3:22 AM
  • User1645911105 posted

    Thanks for the Reply.

    This does not explain why the model could be built in the example and not in my code.

    1: May be the problem is that Person has no keys defined in the DB model rather than the OData EDM model. Try the following code.

    The database contains a key field, as expected.

    2: Take full control of the model by using the ODataModelBuilder class, here you explicitly add EntityTypes, Properties, Keys.

    I have considered using this to control the Model need more information on this.

    Still not answered "WHY IT WORKS ON THE TUTORIAL AND NOT WHEN I POINT TO MY DATA?"

    I must be missing something in the application!

    Thanks again.

    jl

    Saturday, June 4, 2016 4:21 PM
  • User36583972 posted

    Hi jl.rey,

    I have made a sample on my side. I found the error code. You should change your code like the below

     public static class WebApiConfig
        {
            public static void Register(HttpConfiguration config)
            {
                
                // Web API configuration and services
    
                // Web API routes
                config.MapHttpAttributeRoutes();
    
                config.Routes.MapHttpRoute(
                    name: "DefaultApi",
                    routeTemplate: "api/{controller}/{id}",
                    defaults: new { id = RouteParameter.Optional }
                );
    
               // ODataModelBuilder builder = new ODataModelBuilder();
                ODataModelBuilder builder = new ODataConventionModelBuilder();
                builder.EntitySet<Person>("People");
                config.MapODataServiceRoute(
                    routeName: "ODataRoute",
                    routePrefix: "odata",
                    model: builder.GetEdmModel());
    
            }
        }

    Best Regards,

    Yohann Lu

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, June 7, 2016 10:00 AM