November Happy Hour will be moved to Thursday December 5th.

Get property value of user given page and property

Vote:
 

I need to get the property value for user given property of user given page in episerver... for that i write a method..

 public string GetContent(string pageName, string propertyName)
    {
        var contentTypeRepo = ServiceLocator.Current.GetInstance();
        IEnumerable allPageTypes = contentTypeRepo.List();
        var currentpage = allPageTypes.Where(x => x.Name.ToLower() == pageName);
        var pageId = currentpage.First().ID;
        var pageRef = new PageReference(pageId);
        var contentRepository = ServiceLocator.Current.GetInstance();
        var page = contentRepository.Get(pageRef);
        var content = page.GetPropertyValue(propertyName);
        return content;
    }

But I can not get the correct page by pageType ID...it is get some other page ....so this is what my requirement... user given page name and property name and the get method will return corresponding property value... Thanks.....

#185572
Nov 24, 2017 12:27
Vote:
 

Hi, Mogi,

It seems that you have mixed up pages and page types.

This piece of code:

var contentTypeRepo = ServiceLocator.Current.GetInstance<IContentTypeRepository>();
IEnumerable<ContentType> allPageTypes = contentTypeRepo.List();
var currentpage = allPageTypes.Where(x => x.Name.ToLower() == pageName);

whereas you are actually accepting a pageName parameter and trying to use this as a current page. Just to illustrate, the variable name would be in this case currentPageType, not currentPage.

