博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ASP.NET WebApi 开放数据
阅读量:5356 次
发布时间:2019-06-15

本文共 7447 字,大约阅读时间需要 24 分钟。

概述

      开放式数据协议(OData) 是用于在 web 数据访问协议。它提供统一的方式来构造数据、 查询的数据和操纵数据集通过 CRUD 操作。它支持 AtomPub (XML) 和 JSON 格式。它还定义的方式来公开元数据有关的数据。客户端可以使用元数据来发现的类型信息和数据集的关系。

      ASP.NET Web API 容易地创建一个数据集的 OData 终结点。您可以控制到底哪些 OData 操作终结点支持。你可以承载多个 OData 端点,除了非 OData 端点。你有你的数据模型后, 端业务逻辑和数据层的完全控制。

项目搭建

   

添加模型

    在Models文件夹下,添加Product.cs:           

namespace ApiDemo02.Models{    /// 产品实体类    public class Product    {        /// 产品ID        public int ID { get; set; }        /// 产品名称        public string Name { get; set; }        /// 产品类别        public string Genre { get; set; }        /// 产品价格        public decimal Price { get; set; }    }}

  注:先生成一下项目!

添加模型

     在 Controllers文件夹下,添加控制器:

     

     

     点击“添加”,则出现下面错误:

     

     原因:前面我提示过,创建新实体后,先生成一下项目。这里我还是忘记了,生成项目后,再照上面步骤添加控制器,ok!

     支架自动创建了两个文件:

        

修改配置

