【问题标题】:ASP MVC null reference exception with MVC Membership (OpenID) controller带有 MVC 成员资格 (OpenID) 控制器的 ASP MVC 空引用异常
【发布时间】:2009-04-27 04:46:39
【问题描述】:

我要提前道歉。我是 ASP.NET 和 MVC 的新手,还没有深入了解内部结构和操作流程。我正在尝试将ASP.NET MVC Membershp Starter Kit 集成到我正在开发的网站中以获得 OpenID 支持。

我已经解决了几个问题,但我不知道从哪里开始寻找我不断遇到的空引用异常。流程如下:

  1. 用户点击页面上的“登录”
  2. MVC MembershipAdministrationController 被正确触发。它检测到当前没有登录用户,因此使用登录表单 (Login.aspx) 进行响应。
  3. 渲染此表单时引发空引用异常。具体来说,抛出异常的部分是:

    <% using(Html.Form( "OpenID", "Login" )){ %>
      <fieldset class="MvcMembership">
        <legend>Login</legend>
        <div><label for="openid_identifier">OpenID Url:</label> <% =Html.TextBox( "openid_identifier" )%></div>
        <div><% =Html.SubmitButton( "submit", "Login", new { onclick = "return starterKit_mvc_membership_validateOpenIdLogin();" } )%></div>
      </fieldset>
    <% } %>
    

对 Html.Form ("OpenID", "Login") 的调用是引发异常的调用。这是调用堆栈:

