Asp.NET MVC ModelBinder, получая метод действия - PullRequest
9 голосов
/ 01 июня 2011

Я получил пользовательский ModelBinder, и я хотел бы получить действие. Поскольку я хочу получить атрибуты действия, используя отражение, имени действия недостаточно.

мой метод действия:

[MyAttribute]
public ActionResult Index([ModelBinder(typeof(MyModelBinder))] MyModel model)
{
}

и здесь обычно ModelBinder

public class MyModelBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    {
        // here i would like to get the action method and his "MyAttribute"
    }
}

какие-либо предложения, другие решения?

большое спасибо заранее

Ответы [ 3 ]

4 голосов
/ 01 июня 2011

Нет, вы не можете со 100% уверенностью получить текущее действие из подшивки модели. Связыватель модели связан не с действием, а с привязкой к модели. Например, вы можете позвонить

TryUpdateMode(model)

В фильтре до выбора действия. Также обратите внимание, что метод действия может даже не быть методом CLR (см. http://haacked.com/archive/2009/02/17/aspnetmvc-ironruby-with-filters.aspx), который может быть отражен.

Я думаю, что реальный вопрос в том, что именно вы пытаетесь достичь, и это правильный путь? Если вы хотите, чтобы информация из действия передавалась в механизм связывания модели (учитывая, что механизм связывания модели должен постепенно ухудшаться, если информация отсутствует), вам следует использовать фильтр действий, чтобы поместить информацию в HttpContext.Items (или где-то в этом роде), а затем попросите ваше связующее.

Метод OnActionExecuting фильтра действий получает ActionExecutingContext, который имеет ActionDescriptor. Вы можете вызвать GetCustomAttributes для этого.

1 голос
/ 01 июня 2011

Вы можете попробовать это:

var actionName = controllerContext.RouteData.GetRequiredString("action");
var myAttribute = (MyAttribute) Attribute.GetCustomAttribute(controllerContext.Controller.GetMethod(actionName), typeof(MyAttribute));
0 голосов
/ 26 ноября 2016

Вы можете переопределить ControllerActionInvoker.FindAction(), чтобы получить атрибут действия и сохранить его в HttpContext.Current.Items, как упомянуто здесь, или в расширенном ControllerContext.RequestContext, как показано ниже:

public class MyControllerActionInvoker : ControllerActionInvoker
{
    protected override ActionDescriptor FindAction(ControllerContext controllerContext, ControllerDescriptor controllerDescriptor, string actionName)
    {
        var action = base.FindAction(controllerContext, controllerDescriptor, actionName);

        if (action != null)
        {
            var requestContext = ExtendedRequestContext.Bind(controllerContext);
            var attr = action.GetCustomAttributes(typeof(MyAttribute), false).FirstOrDefault();

            if (attr != null)
                requestContext.CustomAttribute = (MyAttribute)attr;
        }

        return action;
    }
}

public class ExtendedRequestContext : RequestContext
{
    public MyAttribute CustomAttribute { get; set; }

    public static ExtendedRequestContext Bind(ControllerContext controllerContext)
    {
        var requestContext = new ExtendedRequestContext
        {
            HttpContext = controllerContext.RequestContext.HttpContext,
            RouteData = controllerContext.RequestContext.RouteData
        };

        controllerContext.RequestContext = requestContext;
        return requestContext;
    }
}

По умолчанию вызыватель действия заменяется либов конструкторе вашего контроллера или на фабрике пользовательских контроллеров:

public MyController() : base()
{
    ActionInvoker = new MyControllerActionInvoker();
}

Кстати, Controller.TempData уже содержит элемент типа ReflectedParameterDescriptor, который дает вам доступ к ActionDescriptor, поэтому приведенный выше кодможет быть избыточным.Однако имейте в виду, что это зависит от реализации, поэтому может со временем меняться.

Наконец, получите атрибут из этого хранилища в своем классе связующего:

var requestContext = (ExtendedRequestContext)controllerContext.RequestContext;
if (requestContext.CustomAttribute != null)
{
    // apply your logic here
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...