Jasper van Zijp
Jasper van Zijp

Reputation: 41

WebApi2 ResponseType attribute of a generic type

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

Answers (1)

Boney
Boney

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

Related Questions