Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Craig100 1136 posts 2523 karma points c-trib
    Oct 13, 2015 @ 18:29
    Craig100
    0

    Login partial view macro fail

    Taking a login system used to protect some assets from a site in V7.2.4 over to a V7.2.8 site and getting an error when the login occurs. (Seeing the fault by changing /config/umbracoSettings.config and change from " <MacroErrors>inline</MacroErrors>" to " <MacroErrors>throw</MacroErrors>)

    The error is:-

    Collection was modified; enumeration operation may not execute.
    
    Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 
    
    Exception Details: System.InvalidOperationException: Collection was modified; enumeration operation may not execute.
    
    Source Error: 
    
    
    Line 10:        @Umbraco.Field("introText")
    Line 11: 
    Line 12:        @Umbraco.RenderMacro("Login")
    Line 13: 
    Line 14:    </div>
    
    Stack Trace: 
    
    
    [InvalidOperationException: Collection was modified; enumeration operation may not execute.]
       System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource) +52
       System.Collections.Generic.Enumerator.MoveNext() +12161977
       System.Web.Mvc.ModelStateDictionary.Merge(ModelStateDictionary dictionary) +98
       Umbraco.Web.Mvc.ControllerExtensions.EnsureViewObjectDataOnResult(ControllerBase controller, ViewResultBase result) +160
       Umbraco.Web.Mvc.ControllerExtensions.RenderViewResultAsString(ControllerBase controller, ViewResultBase viewResult) +60
       Umbraco.Web.Macros.PartialViewMacroEngine.Execute(MacroModel macro, IPublishedContent content) +686
       Umbraco.Web.Macros.PartialViewMacroEngine.Execute(MacroModel macro, INode node) +125
       umbraco.macro.LoadPartialViewMacro(MacroModel macro) +50
       umbraco.macro.renderMacro(Hashtable pageElements, Int32 pageId) +1134
       Umbraco.Web.UmbracoHelper.RenderMacro(macro m, IDictionary`2 parameters, page umbracoPage) +368
       Umbraco.Web.UmbracoHelper.RenderMacro(String alias, IDictionary`2 parameters, page umbracoPage) +72
       Umbraco.Web.UmbracoHelper.RenderMacro(String alias, IDictionary`2 parameters) +54
       Umbraco.Web.UmbracoHelper.RenderMacro(String alias, Object parameters) +47
       Umbraco.Web.UmbracoHelper.RenderMacro(String alias) +26
       ASP._Page_Views_LoginPage_cshtml.Execute() in c:\WebProjects\CPV7\CPV7\Views\LoginPage.cshtml:12
    

    I've checked the code and the Umbraco set up as much as I can but don't see any issues. Can anyone point me in the right direction to be looking?

    TIA

    Craig

  • Robert Foster 459 posts 1820 karma points MVP 2x admin c-trib
    Oct 14, 2015 @ 02:54
    Robert Foster
    0

    Hi Craig, Can you show us your Login macro contents and any other relevant code? Are you manipulating the ModelStateDictionary at all?

  • Craig100 1136 posts 2523 karma points c-trib
    Oct 14, 2015 @ 07:04
    Craig100
    0

    Sure.

    The login page code:

    @inherits Umbraco.Web.Mvc.UmbracoTemplatePage
    @{
        Layout = "Master.cshtml";
    }
    
    @Html.Partial("pageHeader", Model.Content)
    
    <div class="row row-margin-top">
        <div class="col-sm-12">
            @Umbraco.Field("introText")
    
            @Umbraco.RenderMacro("Login")
    
        </div>
    </div>
    

    And the Login partial view macro code:

    @inherits Umbraco.Web.Macros.PartialViewMacroPage
    
    @using System.Web.Mvc.Html
    @using ClientDependency.Core.Mvc
    @using Umbraco.Web
    @using Umbraco.Web.Models
    @using Umbraco.Web.Controllers
    
    
    @{
        // You have to set the login node ID otherwise you'll have an infinite loop if someone hits the login page first
        var loginNodeID = 1778;
        var loginModel = new LoginModel();
        var loginStatusModel = Members.GetCurrentLoginStatus();
    
        Html.EnableClientValidation();
        Html.EnableUnobtrusiveJavaScript();
        Html.RequiresJs("/umbraco_client/ui/jquery.js");
        Html.RequiresJs("/umbraco_client/Application/JQuery/jquery.validate.min.js");
        Html.RequiresJs("/umbraco_client/Application/JQuery/jquery.validate.unobtrusive.min.js");
    }
    
    @* NOTE: This RenderJsHere code should be put on your main template page where the rest of your script tags are placed *@
    @Html.RenderJsHere()
    
    @{
        var checkUrl = HttpContext.Current.Request.Url.AbsolutePath.ToString();
    
        // add a trailing / if there isn't one (you can access http://mydomain.com/login or http://mydomain.com/login/
        if(@checkUrl[checkUrl.Length - 1] != '/') {
            checkUrl = checkUrl + "/";
        }
    
        @* if we don't have a session variable and have a request URL then store it *@
        @* we have to store it because if user tries an incorrect login then Current.Request.Url will show /umbraco/RenderMvc *@
        if(HttpContext.Current.Request.Url != null && HttpContext.Current.Request.Url.AbsolutePath.ToString() != "/umbraco/RenderMvc" && HttpContext.Current.Session["redirectURL"] == null) {
            if(checkUrl != @Umbraco.Content(loginNodeID).Url) {
                HttpContext.Current.Session["redirectURL"] = HttpContext.Current.Request.Url.ToString();
            }
        }
    
        if(loginStatusModel.IsLoggedIn) {
            var redirectUrl = (string)HttpContext.Current.Session["redirectURL"];
    
            var currentUrl = HttpContext.Current.Request.Url.ToString();
            if(HttpContext.Current.Session["redirectURL"] != null) {
                // clear the session variable for future logins
                HttpContext.Current.Session["redirectURL"] = null;
                HttpContext.Current.Response.Redirect(redirectUrl);
            } else {
                // Nothing in the session so we will go home
                HttpContext.Current.Response.Redirect("/");
            }
        }
    
    
        using(Html.BeginUmbracoForm<UmbLoginController>("HandleLogin")) {
        <fieldset>
            <legend>Login</legend>
    
            @Html.ValidationSummary("loginModel",true)
    
            @Html.LabelFor(m => loginModel.Username)
            @Html.TextBoxFor(m => loginModel.Username)
            @Html.ValidationMessageFor(m => loginModel.Username)
            <br />
    
            @Html.LabelFor(m => loginModel.Password)
            @Html.PasswordFor(m => loginModel.Password)
            @Html.ValidationMessageFor(m => loginModel.Password)
            <br />
    
            <button>Login</button>
        </fieldset>
        }
    }
    

    It's just the basic login code snippets from Umbraco. I'm not doing any collection manipulations myself. Maybe there's a difference between the Umbraco versions?

    Thanks

    P.S. Actually it's the code from this post and not the bare Umbraco snippet:

    http://siempresolutions.co.uk/blog/Umbraco_Members_Protected_Area_of_Website
    
  • Andy Butland 422 posts 2334 karma points MVP 4x hq c-trib
    Oct 14, 2015 @ 12:28
    Andy Butland
    100

    Looks like you've run into this issue which has been resolved in 7.3.

    Andy

  • Craig100 1136 posts 2523 karma points c-trib
    Oct 14, 2015 @ 13:22
    Craig100
    0

    Thanks Andy, thought I was going nuts. Seems there's still some issues with Public Access in 7.3 that will be addressed in 7.3.1. I'll try an upgrade to 7.3 and see what happens. I'll report back of course ;)

    Thanks again.

  • Darren Wilson 228 posts 596 karma points
    Nov 10, 2015 @ 11:46
    Darren Wilson
    0

    Hi Folks,

    I'm using 7.3.1 and still getting errors - any news on the issue?

    Cheers Darren

  • Craig100 1136 posts 2523 karma points c-trib
    Nov 10, 2015 @ 11:54
    Craig100
    0

    Sorry for the late reply but upgrading to 7.3.0 (and now to 7.3.1) appeared to fix this for us.

  • Darren Wilson 228 posts 596 karma points
    Nov 10, 2015 @ 12:12
    Darren Wilson
    0

    Mus be something I'm doing wrong - getting a loads of errors in the log...

    2015-11-10 12:10:21,434 [P3176/D4/T87] WARN umbraco.macro - Error loading Partial View (file: ~/Views/MacroPartials/Login.cshtml). Exception: System.NullReferenceException: Object reference not set to an instance of an object. at ASP.PageViewsMacroPartialsLogin_cshtml.Execute() in c:\Users\Darren\Documents\My Web Sites\nl-community\Views\MacroPartials\Login.cshtml:line 34 at System.Web.WebPages.WebPageBase.ExecutePageHierarchy() at System.Web.Mvc.WebViewPage.ExecutePageHierarchy() at System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage) at System.Web.Mvc.RazorView.RenderView(ViewContext viewContext, TextWriter writer, Object instance) at System.Web.Mvc.BuildManagerCompiledView.Render(ViewContext viewContext, TextWriter writer) at Umbraco.Core.Profiling.ProfilingView.Render(ViewContext viewContext, TextWriter writer) at Umbraco.Web.Mvc.ControllerExtensions.RenderViewResultAsString(ControllerBase controller, ViewResultBase viewResult) at Umbraco.Web.Macros.PartialViewMacroEngine.Execute(MacroModel macro, IPublishedContent content) at Umbraco.Web.Macros.PartialViewMacroEngine.Execute(MacroModel macro, INode node) at umbraco.macro.LoadPartialViewMacro(MacroModel macro) at umbraco.macro.renderMacro(Hashtable pageElements, Int32 pageId)

  • Craig100 1136 posts 2523 karma points c-trib
    Dec 26, 2015 @ 17:28
    Craig100
    0

    When I put the code from my above post (14th Oct) on a V7.3.3 site on Azure that uses a Redis Cache I get an infinite redirect loop. Using some output debugging to the page I can see the redirectUrl is correct as are all the other session and cache data items. The page performs the login function correctly but the redirect appears to cause a loop. Have Googled this for a few days to no avail. I was wondering if anyone here can shed any light on it?

    Thanks.

  • Craig100 1136 posts 2523 karma points c-trib
    Dec 26, 2015 @ 19:01
    Craig100
    0

    Further testing has shown that Umbraco appears to be routing the redirection via the login page thus causing the loop. The issue is why does this happen on Azure but not on IIS? Is it anything to do with the mechanism for Authentication in Azure and therefore Umbraco needs to handle it differently? Just wondering aloud.

  • Craig100 1136 posts 2523 karma points c-trib
    Dec 26, 2015 @ 19:12
    Craig100
    0

    And even further testing has shown the looping was caused by the page being protected by "Role" and the user, while logging in correctly, wasn't a member of the Member Group.

    Problem solved, hope this helps some other bewildered ;)

    However, would be nice if it refused to Authenticate! Issue opened: http://issues.umbraco.org/issue/U4-7611

Please Sign in or register to post replies

Write your reply to:

Draft