【发布时间】:2018-06-29 07:36:39
【问题描述】:
我们有一组控制器返回 JSON 数据以通过 Web API 同步实体。每个数据实体都有自己的控制器和数据模型(“Order, Item, Customer, ...”) 因此,这基本上让每个控制器都使用完全相同的代码。唯一的区别是控制器/web api 路径的名称,以及将通过 JSON 返回的数据模型。 我们想要做的是拥有一个所有其他控制器实现/扩展的基本控制器(BaseController.cs)。为此,我们希望在每个子控制器类定义的基类中拥有一个虚拟的“EntityType”或“EntityName”属性。然后,我们返回数据的代码不必在每个控制器中重复。 我们的问题是我们无法弄清楚如何存储/传递/定义“类型”或“TEntity”变量。我们需要它来执行“Get” api 方法的主要部分:
例子:
var returnValue = dbContext.Set<GetEntityModelClass()>().FromSql("EXEC dbo.[AJ_P_{0}_API]", GetEntityModelName()).ToList();
我们在 BaseController.cs 类中实现 GetEntityModelName(),如下所示:
public virtual string GetEntityName() { return null; }
子控制器类的示例将具有以下内容:
public override string GetEntityName() { return "Product"; }
对于可以传递 dbContext.Set() 调用所需的值的类似 GetEntityModelClass(),我们如何做到这一点?
如果有帮助,这里有一个更大的代码示例:
BaseController.cs
-----------------------------------------
namespace API.Controllers
{
[Produces("application/json")]
public class BaseController : Controller
{
// Returns the name of an entity as it is used in stored procedures, class names, etc...
public virtual string GetEntityName()
{
return null;
}
// Return a type that can be utilized with the dbContext.Set<???>() call
public virtual ??? GetEntityName()
{
return ???;
}
// SiteContext is the API site's data context.
protected readonly SiteContext dbContext;
public BaseController(SiteContext context)
{
dbContext = context;
}
[HttpGet("{token}")]
public IActionResult Get([FromRoute] string token)
{
return Get(token);
}
public IActionResult Results(string token)
{
if (!ModelState.IsValid) { return BadRequest(ModelState); }
var returnValue = dbContext.Set<???GetEntityModel()???>().FromSql("EXEC dbo.[AJ_P_{0}_API] @Token={1}", GetEntityName(), token).ToList();
return Ok(returnValue);
}
}
}
ProductController.cs
-----------------------------------------
namespace API.Controllers
{
[Produces("application/json")]
[Route("/Product")]
public class ProductController : BaseController
{
public override string GetEntityName() {
return "Product";
}
public override ???? GetEntityModel() {
return ( ??? ProductModel type ??? )
}
public ProductController(SiteContext context) : base(context) { }
}
}
【问题讨论】:
-
我不是通用基本控制器的粉丝。但是,您可以使控制器通用,将所需的实体类型作为类型参数。那应该可以解决您的问题。
public abstract class BaseController<TEntity> : Controller
标签: c# generics asp.net-core asp.net-core-2.0