问题
我正在尝试采用现有的 ASP.NET Web 应用程序并手动将其迁移到使用 MVC 2(我目前正在运行 RC)。我遵循了几个步骤(稍后会列出)并且似乎可以正常工作,但后来我注意到我无法设置,AuthorizeAttribute
因为控制器上的 User 为 null。然后我注意到,当我导航到一个操作时,没有引发 HttpApplication 的常规生命周期事件(例如 BeginRequest 等)。我认为这可能与用户主体为空的原因有关。Web 主机是本地 IIS7 实例(在我的 Vista 工作站上)。
我创建了一个全新的 MVC 2 Web 应用程序,在迁移时用作参考。它运行得很好,引发了应用程序事件并按照我的预期填充了用户主体。
如果您想惩罚自己,请继续阅读下面的详细信息(尽我所能)。
迁移步骤
- 确保应用程序目录的应用程序池是 .NET 2.0 和集成
- 在我的 Web 项目中引用了 System.Web.Abstractions (v.3.5.0.0)、System.Web.routing (v3.5.0.0) 和 System.Web.Mvc (v2.0.0.0)。现在,我添加了 System.Web.Mvc 作为本地引用,以便更轻松地进行集成和部署。
- 修改了 csproj 以启用 MVC VS 插件优点(请参阅本文)
- 在项目中添加了 Controllers 和 Views 目录,从我的示例 MVC 应用程序中添加到 /Views/web.config 中。
- 修改了我的 web.config (注意:我在模块和处理程序中有其他废话,但为了简单和安全起见,我隐藏了......但这些很可能是问题的一部分):
该compilation
部分:
<compilation defaultLanguage="c#" debug="true">
<assemblies>
<add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
<add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add assembly="System.Web.Abstractions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add assembly="System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add assembly="System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add assembly="System.Data.DataSetExtensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
<add assembly="System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
<add assembly="System.Data.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
</assemblies>
</compilation>
该pages
部分:
<pages enableEventValidation="false"
pageBaseType="MyAssembly.ThemedBasePage">
<controls>
<add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add tagPrefix="asp" namespace="System.Web.UI.WebControls" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
</controls>
<namespaces>
<add namespace="System.Web.Mvc"/>
<add namespace="System.Web.Mvc.Ajax"/>
<add namespace="System.Web.Mvc.Html"/>
<add namespace="System.Web.Routing"/>
<add namespace="System.Linq"/>
<add namespace="System.Collections.Generic"/>
</namespaces>
</pages>
该system.webServer/modules
部分(记住,IIS7 集成):
<modules>
<remove name="ScriptModule" />
<remove name="UrlRoutingModule" />
<add name="ScriptModule" preCondition="managedHandler" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
</modules>
该system.webServer/handlers
部分:
<handlers>
<remove name="WebServiceHandlerFactory-Integrated"/>
<remove name="ScriptHandlerFactory"/>
<remove name="ScriptHandlerFactoryAppServices"/>
<remove name="ScriptResource"/>
<remove name="MvcHttpHandler"/>
<remove name="UrlRoutingHandler"/>
<add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add name="ScriptHandlerFactoryAppServices" verb="*" path="*_AppService.axd" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add name="ScriptResource" preCondition="integratedMode" verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add name="MvcHttpHandler" preCondition="integratedMode" verb="*" path="*.mvc" type="System.Web.Mvc.MvcHttpHandler, System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add name="UrlRoutingHandler" preCondition="integratedMode" verb="*" path="UrlRouting.axd" type="System.Web.HttpForbiddenHandler, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</handlers>
更新了我的 global.asax 以注册路由,并忽略会干扰我的遗留内容的内容:
private static void RegisterRoutes(RouteCollection routes) { // place any routes here you need to ignore, whether they // be legacy or legitimate resources. routes.IgnoreRoute(""); // i currently have functionality at "/", and this route frees up the root to be used by my Default.aspx routes.IgnoreRoute("{webForms}.aspx/{*pathInfo}"); routes.IgnoreRoute("{webServices}.asmx/{*pathInfo}"); routes.IgnoreRoute("ajaxpro/{*pathInfo}"); routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( "Default", // Route name "{controller}/{action}/{id}", // URL with parameters new {controller = "Home", action = "Index", id = ""} // Parameter defaults ); } protected void Application_Start() { // legacy crap here AreaRegistration.RegisterAllAreas(); RegisterRoutes(RouteTable.Routes); }
附加信息
我还使用 Autofac (v1.4.5.676) 的最新版本并利用他们的 Web 集成处理程序。我已经检查了两种方式,所有自动事实的东西都完全删除/禁用了,一切都按照我想要的方式进行了设置;无论哪种方式,对这个问题都没有影响。
我也试过这个,有没有我专门的超甜 IgnoreRoute 设置。没有效果。
另外,我想明确一点,路由似乎确实有效,我被正确发送到我的控制器和操作,我在 HttpContext.Current.User 处只有一个 Null 主体,它似乎完全没有提高任何应用程序生命周期事件。如果我不必,你知道,得到现任校长或做任何讨厌的授权,我永远不会知道有什么问题;)
是的,常规 ASPX 页面正常工作,应用程序生命周期事件正常引发。
这是我制作的一个失败的简单测试控制器的示例:
[Authorize]
public class FartsController : Controller
{
//
// GET: /Farts/
public ActionResult Index()
{
return View();
}
}
产生以下异常:
[NullReferenceException: Object reference not set to an instance of an object.]
System.Web.Mvc.AuthorizeAttribute.AuthorizeCore(HttpContextBase httpContext) +48
System.Web.Mvc.AuthorizeAttribute.OnAuthorization(AuthorizationContext filterContext) +35
System.Web.Mvc.ControllerActionInvoker.InvokeAuthorizationFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor) +103
System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +316
System.Web.Mvc.Controller.ExecuteCore() +104
System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +36
System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext) +7
System.Web.Mvc.<>c__DisplayClass8.<BeginProcessRequest>b__4() +34
System.Web.Mvc.Async.<>c__DisplayClass1.<MakeVoidDelegate>b__0() +21
System.Web.Mvc.Async.<>c__DisplayClass8`1.<BeginSynchronous>b__7(IAsyncResult _) +12
System.Web.Mvc.Async.WrappedAsyncResult`1.End() +53
System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +43
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +7
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +8678910
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155
这很糟糕:(。感谢您阅读我的短篇小说。