Oneweb API 控制所有模型的控制器
One Web API Controller to control all models
我正在创建一个包含 API 和 Web 的 MVC Core 1.0.1 项目。所以我已经创建了我的模型,现在我想在单个控制器中创建 CRUD 操作,而不是为每个模型搭建脚手架。我创建了一个看起来像这样的 ApiController
[Consumes("application/json")]
[Produces("application/json")]
[Route("/api/{resource}")]
public class ApiController : Controller
{
private readonly MasterContext _context;
public ApiController(MasterContext context)
{
_context = context;
}
[HttpPost]
public IActionResult Create(string resource, [FromBody] object body)
{
//_context.Add();
return Ok("ok api Create");
}
[HttpGet("{id?}")]
public IActionResult Read(string resource, int? id)
{
return Ok("ok api get Read");
}
[HttpPatch("{id}")]
public IActionResult Update(string resource, [FromBody] object body)
{
//_context.Update();
return Ok("ok api Update");
}
[HttpDelete("{id}")]
public IActionResult Delete(string resource, [FromBody] object body)
{
return Ok("ok api Delete");
}
}
这样我就有了我需要的每个 HTTP 方法的方法(Post、Get、Patch、Delete),在资源中我有模型作为字符串,在正文中有正文作为对象的请求。在使用 entity framework 执行请求的操作之前,我必须根据资源找到模型并将对象主体转换为 class。
有什么建议吗?一位同事使用 Python 完成了此操作,可以使用 c# 完成吗?结果会有什么缺点?例如,我认为模型验证将很难完成。
是的,这是可能的。假设我们有这个 DbContext:
public partial class FooContext : DbContext
{
//has "MyAssembly.Blog" type
public virtual DbSet<Blog> Blog { get; set; }
}
要在数据库中保存新实体,我们应该先找到 Blog
类型。有了类型,反序列化对象并保存它就很容易了:
//you called POST /blog
string resource = "blog";
string body = "{...}";
var context = new FooContext();
IEntityType entityType = context.Model
.GetEntityTypes()
.First(x => x.Name.EndsWith($".{resource}", StringComparison.OrdinalIgnoreCase));
//This type should be "MyAssembly.Blog" - exact entity CLR type.
//Another option to get this CLR type is assembly scan.
Type type = entityType.ClrType;
//having type, it is possible to create instance
object entity = JsonConvert.DeserializeObject("body", type);
//var entity = Activator.CreateInstance(type);
context.Entry(entity).State = EntityState.Added;
context.SaveChanges();
要通过 ID 从数据库中读取实体,请使用非通用 DbContext.Find
var entityFromDb = context.Find(type, id);
P.S。我认为通用 ApiController
通常不是一个好主意。它体积庞大,带来了巨大的不必要的复杂性,但却带来了很小的好处。
我正在创建一个包含 API 和 Web 的 MVC Core 1.0.1 项目。所以我已经创建了我的模型,现在我想在单个控制器中创建 CRUD 操作,而不是为每个模型搭建脚手架。我创建了一个看起来像这样的 ApiController
[Consumes("application/json")]
[Produces("application/json")]
[Route("/api/{resource}")]
public class ApiController : Controller
{
private readonly MasterContext _context;
public ApiController(MasterContext context)
{
_context = context;
}
[HttpPost]
public IActionResult Create(string resource, [FromBody] object body)
{
//_context.Add();
return Ok("ok api Create");
}
[HttpGet("{id?}")]
public IActionResult Read(string resource, int? id)
{
return Ok("ok api get Read");
}
[HttpPatch("{id}")]
public IActionResult Update(string resource, [FromBody] object body)
{
//_context.Update();
return Ok("ok api Update");
}
[HttpDelete("{id}")]
public IActionResult Delete(string resource, [FromBody] object body)
{
return Ok("ok api Delete");
}
}
这样我就有了我需要的每个 HTTP 方法的方法(Post、Get、Patch、Delete),在资源中我有模型作为字符串,在正文中有正文作为对象的请求。在使用 entity framework 执行请求的操作之前,我必须根据资源找到模型并将对象主体转换为 class。
有什么建议吗?一位同事使用 Python 完成了此操作,可以使用 c# 完成吗?结果会有什么缺点?例如,我认为模型验证将很难完成。
是的,这是可能的。假设我们有这个 DbContext:
public partial class FooContext : DbContext
{
//has "MyAssembly.Blog" type
public virtual DbSet<Blog> Blog { get; set; }
}
要在数据库中保存新实体,我们应该先找到 Blog
类型。有了类型,反序列化对象并保存它就很容易了:
//you called POST /blog
string resource = "blog";
string body = "{...}";
var context = new FooContext();
IEntityType entityType = context.Model
.GetEntityTypes()
.First(x => x.Name.EndsWith($".{resource}", StringComparison.OrdinalIgnoreCase));
//This type should be "MyAssembly.Blog" - exact entity CLR type.
//Another option to get this CLR type is assembly scan.
Type type = entityType.ClrType;
//having type, it is possible to create instance
object entity = JsonConvert.DeserializeObject("body", type);
//var entity = Activator.CreateInstance(type);
context.Entry(entity).State = EntityState.Added;
context.SaveChanges();
要通过 ID 从数据库中读取实体,请使用非通用 DbContext.Find
var entityFromDb = context.Find(type, id);
P.S。我认为通用 ApiController
通常不是一个好主意。它体积庞大,带来了巨大的不必要的复杂性,但却带来了很小的好处。