Copied to clipboard

Flag this post as spam?

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


  • Hefin Jones 39 posts 161 karma points
    Feb 20, 2014 @ 12:16
    Hefin Jones
    0

    Umbraco Helper - TypedContentAtXPath

    Umbraco Version: 7.0.3

    Hello all,

    I'm currently working on a MemberLoginSurfaceController with the following action for loggin out:

       // The MemberLogout Action signs out the user and redirects to the site homepage
            [HttpGet]
            public ActionResult MemberLogout()
            {
                Session.Clear();
                FormsAuthentication.SignOut();
                var umbracoHelper = new UmbracoHelper(UmbracoContext.Current);
                var homePage = umbracoHelper.TypedContentAtXPath(".//ancestor-or-self::Homepage[@level=2 and @isDoc]").FirstOrDefault();
                return RedirectToUmbracoPage(homePage);
            }

    As you can see I am trying to redirect to the homepage of the current site, I have a structure like this:

    Content (Root)
    --- Intro page (splash page)
    ------ Home (en)
    --------- Page 1 en
    --------- Page 2 en
    --------- etc ...
    ------ Home (cy)
    --------- Page 1 cy
    --------- Page 2 cy
    --------- etc ...

    What I'm trying to do is redirect the user to the relevant homepage when loggin out, depending on which site they are viewing.  I used to be able to do this using code similar to this:

    umbraco.uQuery.GetNodesByXPath("$currentPage/ancestor-or-self::Homepage[@level=2 and @isDoc]").FirstOrDefault().Id

    But the Umbraco Helper TypedContentAtXPath doesn't seem to like $currentPage.

    Is there a way I can replicate the uQuery method using TypedContentAtXPath?

  • Matt Linsenbardt 24 posts 147 karma points
    Feb 20, 2014 @ 19:42
    Matt Linsenbardt
    0

    Hi Hefin,

    You have a couple of options using the IpublishedContent model:

    Traverse by contentTypeAlias
    Model.Content.Ancestor('Home").Url

    Traverse by level
    Model.Content.Ancestor(2).Url

    I see that you are using a surface controller. Were you able to get the ModelState errors to bubble back up to your View (e.g. login errors)?

    - Matt 

  • Hefin Jones 39 posts 161 karma points
    Feb 20, 2014 @ 21:29
    Hefin Jones
    0

    Hi Matt,

    I don't seem to have the option of using Model.Content.Ancestor("Home").Url or Model.Content.Ancestor(2).Url - I imagine that this is because I'm using a custom model?  

    public class MemberLoginModel
    {
    [Required, Display(Name = "Enter your username")]
    public string Username { get; set; }

    [Required, Display(Name = "Password"), DataType(DataType.Password)]
    public string Password { get; set; }

    [Display(Name = "Remember me")]
    public bool RememberMe { get; set; }

    In answer to your question, yes I do get the ModelState errors bubble back to my view, I call the partial view of "_MemberLogin" like this:

    @Html.Partial("_MemberLogin", new dpp.models.Shared.MemberLoginModel())

    Would this also me contributing to my issue in getting hold of the current page in the controller?  

    - Hefin

  • Matt Linsenbardt 24 posts 147 karma points
    Feb 20, 2014 @ 22:06
    Matt Linsenbardt
    0

    You can inherit from the RenderModel to gain access to the Content class.

    publicclassMemberLoginModel : Umbraco.Web.Models.RenderModel
    {
    [Required,Display(Name="Enter your username")]
    publicstringUsername{get;set;}
     
    [Required,Display(Name="Password"),DataType(DataType.Password)]
    publicstringPassword{get;set;}
     
    [Display(Name="Remember me")]
    publicboolRememberMe{get;set;}

    public MemberLoginModel() : this(UmbracoContext.Current.PublishedContentRequest.PublishedContent) {}
    public MemberLoginModel(IPublishedContent content) : base(content) {}

    }

  • Hefin Jones 39 posts 161 karma points
    Feb 21, 2014 @ 14:58
    Hefin Jones
    0

    Hi Matt - still don't get the Model.Content.Ancestor("Home").Url or Model.Content.Ancestor(2).Url.  I'm doing this in the Surface Controller .... here is my code for the Surface Controller:

    public class MemberLoginSurfaceController : SurfaceController
    {
    // The MemberLogin Action returns the view. it also instantiates a new, empty model for our view
    [HttpGet]
    [ActionName("MemberLogin")]
    public ActionResult MemberLoginGet()
    {
    return PartialView("_MemberLogin", new MemberLoginModel());
    }

    // The MemberLogout Action signs out the user and redirects to the site homepage
    [HttpGet]
    public ActionResult MemberLogout()
    {
    Session.Clear();
    FormsAuthentication.SignOut();
    return Redirect("/");
    }

    // The MemberLoginPost checks the entered credentials using the standard ASP.NET membership provider and redirects the user to the same page
    [HttpPost]
    [ActionName("MemberLogin")]
    public ActionResult MemberLoginPost(MemberLoginModel model)
    {
    if (ModelState.IsValid)
    {
    if (Membership.ValidateUser(model.Username, model.Password))
    {
    FormsAuthentication.SetAuthCookie(model.Username, model.RememberMe);
    return RedirectToUmbracoPage(Settings.LocalSettingsNode.GetPropertyValue("membersHomepage"));
    }
    else
    {
    ModelState.AddModelError("", "Login data is incorrect!");
    }
    }
    return CurrentUmbracoPage();
    }
    }

    And it's the MemberLogout() action where I'm trying to do the redirect.  So instead of having 

    return Redirect("/");

    I would like to do something like:

    return RedirectToUmbracoPage()

    But I can't seem to get it to work?

  • Matt Linsenbardt 24 posts 147 karma points
    Feb 21, 2014 @ 17:07
    Matt Linsenbardt
    0

    Hi Hefin,

    It appears to be very difficult to get the Umbraco Context from your GET as your not on a page. Perhaps it would be easier to pivot slightly and pass a url parameter to your get and redirect to that url after SignOut.

  • Hefin Jones 39 posts 161 karma points
    Mar 05, 2014 @ 17:45
    Hefin Jones
    100

    Hi Matt,

    I implemented something along those lines.  In my partial view I now have this:

    <p>@Html.ActionLink("Log out", "MemberLogout", "MemberLoginSurface", new { homePageId = dpp.library.Extensions.Settings.PageIDs.HomepageID }, null)</p>

    Which uses gets the home page of the current node from a class which returns the homepage Id:

    public static int HomepageID
    {
    get
    {
    int id = 0;
    id = umbraco.uQuery
    .GetNodesByXPath("$currentPage/ancestor-or-self::Homepage[@level=2 and @isDoc]").FirstOrDefault().Id;
    return id;
    }
    }

    Now my controller action looks like this:

    [HttpGet]
    public ActionResult MemberLogout(int homePageId)
    {
    Session.Clear();
    FormsAuthentication.SignOut();
    return RedirectToUmbracoPage(homePageId);
    }

    Might not be the perfectly correct solution but it works for me.

Please Sign in or register to post replies

Write your reply to:

Draft