6

作为 MVC4 + Entity + WebAPI 的新手,我很沮丧,为了简单地拥有 GET、POST 控制器处理程序和到数据模型的自定义映射。

我想我问的是有没有一个生成工具,例如从你的数据类中创建你的控制器类,这样我就可以直接从数据中执行简单的 GET 命令?

制作通用 RESTful API 的方法是什么,因此可以这样制作命令

获取 api/1.0/{genericdatatype}/{id}

通用数据类型可以是任何模型而没有特定控制器?假设我不需要 PUT(通过 MVC 应用程序处理),所以我真的不需要 POST 验证等。

4

3 回答 3

3

有一个名为 MVC Scaffolding 的工具/包,它将根据您的模型构建您的控制器。

http://mvcscaffolding.codeplex.com/

http://blog.stevensanderson.com/2011/01/13/scaffold-your-aspnet-mvc-3-project-with-the-mvcscaffolding-package/

至于通用部分,这是一个非常漫长和困难的过程,需要大量时间。如果有人对此有很好的答案,我也很乐意看到这一点。

编辑:我花了一些额外的时间来研究通用部分。看起来其他人也有类似的想法,并在这里提出了一个几乎相同的问题:Generic Web Api controller to support any model

归根结底,他们在那次谈话中表达了一些非常好的担忧。您如何处理不同类型的 ID?它们是否总是需要成为字符串然后解析出来?一旦你进入更多的业务规则,我怀疑你在控制器后面会有一个非常复杂的业务层。也就是说,我会说你最好坚持使用直接脚手架,而不是构建通用 API。当然,它可能可以完成,但是 API 背后的时间和疯狂解析代码的成本是多少?只是我的想法。

于 2013-01-23T22:42:59.250 回答
3

对于原始海报来说,这个答案可能为时已晚,但也许其他人可以使用它。

我刚刚为 MVC 5 代码优先 CRUD 操作制作了这个通用的基本 api 控制器:

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using My.Models;
using System.Data.Entity.Validation;

namespace My.Controllers.Api
{
  public abstract class CrudController<TEntity>
    : ApiController where TEntity : class
  {
    private readonly MyContext _db = new MyContext();
    private readonly DbSet<TEntity> _dbSet;

    protected CrudController(Func<MyContext, DbSet<TEntity>> dbSet)
    {
      _db = new EtlContext();
      _dbSet = dbSet(_db);
    }

    public IEnumerable<TEntity> Get()
    {
      return _dbSet.AsEnumerable();
    }

    public HttpResponseMessage Post(TEntity entity)
    {
      try
      {
        if (!ModelState.IsValid)
          return Request.CreateResponse(HttpStatusCode.BadRequest);

        _db.Entry(entity).State = EntityState.Added;

        _db.SaveChanges();

        return Request.CreateResponse(HttpStatusCode.Created);
      }
      catch (DbEntityValidationException)
      {
        return Request.CreateResponse(HttpStatusCode.BadRequest);
      }
      catch (DbUpdateException)
      {
        return Request.CreateResponse(HttpStatusCode.Conflict);
      }
    }

    public HttpResponseMessage Put(TEntity entity)
    {
      try
      {
        if (!ModelState.IsValid)
          return Request.CreateResponse(HttpStatusCode.BadRequest);

        _db.Entry(entity).State = EntityState.Modified;

        _db.SaveChanges();

        return Request.CreateResponse(HttpStatusCode.OK);
      }
      catch (DbEntityValidationException)
      {
        return Request.CreateResponse(HttpStatusCode.BadRequest);
      }
      catch (DbUpdateConcurrencyException)
      {
        return Request.CreateResponse(HttpStatusCode.NotFound);
      }
      catch (DbUpdateException)
      {
        return Request.CreateResponse(HttpStatusCode.Conflict);
      }
    }

    public HttpResponseMessage Delete(TEntity entity)
    {
      try
      {
        _db.Entry(entity).State = EntityState.Deleted;

        _db.SaveChanges();

        return Request.CreateResponse(HttpStatusCode.OK);
      }
      catch (DbUpdateConcurrencyException)
      {
        return Request.CreateResponse(HttpStatusCode.NotFound);
      }
    }

    protected override void Dispose(bool disposing)
    {
      _db.Dispose();
      base.Dispose(disposing);
    }
  }
}

我仍然必须像这样为每个 DbSet 创建子类:

public class CustomersController 
  : CrudController<Customer>
{
  public CustomersController()
    : base(db => db.Customers)
  {}
}

public class ProductsController 
  : CrudController<Product>
{
  public ProductsController()
    : base(db => db.Products)
  {}
}

使此路由工作:

config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}",
 );
于 2013-09-22T20:39:09.360 回答
1

我自己提供了我们团队采用的替代方案。数据。它是构建初始 RESTful 模板的一种快速方法,比 CRUD 更强调查询,它使数据可用,而无需手动构建端点。我现在正在为一个在 Web API 服务器上具有 OData 的项目做前端,这可以很好地释放后端开发人员来处理比集合端点更紧迫的问题。

它也适用于实体框架。

于 2016-02-04T21:54:58.467 回答