ASP.NET Web API OData - CRUD (New)


 ASP.NET MVC >  OData


 

Конфигурация OData канала с нуля


1. Установить пакет "Web API 2.2 for OData v4.0"

2. Установить пакет "Microsoft.AspNet.WebApi.WebHost"
3. В Web.config добавить assemblyBinding и runAllManagedModulesForAllRequests="true"
4. На клиента установить пакет "Microsoft.OData.Client"
5. Установить расширение VS для генерации прокси сервиса odata (подробная инструкция тут How to use OData Client Code Generator to generate client-side proxy class)
6. VS restart, Add New Item => Code => OData Client
7. В файле ODataClient.odata.config в "MetadataDocumentUri" ставим Value="http://localhost:21874/odata/$metadata" (в новой версии расширения odata.config не нужен, MetadataDocumentUri устанавливается прямо в ODataClient.tt шаблоне)
8. ODataClient.tt => Run Custom Tool
9. Реализуем ODataClientExtentions

Солюшен с сервисом и клинтом прилагается в аттаче.
 
Сервер


[ODataRoutePrefix("Degustations")]
public class DegustationsController : ODataController
{
    
protected DataContext Context { get; private set; }
    
public DegustationsController()
    {
        Context =
new DataContext();
        Context.Configuration.ProxyCreationEnabled =
false;
    }

    [
EnableQuery]
    [
ODataRoute]
    
public IHttpActionResult Get()
    {
        
return Ok(Context.Degustations);
    }

    [
ODataRoute("({id})")]
    [
EnableQuery]
    
public IHttpActionResult GetEntity(int id)
    {
        
return Ok(SingleResult.Create<Degustation>(Context.Degustations.Where(d => d.DegustationId == id)));
    }

    
public async Task<IHttpActionResult> Post(Degustation degustation)
    {
        
if (degustation.DegustationId == default(int))
        {
            Context.Degustations.Add(degustation);
            
await Context.SaveChangesAsync();
            
return base.Created(degustation);
        }

        
return NotFound();
    }

    
public async Task<IHttpActionResult> Patch(int key, Delta<Degustation> patch)
    {
        
var degustation = await Context.Degustations.FindAsync(key);
        
if (degustation == null)
        {
            
return NotFound();
        }

        patch.Patch(degustation);
        
await Context.SaveChangesAsync();
        
return Updated(degustation);
    }

    
public async Task<IHttpActionResult> Delete(int key)
    {
        
var degustation = await Context.Degustations.FindAsync(key);
        
if (degustation == null)
        {
            
return NotFound();
        }
        
else
        {
            Context.Degustations.Remove(degustation);
            
await Context.SaveChangesAsync();
            
return StatusCode(HttpStatusCode.NoContent);
        }
    }

    
protected override void Dispose(bool disposing)
    {
        
if (disposing)
        {
            
if (Context != null)
            {
                Context.Dispose();
                Context =
null;
            }
        }
        
        
base.Dispose(disposing);
    }
}

Клиент


var client = new ODataContext("http://localhost:21874/odata/");

// get all
var all = client.GetDegustationsAsync().Result;
Console.WriteLine("Всего: " + all.Count());

// get by id
var one = client.GetDegustationAsync(3).Result;
Console.WriteLine("Найдена запись: " + one != null);

// create
var new_degustation = client.CreateDegustationAsync(DateTime.Today, "Тестовая дегустация", "Описание").Result;
Console.WriteLine("Новая запись: " + new_degustation.DegustationId);

// update
client.UpdateDegustationAsync(3, DateTime.Today, "upd", "upd").Wait();

// delete
client.DeleteDegustationAsync(10).Wait();

Console.WriteLine("ok");
Console.Read();


OData.Application.zip


12.04.2017 10:02   troika  

Подскажите в чем разница в таком подходе создания OData сервиса с помощью, как я понял, WebAPI, и с помощью WCF Data Service? Я делал сервис WCF Data Service по этой статье https://www.codeproject.com/articles/572417/WebControls/ Но уже использовал EntityFrameworkDataService вместо DataService т.к. хочу использовать EF в работе. И сейчас при желании могу создавать на клиенте (основной клиент будет под .Net) по сути прокси с серверному dbContext: EntityRef.Entities dbContext = new EntityRef.Entities(new Uri("http://localhost:1816/WCF.svc/")); Правда я хочу побольше логики засунуть в сервис, поэтому это не слишком уж и важная штука, но интересная. И вот теперь я попал на вашу статью и задумался, а не будет ли для меня лучше такой подход? Подскажите чем руководствоваться что бы принять решение о выборе

13.04.2017 09:39   admin  

Очень хороший вопрос. Вот тут есть рецепт http://codearticles.ru/articles/2466 как раз на EntityFrameworkDataService, описывается его применение - Feed для MS Excel. Это очень удобно для отчётов, если никакой логики нет. Делаем модель, оборачиваем в EntityFrameworkDataService и у нас всё готово. Если нужна логика - приходится писать кучу контроллеров и методов, как здесь. Хочу заметить, что EntityFrameworkDataService является устаревшим подходом, приходится использовать старые протоколы WCF Data Services 5.6 и OData protocol V3. Да, мне нравится EntityFrameworkDataService, тем более он идеален для некоторых задач, но увы - это тупиковая ветвь эволюции.

Оставлять комментарии могут только зарегистрированные пользователи
Дата создания: 08.04.2014 16:10
Дата изменения: 04.09.2014 22:55
Автор: admin