System.Web.HttpUnhandledException: Exception of type 'System.Web.HttpUnhandledException' was thrown. ---> System.NullReferenceException: Object reference not set to an instance of an object.
   at System.Collections.Generic.Dictionary`2.Enumerator.MoveNext()
   at System.Web.Routing.ParsedRoute.Bind(RouteValueDictionary currentValues, RouteValueDictionary values, RouteValueDictionary defaultValues, RouteValueDictionary constraints)
   at System.Web.Routing.Route.GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
   at System.Web.Routing.RouteCollection.GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
   at Microsoft.Web.Mvc.FormExtensions.Form(HtmlHelper helper, String controllerName, String actionName, FormMethod method, IDictionary`2 htmlAttributes)
   at Microsoft.Web.Mvc.FormExtensions.Form(HtmlHelper helper, String controllerName, String actionName)
   at ASP.views_openid_login_aspx.__RenderopenIdLoginContent(HtmlTextWriter __w, Control parameterContainer) in d:\Data\Personal\purplemartin.tv\mvc\MvcMembership\Views\OpenID\Login.aspx:line 15
   at System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children)
   at System.Web.UI.Control.RenderChildren(HtmlTextWriter writer)
   at System.Web.UI.Control.Render(HtmlTextWriter writer)
   at System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter)
   at System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter)
   at System.Web.UI.Control.RenderControl(HtmlTextWriter writer)
   at ASP.views_shared_site_master.__Render__control1(HtmlTextWriter __w, Control parameterContainer) in d:\Data\Personal\purplemartin.tv\mvc\MvcMembership\Views\Shared\Site.Master:line 46
   at System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children)
   at System.Web.UI.Control.RenderChildren(HtmlTextWriter writer)
   at System.Web.UI.Control.Render(HtmlTextWriter writer)
   at System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter)
   at System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter)
   at System.Web.UI.Control.RenderControl(HtmlTextWriter writer)
   at System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children)
   at System.Web.UI.Control.RenderChildren(HtmlTextWriter writer)
   at System.Web.UI.Page.Render(HtmlTextWriter writer)
   at System.Web.Mvc.ViewPage.Render(HtmlTextWriter writer)
   at System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter)
   at System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter)
   at System.Web.UI.Control.RenderControl(HtmlTextWriter writer)
   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
   --- End of inner exception stack trace ---
   at System.Web.UI.Page.HandleError(Exception e)
   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
   at System.Web.UI.Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
   at System.Web.UI.Page.ProcessRequest()
   at System.Web.UI.Page.ProcessRequestWithNoAssert(HttpContext context)
   at System.Web.UI.Page.ProcessRequest(HttpContext context)
   at ASP.views_openid_login_aspx.ProcessRequest(HttpContext context) in c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\root\cada2385\9a6742fc\App_Web_zl9plrr2.1.cs:line 0
   at System.Web.Mvc.ViewPage.RenderView(ViewContext viewContext)
   at System.Web.Mvc.WebFormView.RenderViewPage(ViewContext context, ViewPage page)
   at System.Web.Mvc.WebFormView.Render(ViewContext viewContext, TextWriter writer)
   at System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context)
   at System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult)
   at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass11.<InvokeActionResultWithFilters>b__e()
   at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func`1 continuation)
   at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass11.<>c__DisplayClass13.<InvokeActionResultWithFilters>b__10()
   at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult)
   at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName)
   at System.Web.Mvc.Controller.ExecuteCore()
   at System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext)
   at System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext)
   at System.Web.Mvc.MvcHandler.ProcessRequest(HttpContextBase httpContext)
   at System.Web.Mvc.MvcHandler.ProcessRequest(HttpContext httpContext)
   at System.Web.Mvc.MvcHandler.System.Web.IHttpHandler.ProcessRequest(HttpContext httpContext)
   at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

根据要求,控制器如下所示:

    [HandleError( ExceptionType = typeof(OpenIdException) )]
    [HandleError( ExceptionType = typeof(System.Net.WebException) )]
    public virtual ActionResult Login( string openid_identifier )
    {
        //### set page title & declare variables
        ViewData["Title"] = "Login via OpenID";
        var errors = new List<string>();
        var rememberMe = false;
        var openid = new OpenIdRelyingParty();

        //### stage 1: display login form to user
        if( openid.Response == null && Request.HttpMethod != "POST" )
            return View();

显然,这不是完整的控制器,但这是第一次执行的全部内容(当登录表单被渲染时)。第一次openid.Response为null,请求方法为"POST"

我从哪里开始寻找问题?看起来可能与路由有关,但我不确定。

【问题讨论】:

  • 控制器中的代码长什么样?
  • 我已将控制器(相关部分)添加到主要问题中。感谢收看。

标签: asp.net asp.net-mvc asp.net-membership


【解决方案1】:

Simon,您实际上是指“System.Web.Mvc.Html.FormExtensions”,而不是“Microsoft.Web.Mvc.FormExtensions”吗?有 'Microsoft.Web.Mvc.FormExtensions' 类 (http://aspnet.codeplex.com/SourceControl/changeset/view/22929#266407) 但没有 Form 方法。也许您使用的是旧版本的 Microsoft.Web.Mvc.dll ?在 Reflector 中打开您的 Microsoft.Web.Mvc.dll - 在我的机器上 Microsoft.Web.Mvc.dll 的版本为 1.0.0.0,有 4 种方法:

public static MvcForm BeginForm<TController>(this HtmlHelper helper, Expression<Action<TController>> action) where TController: Controller;
public static MvcForm BeginForm<TController>(this HtmlHelper helper, Expression<Action<TController>> action, FormMethod method) where TController: Controller;
public static MvcForm BeginForm<TController>(this HtmlHelper helper, Expression<Action<TController>> action, FormMethod method, IDictionary<string, object> htmlAttributes) where TController: Controller;
public static MvcForm BeginForm<TController>(this HtmlHelper helper, Expression<Action<TController>> action, FormMethod method, object htmlAttributes) where TController: Controller;

声明类型:Microsoft.Web.Mvc.FormExtensions

程序集:Microsoft.Web.Mvc,版本=1.0.0.0

更新:

我已经下载了ASP.Net MVC Membership Starter Kit Preview 5 (0.5)。 bin 文件夹中的 Microsoft.Web.Mvc.dll 具有 1.0.0.0 版本,但它比 ASP.NET MVC v1.0 的 Microsoft.Web.Mvc.dll 旧。您可以下载最新版本的 Microsoft.Web.Mvc.dll there

【讨论】:

  • 是的...原来是 beta-> 发布问题。谢谢。
【解决方案2】:

由于我对这个问题的回应很少,我开始寻找将 OpenID 集成到 ASP.NET MVC 中的替代方法。我发现RPXLibRPXNow 的一个很好的.NET 和MVC 包装器。这是一种来自多个供应商的 OpenID 登录 Web 服务方法。

这不是一个完美的解决方案,因为我必须编写 openid 凭据和本地配置文件之间的映射代码,但这足以满足我的需求。

我仍然有兴趣解决 Html.Form("controller", "action") 引发空引用异常的原始问题。我试过使用通用版本,结果相同:Html.Form&lt;Controller&gt;(c =&gt; c.Action())

【讨论】:

    【解决方案3】:

    您使用的是 ASP.NET MVC v1.0(不是 Preview、Beta 或 RC)吗? v1.0似乎没有Html.Form,只有Hrml.BeginForm。如果您查看 ASP.NET MVC v1.0 源代码,则在 System.Web.Mvc.Html.FormExtensions 类中没有 Form 方法,而只有 BeginForm

    【讨论】:

    • 实际上确实似乎是 MVC 1.0 中的 Html.Form 扩展方法。请参阅 Microsoft.Web.Mvc.FormExtensions 静态方法类。 “Form”有 7 个重载。但是 FormBegin 听起来很有趣。我去看看。
    • 我认为您使用的是旧版本 Microsoft.Web.Mvc.dll
    【解决方案4】:

    如果一切都失败了,您仍然可以下载ASP.NET MVC source,将其连接到您的项目并进行调试。这需要更多的努力,但它确实有助于找出引擎盖下出了什么问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-10-31
      • 1970-01-01
      • 2013-04-22
      • 1970-01-01
      • 2017-03-25
      • 2018-11-11
      • 1970-01-01
      相关资源
      最近更新 更多