Copied to clipboard

Flag this post as spam?

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


  • David 26 posts 196 karma points
    May 28, 2020 @ 12:25
    David
    0

    Umbraco v8 ModelsBuilder Issues

    I am trying to setup a login facility for members on my umbraco site, but am having issues when rendering the view.

    Here is some information on my setup:

    Umbraco version: 8.6.1

    Modelsbuilder mode: PureLive

    Doc Type: accountLogin

    Model:

        public class CustomerLogin 
    {
        public CustomerLogin()
        {
            ViewData = new MembershipViewData();
        }
    
        [Required(ErrorMessage = "Username is required.")]
        [Display(Name = "User Name")]
        public string Username { get; set; }
    
        [Required(ErrorMessage = "Password is required.")]
        [Display(Name = "Password"), DataType(DataType.Password)]
        public string Password { get; set; }
    
        [Display(Name = "Remember Me")]
        public bool RememberMe { get; set; }
    
        public string SuccessRedirectUrl { get; set; }
        public MembershipViewData ViewData { get; set; }
    }
    

    Controller

    public class AccountLoginController : SurfaceController
    {
        public ActionResult LoginForm(string view = "")
        {
            var model = new CustomerLogin { RememberMe = true };
            return view.IsNullOrWhiteSpace() ? PartialView(model) : PartialView(view, model);
        }
    
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Login(CustomerLogin model)
        {
            if (!ModelState.IsValid) return CurrentUmbracoPage();
    
            if (!Members.Login(model.Username, model.Password))
            {
                var member = Members.GetByUsername(model.Username);
                var viewData = new MembershipViewData { Success = false };
    
                if (member == null)
                {
                    viewData.Messages = new[] { "Account does not exist for this email address." };
                }
                else
                {
                    var messages = new List<string>
                    {
                        "Login was unsuccessful with the email address and password entered."
                    };
    
                    if (!member.Value<bool>("umbracoMemberApproved")) messages.Add("This account has not been approved.");
                    if (member.Value<bool>("umbracoMemberLockedOut")) messages.Add("This account has been locked due to too many unsuccessful login attempts.");
    
                    viewData.Messages = messages;
                }
    
                TempData["LoginModel"] = viewData;
                return CurrentUmbracoPage();
            }
    

    View: (Partial View)

    @inherits UmbracoViewPage<CustomerLogin>
    
    @using PriceBeater.Models.Membership;
    @using PriceBeater.Controllers;
    
    
    @{
        Model.SuccessRedirectUrl = "/Account";
        MembershipViewData result = (MembershipViewData)TempData["LoginModel"];
    }
    
    @using (Html.BeginUmbracoForm<AccountLoginController>("Login"))
    {
        @Html.AntiForgeryToken()
        <div class="form-group">
            @Html.LabelFor(x => x.Username)
            @Html.TextBoxFor(x => x.Username, new { @placeholder = "Your email address", @class = "form-control" })
            @Html.ValidationMessageFor(x => x.Username)
        </div>
        <div class="form-group">
            @Html.LabelFor(x => x.Password)
            @Html.PasswordFor(x => x.Password, new { @placeholder = "Your password", @class = "form-control" })
            @Html.ValidationMessageFor(x => x.Password)
        </div>
        <div class="form-group ">
            @Html.HiddenFor(x => x.SuccessRedirectUrl)
            <input type="submit" value="Login" class="btn btn-default pull-right" />
        </div>
    
    }
    

    Template Page

    @inherits Umbraco.Web.Mvc.UmbracoViewPage
    
    @{
        Layout = "priceBeater.cshtml";
    }
    
    <section>
        <div class="container">
            <h1>Login</h1>
            <p>Currently not a member? Go to our <a href="/Register">Registration page</a>.</p>
    
            <div class="row">
                <div class="col-md-8">
                    @Html.Partial("~/Views/Partials/Forms/LoginForm.cshtml")
                </div>
            </div>
        </div>
    </section>
    

    Going round in circles here, getting messages like the following:

    "Cannot bind source type Umbraco.Web.PublishedModels.AccountLogin to model type PriceBeater.Models.Membership.CustomerLogin. The source is a ModelsBuilder type, but the view model is not. The application is in an unstable state and should be restarted."

    I am using the following youtube resource to get this facility set up. youtube video

    Can anyone suggest where I am going wrong? If more information is required please let me know.

    Much appreciated.

  • Joep 70 posts 469 karma points
    May 29, 2020 @ 09:09
    Joep
    0

    Hi,

    Well this isn't an ModelsBuilder issue probably. Somewhere in your code it is giving an AccountLogin model where you expect a CustomerLogin model.

    Can you give more information on what step in the login flow it is giving this error?

    -Joep

  • David 26 posts 196 karma points
    May 29, 2020 @ 15:35
    David
    0

    Here is my "accountLogin" doctype:

    DocType

    Here is my site structure, "logintest" is the page that uses the above doctype. It also uses the template "accountLogin" which the login form partial is rendered within.

    SiteStructure

    Here is my site file structure. (see below) and the code for the model/controller/view are supplied in my post above.

    Site File Structure

    I am receiving the error received in my initial post when just trying to navigate to the "logintest" page.

    If there is any further information required please let me know. Any help on this will be much appreciated as cannot seem to grasp where I am going wrong.

  • Joep 70 posts 469 karma points
    May 29, 2020 @ 15:44
    Joep
    0

    Hi,

    In your login partial, you should set the @inherits UmbracoViewPage to @model CustomerLogin.

    And where you call the partial, you should give a new CustomerLogin().

    Let me know how it went!

    -Joep

  • David 26 posts 196 karma points
    May 29, 2020 @ 18:08
    David
    0

    I will give this a go later and let you know. In the meantime why couldn’t I use @inherits UmbracoViewPage

    Please can you explain this umbracoviewpage and why it won’t work in this case?

    Much appreciated by the way in your fast response!

  • Joep 70 posts 469 karma points
    May 29, 2020 @ 18:20
    Joep
    100

    Hi,

    Well the issue is not that you are using UmbracoViewPage, but what you are using as the model of that view. You are trying to render a partial with the AccountLogin model, but in the partial view you expect the CustomerLogin.

    @Html.Partial("/Views/Partials/Forms/LoginForm.cshtml", new CustomerLogin())
    

    So sorry for the confusion in my answer before. I think that UmbracoViewPage should also work in the partial, but then with the CustomerLogin model. You are gonna have to test that out.

    -Joep

  • David 26 posts 196 karma points
    Jun 02, 2020 @ 08:09
    David
    0

    Thanks for this Joep. The changes you suggested has worked a treat. Much appreciated!

Please Sign in or register to post replies

Write your reply to:

Draft