Search Page with custom viewModel
# help-with-umbraco
p
I've created a custom viewmodel for the search page, where the SearchPageModel itself is a member of. Now when i call the page a surfaceController should take over and first fill the viewModel. In theory this should work right? Now how can i still be able to use the Layout from Umbraco as you see in the picture? Am i doing something wrong? Shouldnt i use a SurfaceController for that? Or would a ViewComponent be a better fit ?
r
What version of umbraco I take itโ€™s a dot net core one??
p
Yes, Umbraco V10
d
I'm pretty sure the line
Copy code
@inherits SearchPageViewModel
Should be one of these:
Copy code
@model SearchPageViewModel
or
Copy code
@inherits UmbracoViewPage<SearchPageViewModel>
p
What is the difference between these two?: Should be one of these: @model SearchPageViewModel or @inherits UmbracoViewPage
And would you use a RenderController or SurfaceController for something like that? When i use a RenderController the index() gets called but with a surfaceController it dont...
So @D_Inventor you we're right the Model! But now there is still a problem because i use the mastertemplate as a layout, but it does not work with the ViewModel because it needs a IPublishedContent.... Is there any way to give the layout the Model IPublishedConetnt which lays in the ViewModel
d
The difference between the two is that the latter gives access to some standard Umbraco helper objects that you commonly use, like the UmbracoHelper. It's also required to use the latter to make rich text editors render properly, although I don't know why
You'll want to use the
RenderController
as your base class for rendering content pages. That's specifically what that base class is for
The reason your layout doesn't work with the IPublishedContent model is because your model is not IPublishedContent. It's your own custom view model. You have two possibilities: 1. Use the original content model and render your content in a partial using any method you prefer. 2. Don't use IPublishedContent as your model in your layout view and instead use the line
@inherits UmbracoViewPage
and use either the Umbraco helper or the Umbraco Context to get the current page.
p
That makes totally sense for me! I will give it a try and let you know if it works! Which one of both approaches do you like more or is cleaner? For me it sounds like number 2 is cleaner.
d
Yeah, I use option 2 for my layouts as well
p
Do you have an example on how to get the current page with the helper or Context?
for me it always looks like this
and if i use the @inherits UmbracoViewPage it gives me an error which says it is no IpublishedContent
d
ah yeah, that makes sense actually. I must've been mistaken there. The UmbracoHelper needs to be instantiated through the use of the
UmbracoViewPage
class though, otherwise you can't get the assigned content item.
I have no opportunity to share any examples at the moment, A quick solution would be to inject the
IUmbracoContextAccessor
instead and use the PublishedRequest.PublishedContent property on the UmbracoContext. That should also give you the current page.
h
If you use a render controller ther is a special object that your view model can inherit from to do this. I should be back home in about an hour and will post an example
The view model
Copy code
csharp
    public class SearchViewModel : PublishedContentWrapped
    {

        public string query { get; set; }
        public string searchIn { get; set; }
        public long TotalResults { get; set; }
        public IEnumerable<IPublishedContent> PagedResult { get; set; }

        public SearchViewModel(IPublishedContent content, IPublishedValueFallback publishedValueFallback) : base(content, publishedValueFallback)
        {
        }
    }
In the view you use
@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage<SearchViewModel>
part of render controller
Copy code
csharp
    public class SearchPageController : RenderController
    {
        private readonly IPublishedContentQuery _publishedContentQuery;
        private readonly IExamineManager _examineManager;
        private readonly IVariationContextAccessor _variationContextAccessor;
        private readonly ServiceContext _serviceContext;
        public SearchPageController(ILogger<SearchPageController> logger, ICompositeViewEngine compositeViewEngine, IUmbracoContextAccessor umbracoContextAccessor, IVariationContextAccessor variationContextAccessor, ServiceContext context,IPublishedContentQuery publishedContentQuery,IExamineManager examineManager)
            : base(logger, compositeViewEngine, umbracoContextAccessor)
        {
            _variationContextAccessor = variationContextAccessor;
            _serviceContext = context;
            _publishedContentQuery = publishedContentQuery;
            _examineManager = examineManager;
        }
        public override IActionResult Index()
        {

            SearchViewModel searchPageViewModel = new SearchViewModel(CurrentPage,
                new PublishedValueFallback(_serviceContext, _variationContextAccessor))
            {
                //do the search
                query = "",
                searchIn = "",
                TotalResults = 0,
                PagedResult = null
            };

            
            // return our custom ViewModel
            return CurrentTemplate(searchPageViewModel);

        }
}
You can view the whole code here https://github.com/huwred/MediaWizForums
p
@huwred @D_Inventor The PublishedContentWrapped did the trick! Thanks a lot! I will let you know when i'm finished and show my code ๐Ÿ™‚
4 Views