To find a page by its name and property value, I would suggest using Episerver Find (that's by far fastest). Do you have Episerver Find? If not so, you either use FindPagesWithCriteria, but do cache the result. If you know where exactly the page is, ex. under a specific parent, then you can find it using IContentLoader. However, it feels like this would be a better candidate for FindPagesWithCriteria.

BR,
Marija

#185620
Nov 27, 2017 22:17
Vote:
 

Hi Marija, i am used epi Find and using FindPageWithCriteria by PropertyCriteriaCollection and both will not give my desired result..

Epi Find I used this code..,,

int contentTypeId = 16;

var data = SearchClient.Instance.Search<IContent>()
 .Filter(x => x.ContentTypeID.Match(contentTypeId))
 .GetContentResult(); 

AND this will throw the exception " The remote name could not be resolved: 'your_uri' "

AND the Find Page With Criteia that will give " Null " .....

code for findpagewithcriteria is ,

var criterias = new PropertyCriteriaCollection
{
new PropertyCriteria()
{
Name = "StartPage",
Type = PropertyDataType.PageType,
Condition = CompareCondition.Equal,
Value = pageId.ToString(),
Required = true
}
};

var repository = ServiceLocator.Current.GetInstance<IPageCriteriaQueryService>();

var pages = repository.FindPagesWithCriteria(
PageReference.StartPage,
criterias);

so both are not working....could you please help me to get rid of this....and give solution to find the desired result for me?

Thanks for ur support.

#185636
Nov 28, 2017 12:46
Vote:
 

Hi, Mogi,

If you are already using Episerver Find, you should have an index. The error you are getting looks like that in web.config the path to the index is actually set to your_uri (which is a default value when you add Find through nuget). If your customer has paid for Find, you can get a developer index https://find.episerver.com/

As for the other piece of code, it's again a matter of naming that confuses me (you are looking by page type, it seems, but you name the parameter pageId and the post as well, which makes me think you might be looking for a page instead). Are you looking for all pages of a specific type? In that case, take a look at Jon's postThis should work:

var pageTypeId =  ServiceLocator.Current.GetInstance<ContentTypeRepository>()
        .Load<StartPage>()
        .ID;

    var criteria = new PropertyCriteria
    {
        Condition = CompareCondition.Equal,
        Name = "PageTypeID",
        Type = PropertyDataType.PageType,
        Value = pageTypeId,
        Required = true
    };

Anyway, try this code, it will give you all start pages. If you have an Id, just use the id.

Hope this helps,

Marija

#185676
Nov 29, 2017 16:44
Vote:
 

Thanks for you help Marija....

Regards,

Mogi

#185697
Nov 30, 2017 4:18
Vote:
 

Mogi, that function are going to possible be very very slow. Might work okey with a small amount of pages but not with more.

Lets go back to the base question.

First explain to me why you need a function that returns a property value by specifying only "Page Name" and "Property Name"?

In what senario are you going to use it?

#185716
Nov 30, 2017 10:36
Vote:
 

Hi Henrik....I don't know why you are saying this function is very slow...first of all explain me that...

and then i need to create a function which is get the page name and property name and return the property value.....this is my use case henrik....

Thanks.

#185764
Dec 01, 2017 7:58
Vote:
 

I will explain that soon.

But that is not a use case, that is an function definition.
A use case would be more like:

As an editor I need to be able to save setting-values that should be accessible from all site

Who and how are you going to use that function?

#185765
Dec 01, 2017 8:26
Vote:
 

This code will do the same as your function will do, but use more built in stuff.

I would still not have used it, at least not without cache'ing and also with a little more checks on access rights (FilterForVisitor) depending on the usage of the function.

I have created this in a Alloy project inside the existing file ContentLocator if you like to try it out (BUT!!!! Please add cacheing if you use it in production)

public string GetPropertyValueByPageNameAndPropertyName(string pageName, string propertyName)
        {
            var criteria = new PropertyCriteriaCollection
            {
                new PropertyCriteria()
                {
                    Name = "PageName",
                    Type = PropertyDataType.String,
                    Condition = CompareCondition.Equal,
                    Value = pageName
                }
            };
            
            var pages = _pageCriteriaQueryService.FindPagesWithCriteria(ContentReference.StartPage, criteria);

            if (pages != null && pages.Count > 0)
            {
                return pages[0].GetPropertyValue(propertyName);
            }

            return string.Empty;
        }
#185771
Dec 01, 2017 9:21
Vote:
 

Hi Henrik...I have tried your code..but in this you miss to create an instance for "IPageCriteriaQueryService" ... but i create that instance and still the code you are given is not working..

the pages is still count = 0 only.....

#185779
Dec 01, 2017 12:50
Vote:
 

and also i tried querying filter in Find also.....i tried all those methods and nothing works....that's why i choosen this method which is i written in my answer....

#185780
Dec 01, 2017 12:55
Vote:
 
public string GetContent(string pageName, string propertyName)
        {
            // Defining "content" variable as null for holding propery value
            string content = string.Empty;
            try
            {
                // Perform the operation only if the page and property names are given
                if (!(pageName == null && propertyName == null))
                {
                    // logging the information about the requested page and property
                    log.DebugFormat("GetContent Method is called for getting property value for the page = {0} and property = {1}", pageName, propertyName);

                    // Creating instance for "ContentTypeRepository" class by ServiceLocator - dependency injection
                    IContentTypeRepository contentTypeRepository = ServiceLocator.Current.GetInstance<IContentTypeRepository>();

                    // Getting all the PageTypes as the list in the site
                    IEnumerable<ContentType> allPageTypes = contentTypeRepository.List().OfType<PageType>();

                    // Creating instance for "ContentModelUsage" class by ServiceLocator - dependency injection
                    IContentModelUsage contentModelUsage = ServiceLocator.Current.GetInstance<IContentModelUsage>();

                    // "pageInstanceCollection" list for storing all the page instances of the site
                    IList<ContentUsage> pageInstanceCollection = new List<ContentUsage>();

                    // Loop through all PageTypes for getting their page instances
                    foreach (ContentType pageType in allPageTypes)
                    {
                        // Storing the page instances of the particular PageType into "pageInstances" list
                        IList<ContentUsage> pageInstances = contentModelUsage.ListContentOfContentType(pageType);

                        // Loop through the "pageInstances" list for storing all the page instances into "pageInstanceCollection" list
                        foreach (ContentUsage pageInstance in pageInstances)
                        {
                            // Storing all the page instances of the site into "pageInstanceCollection" list
                            pageInstanceCollection.Add(pageInstance);
                        }
                    }

                    // Selecting the requested page instance from the "pageInstanceCollection" list by matching the page name
                    IEnumerable<ContentUsage> requstedPageInstance = pageInstanceCollection.Where(x => x.Name.ToLower() == pageName.ToLower());

                    // Proceed only there is requstedPageInstance is available
                    if (!(requstedPageInstance == null))
                    {
                        // Getting the page id of the requested page
                        int pageId = requstedPageInstance.First().ContentLink.ID;

                        // Creating a page reference by the page id
                        PageReference pageReference = new PageReference(pageId);

                        // Creating instance for "ContentLoader" class by ServiceLocator - dependency injection
                        IContentLoader contentLoader = ServiceLocator.Current.GetInstance<IContentLoader>();

                        // Getting the actual requested page
                        PageData requstedPage = contentLoader.Get<PageData>(pageReference);

                        // Getting the corresponding property value
                        content = requstedPage.GetPropertyValue(propertyName);
                    }
                }
            }

            // catch block for catch and handle the exception if occurs
            catch (Exception exception)
            {
                // Storing the Message of an exception in a string variable
                string errorMessage = string.Format("Error in Content Retrieval : {0}", exception.Message);

                // Logging the error with the error message
                log.Error(errorMessage, exception);
            }

            // Returning the property value
            return content;
        }

and finally this is what will give you correct answer for the question i have asked...

#185781
Dec 01, 2017 12:58
Vote:
 

Strange that it did not work for you, it worked for me when I tried in Alloy.

I wrote the code in Alloy and that service is injected through construtor injection.

The reason your code is going to be a performance problem is this

You first loop through all contenttypes that exists on the site and then for each of those you get all content that exists for that contenttype.

That will give you a list with every content that exists on the site and that will on a big site first take up a lot of space in the working memory and it also can take time to do the looping.

After that you filter out all pages with that pagename (could be multiple) and after that you try to get the property if it exist on that page.

This looping you will do for every request to the function and that is not a good thing to do.

I would still argue that there must be some better way to get to the core thing, this feels like shooting flies with a cannon.

#185787
Dec 01, 2017 14:14
Vote:
 

This is a strange request and could be a "good" example of bad practice.

Why having a function like this? why name? in what context are you using this? Is it as a web api? why not use ContentReferenceID and return the whole page? seem no logic in this, would you ask for a pagename with one property and one other pagename with another property? How are u using Episerver CMS?

I would recommend Mogi to learn more / go an cource about Episerver where you learn how to in a best practice way. Delivering bad code just to solve the problem will get back to you. And give Episerver a bad will.

So please Moby, explain how is this function used? help us help u.

#185805
Dec 01, 2017 15:21
This topic was created over six months ago and has been resolved. If you have a similar question, please create a new topic and refer to this one.
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.