Pio*_*jan 7 c# asp.net .net-core asp.net-core asp.net-core-webapi
我正在开发 ASP.NET Core Webapi 项目。我想为每个控制器通用的所有方法(例如 CRUD 方法)实现某种基本/抽象通用控制器,并在所有其他控制器中继承此控制器。我在下面附上示例代码:
public abstract class BaseApiController : Controller
{
[HttpGet]
[Route("")]
public virtual IActionResult GetAll()
{
...
}
[HttpGet]
[Route("{id}")]
public virtual IActionResult GetById(int id)
{
...
}
[HttpPost]
[Route("")]
public virtual IActionResult Insert(myModel model)
{
...
}
}
[Route("api/Student")]
public class StudentController : BaseApiController
{
// Inherited endpoints:
// GetAll method is available on api/Student [GET]
// GetById method is available on api/Student/{id} [GET]
// Insert method is available on api/Student [POST]
//
// Additional endpoints:
// ShowNotes is available on api/Student/{id}/ShowNotes [GET]
[HttpGet]
[Route("{id}/ShowNotes")]
public virtual IActionResult ShowNotes(int id)
{
...
}
}
[Route("api/Teacher")]
public class TeacherController : BaseApiController
{
// Inherited endpoints:
// GetAll method is available on api/Teacher [GET]
// GetById method is available on api/Teacher/{id} [GET]
// Insert method is available on api/Teacher [POST]
//
// Additional endpoints:
// ShowHours is available on api/Teacher/{id}/ShowHours [GET]
[HttpGet]
[Route("{id}/ShowHours")]
public virtual IActionResult ShowHours(int id)
{
...
}
}
Run Code Online (Sandbox Code Playgroud)
我在 .NET Framework WebApi 中看到过这种解决方案,带有额外的自定义 RouteProvider,例如:
public class WebApiCustomDirectRouteProvider : DefaultDirectRouteProvider
{
protected override IReadOnlyList<IDirectRouteFactory> GetActionRouteFactories(HttpActionDescriptor actionDescriptor)
{
return actionDescriptor.GetCustomAttributes<IDirectRouteFactory>(inherit: true);
}
}
Run Code Online (Sandbox Code Playgroud)
每次我尝试到达派生控制器中的端点时,我都会收到 AmbigouslyActionException:
Multiple actions matched. The following actions matched route data and had all constraints satisfied:
XXX.WebApi.Controllers.CommonAppData.TeacherController.GetById
XXX.WebApi.Controllers.CommonAppData.StudentController.GetById
Run Code Online (Sandbox Code Playgroud)
是否可以在 .NET Core WebApi 中创建这样的 Base 控制器?我应该如何编写它来达到操作方法而不在派生控制器中显式声明它?我应该如何配置这种解决方案?Startup 类中还有其他配置吗?
由于这个主题是一个很好的主题,所以它值得并且我解释了我是如何做到的。您可以像这样创建一个通用控制器:
[Route("api/[controller]/[action]")]
[ApiController]
public class BaseController<TEntity> : Controller where TEntity : class, new()
{
private readonly YourDbContext _db;
public BaseController(YourDbContext db)
{
_db=db;
}
public virtual async Task<IActionResult> GetAll()
{
var data= await _db.Set<TEntity>().ToListAsync();
return View(data);
}
public virtual IActionResult GetById(int id)
{
var data= await _db.Set<TEntity>().FindAsync(e=>e.Id == id);
return View(data);
}
.....
}
Run Code Online (Sandbox Code Playgroud)
然后你可以像这样使用它:
public class StudentController : BaseController<Student>
{
}
Run Code Online (Sandbox Code Playgroud)
当然,您可以使用可选参数更好地编写它,如下所示:
public virtual async Task<IActionResult> GetAll(Expression<Func<TEntity, bool>>? predicate = null)
{
var data= await _db.Set<TEntity>().Where(predicate).ToListAsync();
....
}
Run Code Online (Sandbox Code Playgroud)
或者甚至根据需要覆盖继承控制器中的每个操作,并向操作添加必要的参数
public override Task<IActionResult> Get(....
Run Code Online (Sandbox Code Playgroud)
我希望喜欢它;)并且不要忘记投票。
| 归档时间: |
|
| 查看次数: |
4643 次 |
| 最近记录: |