Reputation: 41
I have a generic WebApi controller with CRUD operations like this:
public abstract class BaseController<TEntity> : ApiController where TEntity : class
{
protected abstract DbSet<TEntity> DatabaseSet { get; }
// GET: api/{entity}
[Route("")]
public IEnumerable<TEntity> GetAll()
{
return DatabaseSet;
}
// GET: api/{entity}/5
[Route("{id:int}")]
//[ResponseType(TEntity)] ToDo: is this possible? <---
public IHttpActionResult Get(int id)
{
TEntity entity = DatabaseSet.Find(id);
if (entity == null)
{
return NotFound();
}
return Ok(entity);
}
// ...
// and the rest
// ...
}
My question is about the commented-out [ResponseType(TEntity)]. This line does not work. Also not with typeof(TEntity). The error is 'Attribute argument can not use type parameters' Is there a way to make the ResponseType known for the generic type?
Thanks! Jasper
Upvotes: 4
Views: 2146
Reputation: 2202
As from this link, Generic Attribute is not possible in C#.
I did the below workaround for Generic parameter in ResponseType attribute, which is basically adding the attribute to the derived class method.
public abstract class BaseApiController<TModel, TEntity> : ApiController
where TModel : class, IModel
where TEntity : IApiEntity
{
protected readonly IUnitOfWork _uow;
protected readonly IRepository<TModel> _modelRepository;
public BaseApiController(IUnitOfWork uow)
{
if (uow == null)
throw new ArgumentNullException(nameof(uow));
_uow = uow;
_modelRepository = _uow.Repository<TModel>();
}
protected virtual IHttpActionResult Get(int id)
{
var model = _modelRepository.Get(m => m.Id == id);
if (model == null)
{
return NotFound();
}
var modelEntity = Mapper.Map<TEntity>(model);
return Ok(modelEntity);
}
}
public class PostsController : BaseApiController<Post, PostApiEntity>
{
public PostsController(IUnitOfWork uow) : base(uow)
{
}
[ResponseType(typeof(PostApiEntity))]
public IHttpActionResult GetPost(int id)
{
return Get(id);
}
}
Upvotes: 3