pageAlias and where does it come from?

Lea Lebonski asked on December 9, 2019 01:49

Hi there,

I have experienced problems following the course materials for creation of Landing Pages. It seems that the pageAlias string parameter never populates and therefore the unique page is never found and returned. Where does the pageAlias come from? As it is not part of the DocumentQueryService or Landing Page fields. Can anybody help?

Thanks.

Correct Answer

Lea Lebonski answered on December 16, 2019 05:13

Hi there,

I got it! I feel like a right idiot as after hours of "fun" and re-creating, it was the simplest of things... my alias route was set under my default route! Doh!! So it was always being ignored... :-/ All is good now... off to the widget world...

Once again, thank you for staying with me and helping.

Thanks,

L.

0 votesVote for this answer Unmark Correct answer

Recent Answers


Juraj Ondrus answered on December 9, 2019 07:35

The Page alias you fill out in the Properties -> Page alias field is represented by the NodeAlias column in the CMS_Tree table (and in the API the property name is the same). So, based on this field also the NodeAliasPath is generated. Since the field comes from CMS_Tree table, it is shared across all culture versions of the page. The CMS_Tree table does not hold culture specific data.
What is your code like? Maybe you need to add .Columns("columns") to your query and add the NodeAlias column to the list to get its data.

0 votesVote for this answer Mark as a Correct answer

Lea Lebonski answered on December 9, 2019 10:03 (last edited on December 9, 2019 10:09)

Hi there,

thank you for your reply. I am at the end of my wits now. I feel I have tried everything and no amount of combinations leads to anything. Nice to be able to reach for help. Much appreciated. So... here is my code...

I have a DTO:

using Business.Dto;

public class LandingPageDto : IDto
{
    public int DocumentID { get; set; }

    public string Title { get; set; }

    public string NodeAlias { get; set; }
}

I have a repository:

using Business.Repository;
using Business.Services.Query;
using System.Linq;

public class LandingPageRepository : BaseRepository, ILandingPageRepository
{
    public LandingPageRepository(IDocumentQueryService documentQueryService) : base(documentQueryService)
    {
    }

    public LandingPageDto GetLandingPage(string pageAlias)
    {
        return DocumentQueryService.GetDocument<CMS.DocumentEngine.Types.TSY.LandingPage>(pageAlias)
            .AddColumns("LandingPageName")
            .TopN(1)
            .ToList()
            .Select(landingPage => new LandingPageDto()
            {
                DocumentID = landingPage.DocumentID,
                NodeAlias = landingPage.NodeAlias,
                Title = landingPage.LandingPageName
            })
            .FirstOrDefault();
    }
}

I have added NodeAlias to the DocumentQueryService like so:

using System;
using System.Linq;
using CMS.DocumentEngine;
using Business.Services.Context;

namespace Business.Services.Query
{
    public class DocumentQueryService : BaseService, IDocumentQueryService
    {
        private ISiteContextService SiteContext { get; }

        private readonly string[] _coreColumns =
        {
            // Defines initial columns returned for optimization. If not set, all columns are returned.
            "NodeGUID", "DocumentID", "NodeID", "NodeAlias"
        };

        public DocumentQueryService(ISiteContextService siteContext)
        {
            SiteContext = siteContext;
        }

        public DocumentQuery<TDocument> GetDocument<TDocument>(Guid nodeGuid) where TDocument : TreeNode, new()
        {
            return GetDocuments<TDocument>()
                .TopN(1)
                .WhereEquals("NodeGUID", nodeGuid);

        }

        public DocumentQuery<TDocument> GetDocuments<TDocument>() where TDocument : TreeNode, new()
        {
            var query = DocumentHelper.GetDocuments<TDocument>();

            // Loads the latest version of documents as preview mode is enabled
            if (SiteContext.IsPreviewEnabled)
            {
                query = query
                    .Columns(_coreColumns.Concat(new[] { "NodeSiteId" })) // Sets initial columns returned for optimization.
                                                                          //Adds 'NoteSiteD' column required for the Preview mode.
                    .OnSite(SiteContext.SiteName) // There could be more sites with matching documents
                    .LatestVersion()
                    .Published(false)
                    .Culture(SiteContext.PreviewCulture);
            }
            else
            {
                query = query
                    .Columns(_coreColumns) // Sets initial columns returned for optimization.
                    .OnSite(SiteContext.SiteName) // There could be more sites with matching documents
                    .Published()
                    .PublishedVersion()
                    .Culture(SiteContext.CurrentSiteCulture);
            }

            return query;
        }

        public DocumentQuery<TDocument> GetDocument<TDocument>(string pageAlias) where TDocument : TreeNode, new()
        {
            return GetDocuments<TDocument>()
                .TopN(1)
                .WhereEquals("NodeAlias", pageAlias);
        }
    }
}

Then my controller:

using Business.DependencyInjection;
using Kentico.PageBuilder.Web.Mvc;
using Kentico.Web.Mvc;
using System;
using System.Web.Mvc;
using ###.Controllers;

public class LandingPageController : BaseController
{
    protected ILandingPageRepository LandingPageRepository { get; }

    public LandingPageController(
        IBusinessDependencies dependencies, ILandingPageRepository landingPageRepository) : base(dependencies)
    {
        LandingPageRepository = landingPageRepository ?? throw new ArgumentNullException(nameof(landingPageRepository));
    }

