我有一个基本控制器,其中包含几个我想要使用属性路由的操作,而不必在从基础继承的控制器中覆盖这些方法。
从.NET MVC 5.2开始,这应该是可行的:http://www.asp.net/mvc/overview/releases/whats-new-in-aspnet-mvc-52
提供的示例显示了如何使用类级别属性,但我想在操作级别实现它。有没有人成功实现了动作级别的属性继承? 我看到另一个答案.NET WebAPI Attribute Routing and inheritance声称这可以通过Web API控制器实现,但可以使用标准MVC控制器完成吗?
[InheritedRoute("attributerouting/{controller}/{action=Index}/{id?}")]
public abstract class BaseController : Controller
{
}
public class BlogController : BaseController
{
public string Index()
{
return "Hello from blog!";
}
}
public class StoreController : BaseController
{
public string Index()
{
return "Hello from store!";
}
}
[AttributeUsage(AttributeTargets.Class, Inherited=true, AllowMultiple=true)]
public class InheritedRouteAttribute : Attribute, IDirectRouteFactory
{
public InheritedRouteAttribute(string template)
{
Template=template;
}
public string Name { get; set; }
public int Order { get; set; }
public string Template { get; private set; }
public new RouteEntry CreateRoute(DirectRouteFactoryContext context)
{
// context.Actions will always contain at least one action - and all of the
// actions will always belong to the same controller.
var controllerDescriptor=context.Actions.First().ControllerDescriptor;
var template=Template.Replace("{controller}",
controllerDescriptor.ControllerName);
IDirectRouteBuilder builder=context.CreateBuilder(template);
builder.Name=Name;
builder.Order=Order;
return builder.Build();
}
}
// Custom direct route provider which looks for route attributes of type
// InheritedRouteAttribute and also supports attribute route inheritance.
public class InheritedDirectRouteProvider : DefaultDirectRouteProvider
{
protected override IReadOnlyList
GetControllerRouteFactories(ControllerDescriptor controllerDescriptor)
{
return controllerDescriptor
.GetCustomAttributes(typeof(InheritedRouteAttribute), inherit: true)
.Cast()
.ToArray();
}
}
答案 0 :(得分:9)
我认为我的操作级别使用以下代码:
public class InheritedDirectRouteProvider : DefaultDirectRouteProvider
{
protected override IReadOnlyList<IDirectRouteFactory>
GetActionRouteFactories(ActionDescriptor actionDescriptor)
{
return actionDescriptor.GetCustomAttributes(typeof(IDirectRouteFactory), inherit: true).Cast<IDirectRouteFactory>().ToArray();
}
}
并致电:
routes.MapMvcAttributeRoutes(new InheritedDirectRouteProvider());
这让我从抽象控制器继承控制器及其例程,简化示例:
// Inherited class needs to define [RoutePrefix("childPrefix")]
public abstract class ChildBaseController<TChildEntity> : BaseController where TChildEntity : ChildEntity
{
public ChildBaseController(IUnitOfWork DAL) : base(DAL) { }
protected abstract GenericChildRepository<TChildEntity> ChildRepository { get; }
protected abstract string[] GetCreateBindFields();
protected abstract string[] GetEditBindFields();
[Route("{valueId}")]
public ActionResult Index(int valueId)
{
ViewBag.ValueId = valueId;
return View(ChildRepository.Get().Where(cr => cr.ValueId == valueId));
}
... bunch more CRUD actions with [Route(...)] ...
}
继承的课程:
namespace Web.Frontend.Controllers
{
[RoutePrefix("Fields")]
public class FieldsController : ChildBaseController<Field>
{
public FieldsController(IUnitOfWork DAL) : base(DAL) { }
protected override GenericChildRepository<Field> ChildRepository
{
get
{
return DAL.Fields;
}
}
protected override string[] GetCreateBindFields()
{
return new string[] { ... };
}
protected override string[] GetEditBindFields()
{
return new string[] { ... };
}
}
}