VS2015 使用ODataV4创建Web Api和OData客户端

来源:互联网 发布:nginx 域名无法访问 编辑:程序博客网 时间:2024/06/15 01:41

OData - Open Data Protocol,是一个设计和使用RESTful API的标准。REST本身只是一个构建web服务的思想和理念,其没有规定一个统一的标准来限制开发人员该如何设计RESTful API。其实我们实际开发中的确也没有遵循某个统一的标准去设计WebAPI。因为大多数场景下,遵循一个统一的标准并不是必要的。但在某些场景下,有这样一个标准却能带来很大的好处。

OData的理想是, 无论哪个组织构建的RESTful API,只要其符合OData标准。其他组织就可以按照OData标准中定义的方式去使用这个API获取/修改资源。这个可以类比SQL标准之于RDBMS关系。无论什么关系型数据库,如果其声称支持SQL标准,任何人就可以使用标准SQL查询语句来查询数据。

标准化的另一个好处:可以将Odata协议实现到一个通用的类库中,通过这个类库去创建和访问RESTful API可以减少开发人员的工作量。

一、新建一个空的WebApi项目


、添加包Microsoft.AspNet.OData包

1、工具菜单--NuGet包管理器--程序包管理器控制台:

2、输入Install-Package Microsoft.AspNet.OData 命令


三、添加EntityFramework(如何已经有数据则可以使用自己的数据源,直接跳过)

1、输入Install-Package EntityFramework 命令

2、创建一个实体对象

设置数据库连接

public class Product    {        [Key]        public int ID { get; set; }        public String Name { get; set; }        // [IgnoreDataMember] 属性表示在EDM中不可见        [IgnoreDataMember]        public string Category { get; set; }    }

三、配置OData终结点

1、打开WebApiConfig配置EDM

 private static IEdmModel GenerateEdmModel()        {            var builder = new ODataConventionModelBuilder            {                Namespace = "OdataModel",                ContainerName = "DefaultContainer",            };            builder.EntitySet<Product>("Products");                        return builder.GetEdmModel();        }

2、添加路由并设置查询参数

public static void Register(HttpConfiguration config)        {            // Web API 配置和服务            config.MapODataServiceRoute("ProductOData", null, GenerateEdmModel());            //设置查询参数方式一            //config.Select().OrderBy().Filter().Expand().MaxTop(100).Count();            //设置查询参数方式二            DefaultQuerySettings query = new DefaultQuerySettings()            {                EnableCount = true,                EnableExpand = true,                EnableFilter = true,                EnableOrderBy = true,                EnableSelect = true,                MaxTop = 100            };            config.SetDefaultQuerySettings(query);        }

四、添加OData控制器



public class ODataAPIContext : DbContext    {        public ODataAPIContext() : base("ODataDB")        { }        public DbSet<Product> Products { get; set; }        static ODataAPIContext()        {            //关闭数据库初始化操作            Database.SetInitializer<ODataAPIContext>(null);        }}

数据库连接


public class ProductsController : ODataController    {        private ODataAPIContext db = new ODataAPIContext();        // GET Products        //[Queryable]        [EnableQuery]        public IQueryable<Product> GetProducts()        {            return db.Products;        }        // GET Products(5)        //[Queryable]        [EnableQuery]        public SingleResult<Product> GetProduct([FromODataUri] int key)        {            return SingleResult.Create(db.Products.Where(product => product.ID == key));        }        /// <summary>        /// 更新、 修改        /// </summary>        /// <param name="key"></param>        /// <param name="product"></param>        /// <returns></returns>        // PUT Products(5)        public async Task<IHttpActionResult> Put([FromODataUri] int key, Product product)        {            if (!ModelState.IsValid)            {                return BadRequest(ModelState);            }            if (key != product.ID)            {                return BadRequest();            }            db.Entry(product).State = EntityState.Modified;            try            {                await db.SaveChangesAsync();            }            catch (DbUpdateConcurrencyException)            {                if (!ProductExists(key))                {                    return NotFound();                }                else                {                    throw;                }            }            return Updated(product);        }        /// <summary>        /// 新增        /// </summary>        /// <param name="product"></param>        /// <returns></returns>        // POST Products        public async Task<IHttpActionResult> Post(Product product)        {            if (!ModelState.IsValid)            {                return BadRequest(ModelState);            }            db.Products.Add(product);            await db.SaveChangesAsync();            return Created(product);        }        /// <summary>        ///         /// </summary>        /// <param name="key"></param>        /// <param name="patch"></param>        /// <returns></returns>        // PATCH Products(5)        [AcceptVerbs("PATCH", "MERGE")]        public async Task<IHttpActionResult> Patch([FromODataUri] int key, Delta<Product> patch)        {            if (!ModelState.IsValid)            {                return BadRequest(ModelState);            }            Product product = await db.Products.FindAsync(key);            if (product == null)            {                return NotFound();            }            patch.Patch(product);            try            {                await db.SaveChangesAsync();            }            catch (DbUpdateConcurrencyException)            {                if (!ProductExists(key))                {                    return NotFound();                }                else                {                    throw;                }            }            return Updated(product);        }        /// <summary>        /// 删除        /// </summary>        /// <param name="key"></param>        /// <returns></returns>        // DELETE Products(5)        public async Task<IHttpActionResult> Delete([FromODataUri] int key)        {            Product product = await db.Products.FindAsync(key);            if (product == null)            {                return NotFound();            }            db.Products.Remove(product);            await db.SaveChangesAsync();            return StatusCode(HttpStatusCode.NoContent);        }        protected override void Dispose(bool disposing)        {            if (disposing)            {                db.Dispose();            }            base.Dispose(disposing);        }        private bool ProductExists(int key)        {            return db.Products.Count(e => e.ID == key) > 0;        }    }

运行查看


2查看$metadata



3、查看集合



五、添加OData客户端

1、工具--扩展和更新--安装“OData v4 Client Code Generator



2、添加控制台程序


3、添加新建项



 

4、ODataClient.tt文件中修改MetadataDocumentUri路径


5、保存或者在文件上面右击运行自定义工具,生成相应文件




6、执行

class Program    {        static void Main(string[] args)        {            const string serviceUri = "http://localhost:57244/";             var container = new DefaultContainer(new Uri(serviceUri));            foreach (var p in container.Products)            {                Console.WriteLine("{0} {1}", p.ID, p.Name);            }            Console.Read();        }    }


  


阅读全文
1 0
原创粉丝点击