     打开App_Start文件下的WebApiConfig.cs,修改代码:   

using ApiDemo02.Models;using System.Web.Http;using System.Web.Http.OData.Builder;namespace ApiDemo02{    public static class WebApiConfig    {        public static void Register(HttpConfiguration config)        {            // Web API configuration and services            //创建 OData 端点的实体数据模型 (EDM)            ODataConventionModelBuilder builder = new ODataConventionModelBuilder();            //添加设置为 EDM 实体            builder.EntitySet
("Products"); //添加终结点的路由 config.Routes.MapODataRoute("odata", "odata", builder.GetEdmModel()); // Web API routes //config.MapHttpAttributeRoutes(); //config.Routes.MapHttpRoute( // name: "DefaultApi", // routeTemplate: "api/{controller}/{id}", // defaults: new { id = RouteParameter.Optional } //); } }}

  EDM 是一种抽象的数据模型。EDM 用于创建元数据文件和定义服务的 Uri。ODataConventionModelBuilder通过使用一组默认的命名约定 EDM 创建 EDM,这种方法要求最少代码。如果你想对 EDM 的更多控制,你可以使用ODataModelBuilder类来显式地创建 EDM 中的通过添加属性、 键和导航属性。

      EntitySet<Product>("Product")中"Product"的字符串定义是控制器的名称。终结点可以有多个实体集。EntitySet < T >对应一个实体集,然后再定义一个对应的控制器。

      MapODataRoute方法第一个参数是路线的友好名称。您服务的客户端看不到此名称。第二个参数是为终结点的 URI 前缀。鉴于此代码,为产品实体集的 URI 是 http:// /odata/Product。您的应用程序可以有多个 OData 端点。对于每个终结点,调用MapODataRoute ,并提供一个独特的路由名称和唯一的 URI 前缀。

      在修改一下根目录下的Web.config中的<connectionStrings>数据库连接字符串节点:

      注:这一小节EDM有点难理解,我也得好好琢磨一下!

迁移及初始化数据库

      打开VS“工具”:

      

      查看迁移帮助:

      

      启用迁移:

       

      这时,会多出Migrations文件夹及其下Configuration.cs文件:

      

      修改Migrations文件夹下Configuration.cs文件来添加种子数据:      

using ApiDemo02.Models;using System.Data.Entity.Migrations;namespace ApiDemo02.Migrations{    internal sealed class Configuration : DbMigrationsConfiguration
{ public Configuration() { AutomaticMigrationsEnabled = false; } protected override void Seed(ApiDemo02.Models.ProductContext context) { context.Products.AddOrUpdate(new Product[] { new Product() { ID = 1, Name = "Hat", Price = 15, Genre = "Apparel" }, new Product() { ID = 2, Name = "Socks", Price = 5, Genre = "Apparel" }, new Product() { ID = 3, Name = "Scarf", Price = 12, Genre = "Apparel" }, new Product() { ID = 4, Name = "Yo-yo", Price = 4.95M, Genre = "Toys" }, new Product() { ID = 5, Name = "Puzzle", Price = 8, Genre = "Toys" }, }); } }}

  添加迁移:

      

      更新数据库:

      

      检查数据库文件:

     

      至此,数据库创建OK,也有了模拟数据!

访问测试

      这里使用HTTP工具来模拟请求,所以先去下载(http://www.telerik.com/fiddler)安装Fiddler4。

      运行项目,看一下端口:

      

      注:这里Chrome浏览器以xml方式读取,如果使用IE浏览器,它默认是json方式,会提示下载!

      打开fiddler,点Composer:

      

      点Execute后,并查看xml结果:

        

      响应json请求:

      

      查看结果:

      

      获取元数据,不论是否json请求,它返回xml格式: 

        

      查看结果:

      

      读取Product数据:

      

      查看数据:

      

      由于截图太多了,我就不演示POST等其它请求了! 

小结

      回顾一下Cntrollers下ProductController.cs的代码:      

using System.Data.Entity;using System.Data.Entity.Infrastructure;using System.Linq;using System.Net;using System.Web.Http;using System.Web.Http.ModelBinding;using System.Web.Http.OData;using ApiDemo02.Models;namespace ApiDemo02.Controllers{    /*    若要为此控制器添加路由,请将这些语句合并到 WebApiConfig 类的 Register 方法中。请注意 OData URL 区分大小写。    using System.Web.Http.OData.Builder;    using ApiDemo02.Models;    ODataConventionModelBuilder builder = new ODataConventionModelBuilder();    builder.EntitySet
("Product"); config.Routes.MapODataRoute("odata", "odata", builder.GetEdmModel()); */ public class ProductController : ODataController { private ProductContext db = new ProductContext(); // GET odata/Product [Queryable] public IQueryable
GetProduct() { return db.Products; } // GET odata/Product(5) [Queryable] public SingleResult
GetProduct([FromODataUri] int key) { return SingleResult.Create(db.Products.Where(product => product.ID == key)); } // PUT odata/Product(5) public 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 { db.SaveChanges(); } catch (DbUpdateConcurrencyException) { if (!ProductExists(key)) { return NotFound(); } else { throw; } } return Updated(product); } // POST odata/Product public IHttpActionResult Post(Product product) { if (!ModelState.IsValid) { return BadRequest(ModelState); } db.Products.Add(product); db.SaveChanges(); return Created(product); } // PATCH odata/Product(5) [AcceptVerbs("PATCH", "MERGE")] public IHttpActionResult Patch([FromODataUri] int key, Delta
patch) { if (!ModelState.IsValid) { return BadRequest(ModelState); } Product product = db.Products.Find(key); if (product == null) { return NotFound(); } patch.Patch(product); try { db.SaveChanges(); } catch (DbUpdateConcurrencyException) { if (!ProductExists(key)) { return NotFound(); } else { throw; } } return Updated(product); } // DELETE odata/Product(5) public IHttpActionResult Delete([FromODataUri] int key) { Product product = db.Products.Find(key); if (product == null) { return NotFound(); } db.Products.Remove(product); db.SaveChanges(); 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; } }}

  真的很神奇地采用数据库上下文帮我们封装好数据库操作!疑问:还有必要再封装成仓储库方式吗? 再有WebApi如何路由的和JSON序列化/格式化,有空再介绍。

     (注:截图过多,看起来花花绿绿地,抱歉了!)

       

         

转载于:https://www.cnblogs.com/fanjibao/p/3726458.html

你可能感兴趣的文章
01_1_准备ibatis环境
查看>>
windows中修改catalina.sh上传到linux执行报错This file is needed to run this program解决
查看>>
JavaScript中的BOM和DOM
查看>>
360浏览器兼容模式 不能$.post (不是a 连接 onclick的问题!!)
查看>>
spring注入Properties
查看>>
jmeter(五)创建web测试计划
查看>>
python基本数据类型
查看>>
1305: [CQOI2009]dance跳舞 - BZOJ
查看>>
将html代码中的大写标签转换成小写标签
查看>>
jmeter多线程组间的参数传递
查看>>
零散笔记
查看>>
MaiN
查看>>
[Python学习] 简单网络爬虫抓取博客文章及思想介绍
查看>>
触发器课程SQL Server 知识梳理九 触发器的使用
查看>>
信息浏览器从Android的浏览器中传递cookie数据到App中信息浏览器
查看>>
客户端连接linux虚拟机集群报错
查看>>
linux下部署一个JavaEE项目的简单步骤
查看>>
hash储存机制
查看>>
[Android学习系列16]Android把php输出的json加载到listview
查看>>
20145205 《信息安全系统设计基础》第14周学习总结
查看>>