    // GET: LandingPage/[nodeAlias]
    public ActionResult Index(string nodeAlias)
    {
        var landingPageDto = LandingPageRepository.GetLandingPage(nodeAlias);

        //if (landingPageDto == null)
        //{
        //    return HttpNotFound();
        //}

        var model = GetPageViewModel(landingPageDto.Title);
        HttpContext.Kentico().PageBuilder().Initialize(landingPageDto.DocumentID);

        return View(model);
    }
}

And finally the view:

@using Kentico.PageBuilder.Web.Mvc
@using Kentico.Web.Mvc


<div class="section">
    <div class="container">
        <div class="kn-system-messages"></div>
        @Html.Kentico().EditableArea("top")
    </div>
</div>

@section Styles {
    @Html.Kentico().PageBuilderStyles()
}

@section Scripts {
    @Html.Kentico().PageBuilderScripts()
}

Any help will be much appreciated. I feel I am close but missing a vital bit... I am sure someone can help me to get to that "Eureka!" moment and help me to understand it all better.

Thanks a lot. It is really appreciated.

0 votesVote for this answer Mark as a Correct answer

Roman Hutnyk answered on December 9, 2019 15:43

When you say "It seems that the pageAlias string parameter never populates and therefore the unique page is never found and returned" - where it does not populate? - In controller Index action? - if so then it is not passed there with the request: it should be passed through URL parameter and appropriate routing has to be configured.

0 votesVote for this answer Mark as a Correct answer

Lea Lebonski answered on December 9, 2019 23:12 (last edited on December 10, 2019 10:39)

Hi there, yes it always throws a null exception in the Controller. I suspect you are right. Problem is I can not see where is the pageAlias request made. I can see the culture requests happening in SiteContextService but there is only a getter for SiteName and nothing else...

My route is:

    route = routes.MapRoute(
        name: "LandingPage",
        url: "{culture}/LandingPage/{nodeAlias}",
        defaults: new { culture = defaultCulture.Name, controller = "LandingPage", action = "Index" },
        constraints: new { culture = new SiteCultureConstraint(AppConfig.Sitename), nodeAlias = new OptionalRouteConstraint(new RegexRouteConstraint(@"[\w\d_-]*")) }
    );

The URL pattern in my Landing Page Type is:

/{%DocumentCulture%}/LandingPage//{%NodeAlias%}

and the 404 error I am getting is as follows:

Requested URL http://localhost:80/Kentico12_6_TSY/cmsctx/pv/administrator/culture/en-GB/wg/efee0585-19b1-4bd6-9034-8e5f565fc8e7/readonly/0/pts/637115297469557087/ea/1/h/0ed6710588316fc474e4d7e0f7a5eb470d27cd2efa1fda3ecdb1e0b044c54960/-/en-gb/landingpage/seniorpass?instance=f7031a29-8fc1-465b-a3dd-963b53f98533&uh=b99ef9d685978f1603eb20db0f9591cbe2345fcc3a45f7b197feeb6424392e88&editmode=1&administrationUrl=http%3A%2F%2Flocalhost%2FKentico12_6_Admin Physical Path C:\inetpub\wwwroot\Kentico12_6\TSY\cmsctx\pv\administrator\culture\en-GB\wg\efee0585-19b1-4bd6-9034-8e5f565fc8e7\readonly\0\pts\637115297469557087\ea\1\h\0ed6710588316fc474e4d7e0f7a5eb470d27cd2efa1fda3ecdb1e0b044c54960-\en-gb\landingpage\seniorpass Logon Method Anonymous Logon User Anonymous Request Tracing Directory C:\inetpub\logs\FailedReqLogFiles

Thanks again.

0 votesVote for this answer Mark as a Correct answer

Juraj Ondrus answered on December 10, 2019 09:22

Could you please install, if not done yet, the sample Dancing Goat MVC project and compare your code with it? I do not see anything outstanding in your code. I guess it will be something simple and small somewhere. E.g. check the Article related controller, model and view. It is always a good idea to have the sample project ready so you can do a quick comparison.

0 votesVote for this answer Mark as a Correct answer

Lea Lebonski answered on December 11, 2019 13:45

Hi there,

thank you. I have got the Dancing Goat installed and have referred to it. However, I still can't find the issue. The Page is created in the admin interface but I get 404 error when browsing to it with a null exception at LandingPage controller in the Index action.

Thanks,

Lucia

0 votesVote for this answer Mark as a Correct answer

Juraj Ondrus answered on December 12, 2019 08:11

I assume the cultures are set to en-gb for all your pages and this is also your default culture, right? I guess the URL pattern you posted has just a typo here with the double slashes and they actually are not in the real URL pattern value.

0 votesVote for this answer Mark as a Correct answer

Lea Lebonski answered on December 12, 2019 14:12

Hi,

thank you for staying with me on this. Yes all cultures are set to the en-GB to the extent where the en-US culture has been completely removed in the Sites application. And yes it was a typo sorry. It is:

/{%DocumentCulture%}/LandingPage/{%NodeAlias%}

Thanks again,

Lucia

0 votesVote for this answer Mark as a Correct answer

Juraj Ondrus answered on December 13, 2019 09:50

Would it be possible to submit a support ticket and provide us with the backups of the MVC and Kentico projects as well as with the DB backup? There is something strange going on and I guess it will be something small a simple we are overlooking.

0 votesVote for this answer Mark as a Correct answer

Juraj Ondrus answered on December 16, 2019 07:07

Thanks for the follow up. I would never thought about this! Lesson learnt! :-)

0 votesVote for this answer Mark as a Correct answer

   Please, sign in to be able to submit a new answer.