views:

1161

answers:

4

I'm going to apologize ahead of time. I'm new to ASP.NET and MVC and don't yet grok the internals and flow of operations. I'm trying to get the ASP.NET MVC Membershp Starter Kit integrated into a site I'm developing to get OpenID support.

I've worked through several issues, but I'm stumped at where to start looking for a null reference exception that I keep getting. Here's the flow:

  1. User clicks "Login" on the page
  2. MVC MembershipAdministrationController is properly fired. It detects that there no currently logged-in user and so responds with a login form (Login.aspx).
  3. A null reference exception is thrown while rendering this form. Specifically, the section that throws the exception is:

    <% 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>
    <% } %>
    

The call to Html.Form ("OpenID", "Login") is the call throwing the exception. Here's the call stack:

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)

As requested, here is what the controller looks like:

 [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();

Obviously, this isn't the complete the controller, but this is all that executes the first time (when the login form is rendered). The first time openid.Response is null and the request method is "POST".

Where do I begin looking for the problem? It looks like it might have something to do with routing, but I'm not sure.

A: 

Since I've gotten very little response for this question, I've starting looking at alternatives for integrating OpenID into ASP.NET MVC. I've found RPXLib which is a nice .NET and MVC wrapper for RPXNow. This is a web-service approach to OpenID login from multiple vendors.

This is not a perfect solution since I have to write the mapping code between openid credentials and local profiles, but it's sufficient for my needs.

I'm still interested in resolving the original problem with Html.Form("controller", "action") throwing a null reference exception. I've tried using the generic version with the same results: Html.Form<Controller>(c => c.Action()).

Simon Gillbee
A: 

Are you using ASP.NET MVC v1.0 (not Preview, Beta or RC)? It seems that there is no Html.Form in v1.0 but only Hrml.BeginForm. If you look at ASP.NET MVC v1.0 source there is no Form method but only BeginForm in System.Web.Mvc.Html.FormExtensions class

eu-ge-ne
There actually *does* seem to be a Html.Form extension method in MVC 1.0. See Microsoft.Web.Mvc.FormExtensions static method class. There are 7 overloads of "Form". But FormBegin sounds interesting. I'll look at it.
Simon Gillbee
I think you are using old version Microsoft.Web.Mvc.dll
eu-ge-ne
+1  A: 

If all else fails, you can still download the ASP.NET MVC source, hook it up to your project and debug it. It's a bit more effort, but it really helps figuring out what's going wrong under the hood.

Adrian Grigore
+1  A: 

Simon, did you actually mean 'System.Web.Mvc.Html.FormExtensions', not 'Microsoft.Web.Mvc.FormExtensions'? There is 'Microsoft.Web.Mvc.FormExtensions' class (http://aspnet.codeplex.com/SourceControl/changeset/view/22929#266407) but there is no Form method. Maybe you are using old version of Microsoft.Web.Mvc.dll ? Open your Microsoft.Web.Mvc.dll in Reflector - on my machine Microsoft.Web.Mvc.dll have version 1.0.0.0 and there are 4 methods:

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;

Declaring Type: Microsoft.Web.Mvc.FormExtensions

Assembly: Microsoft.Web.Mvc, Version=1.0.0.0

UPDATED:

I've dowloaded ASP.Net MVC Membership Starter Kit Preview 5 (0.5). Microsoft.Web.Mvc.dll from bin folder have 1.0.0.0 vesion, but it is older than Microsoft.Web.Mvc.dll for ASP.NET MVC v1.0. You can download last version of Microsoft.Web.Mvc.dll there.

eu-ge-ne
Yup... turns out to be beta->release issue. Thanks.
Simon Gillbee