How to make a generic base controller with generic parameters in asp.net mvc4

I'm having problems with how to make a generic controller. I have Model that the id property can be type of string or int. When i want to Edit a model that id is int, i can't find the action resulting in an error, because i implemented a override method to public abstract ActionResult Edit(string id).

Exists a way to pass a generic parameter(string or int) that my route can be undertand?

public abstract class BaseController<T> : Controller
{
    //protected UnitOfWork unitOfWork = new           UnitOfWork(System.Web.HttpContext.Current.User.Identity.Name);        
    protected UnitOfWork unitOfWork = new UnitOfWork("");
    public abstract ActionResult List();
    public abstract ActionResult Index();
    public abstract ActionResult Details(string id);, 
    public abstract ActionResult CreateByModal();
    public abstract ActionResult Create();
    [HttpPost]
    [ValidateAntiForgeryToken]
    public abstract ActionResult Create(T entity);
    public abstract ActionResult Edit(string id);
    [HttpPost]
    [ValidateAntiForgeryToken]
    public abstract ActionResult Edit(T entity);       
    public abstract ActionResult Delete(string id);

    protected override void Dispose(bool disposing)
    {
        //db.Dispose();
        base.Dispose(disposing);
    }
}

 public class ModeloController : BaseController<Modelo>
{
    public override ActionResult Edit(string id)
    {
       //Here i have a int Id im my Model  and the error in my route
        Modelo modelo = unitOfWork.ModeloRepository.Find(id);
        if (modelo == null)
        {
            return HttpNotFound();
        }
        return PartialView("_Edit", modelo);
    }
}


public class GeneroController : BaseController<Genero>
{
    //Here i have a string Id im my Model 
    public override ActionResult Edit(string id)
    {
        Genero genero = unitOfWork.GeneroRepository.Find(id);
        if (genero == null)
        {
            return HttpNotFound();
        }
        return PartialView("_Edit", genero);
    }

}

Upvotes: 1

Views: 2970

Answers (2)

Steve Mitcham
Steve Mitcham

Reputation: 5313

You can add an additional generic type parameter to indicate your key type for the given class.

public abstract class AbstractController<TEntity, TId> : Controller
{
    // irrelevant stuff omitted
    public ActionResult Edit(TEntity id);
}

Upvotes: 1

D Stanley
D Stanley

Reputation: 152511

One option would be to overload each method that has id as a parameter:

public abstract ActionResult Details(string id);
public abstract ActionResult Details(int id); 

Or to add a second generic parameter for the type of id:

public abstract class BaseController<T, U> : Controller
{
    public abstract ActionResult Details(U id);
    public abstract ActionResult Edit(U id);

Either way you're putting more responsibility of the caller to make sure the right types are used.

Upvotes: 2

Related Questions