具有通用操作方法的控制器
使用框架的默认实现,不,您不能执行此类操作:
public IHttpActionResult InsertData([FromBody] T model)
这是您收到的异常:
无法在控制器上调用操作方法“XXXX”
“XXXX”因为
操作方法是一个通用方法。
但是这个框架是非常可扩展的,如果你很好地理解了ASP.NET Web API 中的路由和操作选择 https://learn.microsoft.com/en-us/aspnet/web-api/overview/web-api-routing-and-actions/routing-and-action-selection?WT.mc_id=DT-MVP-5003235并了解路由、控制器选择、操作选择、参数绑定和操作调用是如何工作的,然后您可以对框架进行一些定制以支持通用操作方法选择和调用。
在您的自定义逻辑中,为了能够在运行时执行操作,您需要解析T
在运行时。为此,您可以依靠属性将其限制为某些已知类型,或者您可以依靠一些上下文信息,例如路由数据、标头值、一些特殊值,例如$type
在身体等等。
提供自定义实现来处理通用操作方法对于本文来说太宽泛了。也就是说,让我分享其他解决方案。
从通用基础控制器派生
您可以拥有一个基本通用控制器,然后拥有两个从基本控制器派生的非通用控制器,并通过在基本控制器中实现的单个方法处理请求。我假设你已经看到了这个帖子 https://stackoverflow.com/a/36413607/3110834它已经提出了相同的解决方案:
public class MyBaseController<T> : ApiController
{
public IHttpActionResult InsertData([FromBody] T model)
{
//Write the generic code here, for example:
dbContext.Set<T>().Add(model);
dbContext.SaveChanges();
return some value;
}
}
Then:
public class ProductController : MyBaseController<Product> { }
public class CustomerController : MyBaseController<Customer> { }
Rely on dynamic
并稍后根据上下文信息解析类型
另一种选择是具有以下操作方法:
public IHttpActionResult InsertData([FromBody] dynamic model)
然后基于一些上下文信息,如路由值、标头值、一些特殊值,如$type
在正文等中,您可以解析模型类型并调用您的私有泛型方法:
public IHttpActionResult InsertData([FromBody] dynamic model)
{
Type t = resolve type base on context information
object data = create an instance of t base on the model values;
var method = this.GetType().GetMethod(nameof(InsertDataPrivate),
BindingFlags.NonPublic | BindingFlags.Instance);
var result = (int)method.MakeGenericMethod(t)
.Invoke(this, new object[] { data });
return Ok(result);
}
private int InsertDataPrivate<T>(T model) where T
{
//Write the generic code here, for example:
dbContext.Set<T>().Add(model);
dbContext.SaveChanges();
return some value;
}