一個Web API控制器來控制所有模型

api-design asp.net-core-mvc asp.net-core-webapi c# entity-framework-core

我正在創建一個包含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),在資源中我有模型作為字符串,在體內我有請求的主體作為對象。在使用實體框架執行請求的操作之前,我必鬚根據資源找到模型並將對象體轉換為該類。

有什麼建議怎麼做?一位同事使用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);

PS我認為通用的ApiController通常是個壞主意。它體積龐大,帶來了巨大的不必要的複雜性,但收益很小。



Related

許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow