标签:efi toc result 手动 com post 控制器 斜杠 contex
在VS中创建一个新的Asp.Net Web应用项目,命名为“PersonsService”,如下图:
搜索Microsoft.AspNet.Odata包跟EntityFramework包安装
Model类是一个表示应用中的数据实体的对象。
在解决方案资源管理器中的Models文件夹下,创建一个Person类:
namespace PersonsService.Models { public class Person { public int Id { get; set; } public string Name { get; set; } public bool Gender { get; set; } public string UserName { get; set; } } }
打开Web.config文件,在configuration元素中添加下面的connectionStrings节点:
<connectionStrings> <add name="PersonsContext" connectionString="Server=.;Database=PersonsDB;Integrated Security=True" providerName="System.Data.SqlClient"/> </connectionStrings>
在Models文件夹下添加一个PersonsContext类:
using System.Data.Entity; namespace PersonsService.Models { public class PersonsContext : DbContext { public PersonsContext() : base("name=PersonsContext") { } public DbSet<Person> Persons { get; set; } } }
打开NuGet包管理器,程序包管理器控制台输入以下命令 "enable-migrations" ,"add-migration","update-database "
这个时候打开SQL Server 就可以看到已经创建好的数据库
打开App_Start/WebApiConfig.cs文件,配置下面的新代码
using Microsoft.OData.Edm; using PersonsService.Models; using System.Web.Http; using System.Web.OData.Builder; using System.Web.OData.Extensions; namespace PersonsService { public static class WebApiConfig { public static void Register(HttpConfiguration config) { // Web API 配置和服务 // Web API 路由 config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); //构建路由服务 config.MapODataServiceRoute( routeName: "odata", routePrefix: "odata", model: GetModel() ); } private static IEdmModel GetModel() { var builder = new ODataConventionModelBuilder(); var esPerson = builder.EntitySet<Person>("Persons"); return builder.GetEdmModel(); } } }
上面的代码做了两件事:
EDM是一个抽象的数据模型。EDM用于创建服务元数据文档。ODataConventionModelBuilder类使用默认的命名规范创建了一个EDM。这种方式需要写的代码最少。如果你想更多地控制EDM,那么你可以使用 ODataModelBuilder类来创建EDM类,这样做就要显式添加属性,键和导航属性。
路由(route)会告诉Web API如何将HTTP请求路由到终结点。调用MapODataServiceRoute 扩展方法可以创建一个OData v4路由。
如果你的应用有了多个OData终结点,那么要为每个终结点创建一个单独的路由,给每个路由一个唯一的路由名和前缀(prefix)。
控制器是处理HTTP请求的一个类。在OData应用中,应该为每个实体集创建一个单独的控制器。而在这篇博客中,我们只要为Person实体创建一个控制器就行了。
在Controllers文件夹下添加一个控制器,如下:
修改控制器代码,如下:
using PersonsService.Models; using System.Linq; using System.Web.OData; namespace PersonsService.Controllers { public class PersonsController : ODataController { private readonly PersonsContext db = new PersonsContext(); [EnableQuery] public IQueryable<Person> Get() { return db.Persons; } [EnableQuery] public IQueryable<Person> Get([FromODataUri] int key) { return db.Persons.Where(r=> r.Id==key); } } }
这时我们手动给数据库添加些数据,
好了,现在我们运行项目尝试请求下
请求http://localhost:3370/odata/Persons
现在数据都出来了,试下请求单个Person
http://localhost:3370/odata/Persons(1)
一切正常
无参数的Get()方法会返回整个Person表的集合。
Get([FromODataUri] int key)方法会返回指定Id的Person。
[EnableQuery]特性允许客户端使用查询选项(如$filter,$sort和$page)修改查询。
添加一个Post方法来添加Person
[HttpPost] public IHttpActionResult Post(Person person) { if (!ModelState.IsValid) { return BadRequest(ModelState); } db.Persons.Add(person); db.SaveChanges(); return Created(person); }
使用post请求http://localhost:3370/odata/Persons
看下数据库赵六已经添加进去了,现在添加一个修改方法
OData支持两种不同语义更新实体,包括PATCH和PUT。
PUT的劣势在于客户端必须发送实体的所有属性,包括没有改变的值。
OData说明书陈述了PATCH是首选。
[AcceptVerbs("PATCH", "MERGE")] public IHttpActionResult Patch([FromODataUri] int key, Delta<Person> patch) { if (!ModelState.IsValid) { return BadRequest(ModelState); } Person person = db.Persons.Find(key); if (person == null) { return NotFound(); } patch.Patch(person); try { db.SaveChanges(); } catch (DbUpdateConcurrencyException) { throw; } return Updated(person); }
在PATCH中,控制器使用了Delta类型来跟踪改变。
允许客户端从数据库删除一个Person:
// DELETE: odata/Persons(5) public IHttpActionResult Delete([FromODataUri] int key) { Person person = db.Persons.Find(key); if (person == null) { return NotFound(); } db.Persons.Remove(person); db.SaveChanges(); return StatusCode(HttpStatusCode.NoContent); }
后续会补充下odata配置自定义路由的问题.
[EnableQuery, HttpGet] [ODataRoute("Products({id})/Default.GetCatAndTown")] public IHttpActionResult GetCatAndTown([FromODataUri] int id) { var list = db.Products.Where(r => r.Id == id); return Ok(list); }
当然这个时候我们请求http://localhost:6785//Odata/Products(1)/Default.GetCatAndTown会报错404,解决方案是添加一个尾部的斜杠到请求的网址
这个时候我们http://localhost:6785//Odata/Products(1)/Default.GetCatAndTown/就会好了,具体原因不详。或者是修改web.config文件
<system.webServer> <handlers> <remove name="ExtensionlessUrlHandler-Integrated-4.0" /> <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" /> <add name="ExtensionlessUrlHandler-Integrated-4.0Custom" path="/odata*" verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" /> </handlers> </system.webServer>
标签:efi toc result 手动 com post 控制器 斜杠 contex
原文地址:https://www.cnblogs.com/onetype/p/8890493.html