HttpContext на экземплярах контроллеров имеют значение null в ASP.net MVC

это может быть неправильный способ использования контроллеров, но я заметил эту проблему и не понял, как ее исправить.

public JsonResult SomeControllerAction() {

    //The current method has the HttpContext just fine
    bool currentIsNotNull = (this.HttpContext == null); //which is false    

    //creating a new instance of another controller
    SomeOtherController controller = new SomeOtherController();
    bool isNull = (controller.HttpContext == null); // which is true

    //The actual HttpContext is fine in both
    bool notNull = (System.Web.HttpContext.Current == null); // which is false        

}

Я заметил, что HttpContext на контроллере не является "фактическим" HttpContext, который вы найдете в системе.Сеть.Свойство HttpContext.Текущий.

есть ли способ вручную заполнить HttpContextBase на контроллере? Или лучший способ создать экземпляр контроллера?

5 ответов


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


пока я собираюсь сделать следующее. Это кажется приемлемым решением...

public new HttpContextBase HttpContext {
    get {
        HttpContextWrapper context = 
            new HttpContextWrapper(System.Web.HttpContext.Current);
        return (HttpContextBase)context;                
    }
}

где это добавляется к классу контроллера, от которого эти контроллеры наследуются.

Я не уверен, является ли HttpContext нулевым желаемым поведением, но это исправит его тем временем для меня.


HttpContext в ControllerContext имеет значение null, поскольку он не задан при создании контроллера. Contructor контроллера не назначает это свойство, поэтому оно будет равно null. Обычно HttpContext устанавливается в HttpContext класса ControllerBuilder. Контроллеры создаются классе ControllerBuilder, затем DefaultControllerFactory. Когда вы хотите создать свой собственный экземпляр контроллера, вы можете использовать ExecuteMethod контроллера с собственного ControllerContext. Вы не хотите этого делать, это настоящее приложение. Когда вы получите больше опыта работы с фреймворком, вы найдете подходящий метод, чтобы сделать то, что вы хотите. Когда вам нужен ControllerContext в модульном тесте, вы можете использовать издевательскую структуру для издевательства над ControllerContext или вы можете класс подделки.

вы можете найти модель потока запросов в asp.net mvc on этот блог.

когда ваше новое к Asp.net mvc, это стоит усилий загрузите исходный код и прочитайте трассировку маршрута, как обрабатывается запрос.


вы хотите использовать некоторые функции контроллера? Или контроллер должен выполнить действие?

Если это первое, возможно, это какой-то код, который следует разделить на другой класс. Если это последнее, вы можете сделать это, чтобы просто заставить этот контроллер выполнить определенное действие:


return RedirectToAction("SomeAction", "SomeOtherController", new {param1 = "Something" });


вы используете фабрику регулятора? Если да, то как вы регистрируете компоненты?

Я столкнулся с этой проблемой, когда я непреднамеренно добавил зависимость на основе HttpContext как синглтон, а не Переходный в Windsor.

HttpContext был нулевым для всех, кроме первого запроса. Мне потребовалось время, чтобы найти его.