MVC抽象基本控制器覆盖模型绑定的参数类型

时间:2010-10-30 16:20:43

标签: c# asp.net-mvc model-binding oop

为简单起见,假设我有以下抽象基本控制器类:

public abstract class RESTController : Controller
{      
    public abstract JsonResult List();
    public abstract JsonResult Get(Guid id);
    public abstract JsonResult Create(object obj);
    public abstract JsonResult Update(object obj);
    public abstract JsonResult Delete(Guid Id);
}

创作&更新方法,我不仅要覆盖Method,还要覆盖参数的类型。

通常我会像这样使用泛型:

public abstract JsonResult Create<T>(T obj);

然而,这是一个MVC操作,并且无法指定类型参数。

我有什么选择?如果我将其保留为(object obj),MVC模型绑定器是否正常工作?

var model = obj as MyViewModel;

在任何情况下都不是很干净。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:8)

行间如何:

public abstract class RESTController<T> : Controller
{      
    public abstract JsonResult List();
    public abstract JsonResult Get(Guid id);
    public abstract JsonResult Create(T obj);
    public abstract JsonResult Update(T obj);
    public abstract JsonResult Delete(Guid Id);
}

当覆盖时:

public FooController: RESTController<Foo>
{
    ...
    public override JsonResult Create(Foo obj)
    {
        throw new NotImplementedException();
    }
    ...
}

答案 1 :(得分:0)

如果你想要更充实的东西,你可以尝试使用下面的内容。我使用Onion架构和存储库模式,使用IoC和DI。 IEntity只是提供对实体的Id字段的访问权限(我假设实体框架代码优先在这里,Entity.Id作为每个实体的主键,而EntityId将在另一个表上指定一个外键。)。

这些操作是虚拟的,允许派生类在必要时覆盖它们,并且存储库设置为protected,以便派生类也可以从实体的存储库中提取。这适用于基本的CRUD存储库,但可以用聚合替换以允许更多功能。

using System;
using System.Web.Mvc;
using MySolution.Core.Interfaces.EntityFramework;
using MySolution.Core.Interfaces.Repositories;

namespace MySolution.Ux.Web.Site.Primitives
{
    /// <summary>
    ///     Provides mechanisms for performing CRUD operations on entities within a RESTful environment.
    /// </summary>
    /// <typeparam name="TEntity">The type of the entity.</typeparam>
    public abstract class CrudController<TEntity> : Controller 
        where TEntity : class, IEntity, new()
    {
        /// <summary>
        ///     The repository to use for CRUD operations on the entity. Derived classes
        ///     also have access to this repository so that the virtual actions can be
        ///     overridden with custom implementations.
        /// </summary>
        protected readonly IRepository<TEntity> Repository;

        /// <summary>
        ///     Initialises a new instance of the <see cref="CrudController{TEntity}"/> class.
        /// </summary>
        /// <param name="repository">The repository.</param>
        protected CrudController(IRepository<TEntity> repository)
        {
            // Instantiate the controller's repository.
            Repository = repository;
        }

        /// <summary>
        ///     Lists this specified entities within the data store.
        /// </summary>
        /// <returns>A JSON formatted list of the entities retrieved.</returns>
        [HttpGet]
        public virtual JsonResult List()
        {
            try
            {
                return Json(Repository.GetAll(), JsonRequestBehavior.AllowGet);
            }
            catch (Exception e)
            {
                return Json(e.Message, JsonRequestBehavior.AllowGet);
            }

        }

        /// <summary>
        ///     Gets a specific entity within the data store.
        /// </summary>
        /// <returns>A JSON formatted version of the entity retrieved.</returns>
        [HttpGet]
        public virtual JsonResult Get(Guid id)
        {
            try
            {
                return Json(Repository.Get(id), JsonRequestBehavior.AllowGet);
            }
            catch (Exception e)
            {
                // An error has occured. Handle the exceptions as needed and return feedback via JSON.
                return Json(e.Message, JsonRequestBehavior.AllowGet);
            }

        }

        /// <summary>
        ///     Creates a specific entity within the data store.
        /// </summary>
        /// <returns>A JSON formatted version of the entity created.</returns>
        [HttpPost]
        public virtual JsonResult Create(TEntity entity)
        {
            try
            {
                Repository.Add(entity);
                Repository.Save();
                return Json(entity);
            }
            catch (Exception e)
            {
                // An error has occured. Handle the exceptions as needed and return feedback via JSON.
                return Json(e.Message);
            }

        }

        /// <summary>
        ///     Updates a specific entity within the data store.
        /// </summary>
        /// <returns>A JSON formatted version of the entity updated.</returns>
        [HttpPut]
        public virtual JsonResult Update(TEntity entity)
        {
            try
            {
                Repository.Update(entity);
                Repository.Save();
                return Json(entity);
            }
            catch (Exception e)
            {
                // An error has occured. Handle the exceptions as needed and return feedback via JSON.
                return Json(e.Message);
            }

        }

        /// <summary>
        ///     Deletes a specific entity from the data store.
        /// </summary>
        /// <returns>A JSON formatted version of the entity deleted.</returns>
        [HttpDelete]
        public virtual JsonResult Delete(Guid id)
        {
            try
            {
                var entity = Repository.Get(id);
                Repository.Remove(entity);
                Repository.Save();
                return Json(entity);
            }
            catch (Exception e)
            {
                // An error has occured. Handle the exceptions as needed and return feedback via JSON.
                return Json(e.Message);
            }

        }
    }
}