创建基于OData的Web API - Knowledge Builder API, Part III:Write Model

Posted alvachien

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了创建基于OData的Web API - Knowledge Builder API, Part III:Write Model相关的知识,希望对你有一定的参考价值。

在前两篇文章<Part I: Business Scenario> 和<Part II: Project Setup>后,可以开始真正Model的创建。

步骤如下:

1. 创建Models文件夹,并在该文件夹中加入一个数个Class。

Knowledge Category定义,代码如下:

using System;

namespace knowledgebuilderapi.Models {
    public enum KnowledgeCategory: Int16 {
        Concept     = 0,
        Formula     = 1,
    }
}

 

基类BaseModel,代码如下:

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace knowledgebuilderapi.Models {
    public abstract class BaseModel {

        [Column("CreatedAt")]
        public DateTime CreatedAt { get; set; }
        [Column("ModifiedAt")]
        public DateTime ModifiedAt { get; set; }
    }
}

 

Knowledge的Model,代码如下:

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace knowledgebuilderapi.Models
{
    [Table("Knowledge")]
    public class Knowledge : BaseModel
    {

        [Key]
        public Int32 ID { get; set; }
        [Required]
        [Column("ContentType")]
        public KnowledgeCategory Category { get;set; }
        [Required]
        [MaxLength(50)]
        [ConcurrencyCheck]
        [Column("Title", TypeName = "NVARCHAR(50)")]
        public string Title { get;set; }
        [Required]
        [Column("Content")]
        public string Content { get;set; }
        [Column("Tags")]
        public string Tags { get; set; }
    }
}

最后加入DataContext,代码如下:

using System;
using Microsoft.EntityFrameworkCore;

namespace knowledgebuilderapi.Models
{
    public class kbdataContext : DbContext
    {
        public kbdataContext(DbContextOptions<kbdataContext> options) : base(options)
        { }

        public DbSet<Knowledge> Knowledges { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Knowledge>()
                .Property(b => b.CreatedAt)
                .HasDefaultValueSql("getdate()");
            modelBuilder.Entity<Knowledge>()
                .Property(b => b.ModifiedAt)
                .HasDefaultValueSql("getdate()");
            modelBuilder.Entity<Knowledge>()
                .Property(e => e.Category)
                .HasConversion(
                    v => (Int16)v,
                    v => (KnowledgeCategory)v);
        }
    }
}

 

2. 如果Controller文件夹尚未创建,则创建一个,并在其中创建Knowledge的Controller

完整代码如下:

using System;
using Microsoft.AspNet.OData;
using Microsoft.EntityFrameworkCore;
using knowledgebuilderapi.Models;
using System.Linq;

namespace knowledgebuilderapi.Controllers {
    public class KnowledgeController : ODataController {
        private readonly kbdataContext _context;

        public KnowledgeController(kbdataContext context)
        {
            _context = context;
        }

        [EnableQuery]
        public IQueryable<Knowledge> Get()
        {
            return _context.Knowledges;
        }
    }
}

3. 修改Startup

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.EntityFrameworkCore;
using Microsoft.AspNet.OData.Extensions;
using Microsoft.AspNet.OData.Builder;
using Microsoft.AspNet.OData.Batch;
using knowledgebuilderapi.Models;
using Microsoft.AspNetCore.Routing;

namespace knowledgebuilderapi
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }
        public string ConnectionString { get; private set; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            this.ConnectionString = Configuration["KBAPI.ConnectionString"];

            services.AddDbContext<kbdataContext>(options =>
                options.UseSqlServer(this.ConnectionString));

            services.AddMvc(action => {
                action.EnableEndpointRouting = false;
            }).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
            services.AddOData();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseHttpsRedirection();

            ODataModelBuilder modelBuilder = new ODataConventionModelBuilder(app.ApplicationServices);
            modelBuilder.EntitySet<Knowledge>("Knowledges");
            modelBuilder.Namespace = typeof(Knowledge).Namespace;

            var model = modelBuilder.GetEdmModel();
            app.UseODataBatching();

            app.UseMvc(routeBuilder =>
                {
                    // and this line to enable OData query option, for example $filter
                    routeBuilder.Select().Expand().Filter().OrderBy().MaxTop(100).Count();

                    routeBuilder.MapODataServiceRoute("ODataRoute", "odata", model);
                });
        }
    }
}

4. 在项目的根目录下执行

cd knowledgebuilderapi
dotnet run

5. 这时,打开浏览器,访问 http://localhost:5000/odata/$metadata

会成功拿到一下文件:

<edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx" Version="4.0">
<edmx:DataServices>
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="knowledgebuilderapi.Models">
<EntityType Name="Knowledge">
<Key>
<PropertyRef Name="ID"/>
</Key>
<Property Name="ID" Type="Edm.Int32" Nullable="false"/>
<Property Name="Category" Type="knowledgebuilderapi.Models.KnowledgeCategory" Nullable="false"/>
<Property Name="Title" Type="Edm.String" Nullable="false" MaxLength="50"/>
<Property Name="Content" Type="Edm.String" Nullable="false"/>
<Property Name="Tags" Type="Edm.String"/>
<Property Name="CreatedAt" Type="Edm.DateTimeOffset" Nullable="false"/>
<Property Name="ModifiedAt" Type="Edm.DateTimeOffset" Nullable="false"/>
</EntityType>
<EnumType Name="KnowledgeCategory" UnderlyingType="Edm.Int16">
<Member Name="Concept" Value="0"/>
<Member Name="Formula" Value="1"/>
</EnumType>
<EntityContainer Name="Container">
<EntitySet Name="Knowledges" EntityType="knowledgebuilderapi.Models.Knowledge">
<Annotation Term="Org.OData.Core.V1.OptimisticConcurrency">
<Collection>
<PropertyPath>Title</PropertyPath>
</Collection>
</Annotation>
</EntitySet>
</EntityContainer>
</Schema>
</edmx:DataServices>
</edmx:Edmx>

 

 

 

 

 

以上是关于创建基于OData的Web API - Knowledge Builder API, Part III:Write Model的主要内容,如果未能解决你的问题,请参考以下文章

[转]Web Api系列教程第2季(OData篇)——使用Web Api创建只读的OData服务

在没有实体框架的情况下创建 Odata Web API 应用程序

Web API OData V4 在本地工作,但不在 IIS 上

Web API 中 OData POST 的媒体资源支持

使用 OData 的 ASP.Net Core Web API 实现对于单个实体 URI 失败

使用 $expand 时的 Web API OData 媒体类型格式化程序