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

Alloy MVC with Optimizely Graph Client walkthrough issue

Vote:
 

Hi, I have been folllowing this walkthrough

https://docs.developers.optimizely.com/platform-optimizely/v1.4.0-optimizely-graph/docs/alloy-mvc-with-optimizely-graph-zeroql-copy

successfully up until this part: 

https://docs.developers.optimizely.com/platform-optimizely/v1.4.0-optimizely-graph/docs/alloy-mvc-with-optimizely-graph-zeroql-copy#update-searchpagecontroller-in-controller-folder-to-use-optimizely-query

When I update my code I get a number of errors, e.g. "The type or namespace LocaleSerializer cannot be found, are you missing a using directive or an assembly reference?" etc etc.  There is also a ViewModel in the Alloy project called "SearchContentModel" that is missing some properties that are being referenced by the new code just pasted, i.e. "SearchFacet" and "Facets". Finally it looks like "GraphQueryBuilder" in the namespace "EPiServer.ContentGraph.Api.Querying" is missing some properties being referenced in the pasted code,  namely "ProxyModels" and "Facet". 

Usually I can figure out what is wrong and how to fix it, but I am at a loss in this case. 

Does anyone know how to solve this?

Thanks

Chris

#329820
Sep 13, 2024 16:24
Vote:
 

Hi Chris,

I have just gone through this guide myself and can confirm that I also get the same issues, however I have managed to resolve the issues as follows (these are missing steps from the guide):

Creating the proxy models

On the step where it says to run the following:

dotnet ogschema appsettings.json

Firstly you need to make sure that you have added the following to your appsettings.json file making surwe you add your AppKey, Secret and Single Key

  "Optimizely": {
    "ContentGraph": {
      "GatewayAddress": "https://cg.optimizely.com",
      "AppKey": "",
      "Secret": "",
      "SingleKey": "",
      "AllowSendingLog": "true",
      "SyncReferencingContents": "true"
    }
  }

Then I ran the following command in a windows terminal in the root of the project:

dotnet ogschema appsettings.json "Z:\Learning\ContentGraph\AlloyMvcGraphQL\ContentGraph\Models\ProxyModels.generated.cs" default "AlloyMvcGraphQL.Content.Models"

This command should run successfully and will create your proxy models in a folder of the solution called ContentGraph/Models with a class name of ProxyModels.generated.cs

Updated SearchContentModel class

using AlloyMvcGraphQL.Models.Pages;

namespace AlloyMvcGraphQL.Models.ViewModels;

public class SearchContentModel : PageViewModel<SearchPage>
{
    public SearchContentModel(SearchPage currentPage)
        : base(currentPage)
    {
    }

    public bool SearchServiceDisabled { get; set; }

    public string SearchedQuery { get; set; }

    public int NumberOfHits { get; set; }

    public IEnumerable<SearchHit> Hits { get; set; }

    public IEnumerable<SearchFacet> Facets { get; set; }

    public class SearchHit
    {
        public string Title { get; set; }

        public string Url { get; set; }

        public string Excerpt { get; set; }
    }

    public class SearchFacet
    {
        public string Name { get; set; }
        public int Count { get; set; }
    }
}

Updated SearchPageController class

namespace AlloyMvcGraphQL.Controllers;

using AlloyMvcGraphQL.Models.ViewModels;
using EPiServer.ContentGraph.Api.Querying;
using EPiServer.ContentGraph.Extensions;
using Microsoft.AspNetCore.Mvc;

public class SearchPageController : PageControllerBase<Models.Pages.SearchPage>
{
    private readonly GraphQueryBuilder _contentGraphClient;

    public SearchPageController(GraphQueryBuilder contentGraphClient)
    {
        _contentGraphClient = contentGraphClient;
    }

    public ViewResult Index(Models.Pages.SearchPage currentPage, string q)
    {
        var searchHits = new List<SearchContentModel.SearchHit>();
        var total = 0;
        var facets = new List<SearchContentModel.SearchFacet>();
        if (q != null)
        {
            var result = _contentGraphClient
                .OperationName("Alloy_Sample_Query")
                .ForType<AlloyMvcGraphQL.Content.Models.SitePageData>()
                .Fields(_ => _.Name, _ => _.Url, _ => _.MetaDescription)
                .Facet(_ => _.ContentType)
                .Total()
                .GetResultAsync<AlloyMvcGraphQL.Content.Models.SitePageData>().Result;

            var searchWords = q.Split(" ");
            foreach (var item in result.Content.Hits)
            {
                searchHits.Add(new SearchContentModel.SearchHit()
                {
                    Title = item.Name,
                    Url = item.Url,
                    Excerpt = item.MetaDescription.Length <= 500
                        ? item.MetaDescription
                        : item.MetaDescription.Substring(0, 500)
                });
            }

            facets = result.Content.Facets["ContentType"].Select(x => new SearchContentModel.SearchFacet
            {
                Name = x.Name,
                Count = x.Count
            }).ToList();
            total = result.Content.Total;
        }

        var model = new SearchContentModel(currentPage)
        {
            Hits = searchHits,
            NumberOfHits = total,
            Facets = facets,
            SearchedQuery = q
        };

        return View(model);
    }
}

Let me know how you get on with these changes.

#330163
Sep 18, 2024 7:47
Vote:
 

Hi Graham, thanks for taking the time to run through this, and coming up with this solution.

I think I followed your directions but I must have done something wrong. I end up with these errors:

Severity	Code	Description	Project	File	Line	Suppression State

Error (active)	CS0234	The type or namespace name 'SitePageData' does not exist in the namespace 'AlloyMvcGraphQL.Content.Models' (are you missing an assembly reference?)	AlloyMvcGraphQL	C:\Apps\Optimizely\ContentGraph\AlloyMvcGraphQL\Controllers\SearchPageController.cs	26
	
Error (active)	CS0121	The call is ambiguous between the following methods or properties: 'TypeQueryBuilder<T>.Facet(Expression<Func<T, DateTime>>)' and 'TypeQueryBuilder<T>.Facet(Expression<Func<T, bool>>)'	AlloyMvcGraphQL	C:\Apps\Optimizely\ContentGraph\AlloyMvcGraphQL\Controllers\SearchPageController.cs	28
	
Error (active)	CS0234	The type or namespace name 'SitePageData' does not exist in the namespace 'AlloyMvcGraphQL.Content.Models' (are you missing an assembly reference?)	AlloyMvcGraphQL	C:\Apps\Optimizely\ContentGraph\AlloyMvcGraphQL\Controllers\SearchPageController.cs	30	

I did not have a folder named "Content" in my project structure but went ahead and used that namespace anyway.

It seems that "SitePageData" is not in the generated proxy classes file, but only exists in the original location of \Models\Pages ?

I tried changing the code in the "ViewResult" method of "SearchPageController" to use this only definition, but then there are errors on 

"_.Url" and "_.ContentType".

Not sure what I am doing wrong. 

Thanks,

Chris

#330186
Sep 18, 2024 18:26
* 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.