В .Net MVC как вы получаете доступ к переменным из URL Routing вне Action? - PullRequest
2 голосов
/ 17 февраля 2009

Я создаю контроллер, который могут наследовать другие контроллеры (обеспечивают базовую функциональность для всего сайта без повторения кода):

public abstract class ApplicationController : Controller
{
    protected ApplicationController()
    {
       //site logic goes here
       //what is the value of agentID from the Action below??
    }
}

public class AgentController : ApplicationController
{
    public ActionResult Index(string agentID)
    {
        return View();
    }
}

Логика, которая применяется ко всему сайту, войдет в конструктор класса ApplicationController.

Проблема в том, что в конструкторе мне нужно получить доступ к значению параметра из Action, в данном случае agentID (оно будет одинаковым для всего сайта). Есть ли способ прочитать это значение в?

Ответы [ 3 ]

1 голос
/ 17 февраля 2009

Действия происходят после конструкторов. Значение не существует (не было связано) в конструкторе. Данные о маршруте могут быть известны в конструкторе, но привязка данных действия определенно еще не произойдет. Вы не можете получить это значение с уверенностью, пока не будет вызвано действие.

Данные маршрута могут быть доступны внутри контроллера через:

ControllerContext.RouteData.Values

Однако неверно полагать, что agentID может быть привязан только к данным маршрута. Фактически, он может быть получен из серверной переменной, поля формы, параметра строки запроса и т. Д. Я бы посоветовал передать его явно, где бы это ни было необходимо. Если ничего другого, это делает ваши юнит-тесты лучше.

1 голос
/ 03 сентября 2009

Я понял, как это сделать ... очень похоже на ответ Крейга Стунца, но разница в том, как вы добираетесь до RouteData.

Использование ControllerContext.RouteData.Values ​​не работает в обычном методе, используемом таким образом (это происходит из исходного контроллера, но не из базового, как я построил), но я попал в RouteData, переопределив метод OnActionExecuting :

    protected override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        string agentID = filterContext.RouteData.Values["agentID"].ToString();
        OtherMethodCall(agentID);
    }
0 голосов
/ 17 февраля 2009

Есть, хотя вам нужно переопределить ControllerFactory. В вашем методе RegisterRoutes в global.asax.cs добавьте эту строку:

public static void RegisterRoutes(RouteCollection routes) {
    // Route code goes here
    ControllerBuilder.Current.SetControllerFactory(typeof(MyControllerFactory));
}

А затем определите свой MyControllerFactory класс

public class MyControllerFactory : DefaultControllerFactory {
    public override IController CreateController(RequestContext requestContext, string controllerName) {
        // poke around the requestContext object here
        return base.CreateController(requestContext, controllerName);
    }
}

Объект requestContext содержит все данные маршрута и значения в нем. Вы можете использовать это, чтобы передать все, что вы хотите, конструктору вашего контроллера.

Отредактируйте, чтобы добавить, что так работают большинство популярных инжекторов зависимостей (например, StructureMap ).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...