Copied to clipboard

Flag this post as spam?

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


  • Saba Tandashvili 29 posts 181 karma points
    Dec 24, 2018 @ 11:01
    Saba Tandashvili
    0

    How does SurfaceController returns result to view ?

    Hi, i am making search on my website, I have search input in my home page, after submit it goes to SearchSurfaceController where i have :

    public ActionResult Search(string searchWord)
    {
        return View("Search", searchWord);
    }
    

    How can i return result to search view ? I can not do it with partialview because i can not render partialview at home page, I need render results on blank search page.

    Any ideas ?

  • Alex Skrypnyk 6175 posts 24186 karma points MVP 8x admin c-trib
    Dec 25, 2018 @ 10:50
    Alex Skrypnyk
    0

    Hello Saba

    If you need to return just data, then use UmbracoApiController - https://our.umbraco.com/documentation/reference/routing/webapi/

    SurfaceController is for returning view and data, it's MVC controller that connects data and view, returns together

    Thanks

    Alex

  • Saba Tandashvili 29 posts 181 karma points
    Dec 26, 2018 @ 07:20
    Saba Tandashvili
    0

    Hello Alex

    I don't need to return just data, i need to redirect to specific view page and pass data to it. For example when user fills search input and submits it, submit goes to my SurfaceController, where i select matched results from database, and i am stuck here, i need to return results to search.schtml, but i can not.

    You said SurfaceController is for returning view and data, then tell me how to return specific view with data ? as i searched it is not possible.

  • Marc Goodson 2157 posts 14431 karma points MVP 9x c-trib
    Dec 28, 2018 @ 10:08
    Marc Goodson
    102

    Hi Saba

    The Surface Controller is for handling form posts within the Umbraco request pipeline (and also Child Actions for displaying a partial view).

    When you handle a form post in a Surface Controller you are just validating the posted data via ModelState, and depending on the success of this you can either return

    return CurrentUmbracoPage();
    

    Which will take you back to the page you started on with the ModelState intact, eg showing any validation error messages or

    return RedirectToCurrentUmbracoPage();
    

    Which will return you back to the page you started on but with ModelState cleared.

    It isn't designed to return data to the view that you might have retrieved from a database inside the Surface Controller action.

    In theory, you could use the MVC ViewData dictionary to send data from the SurfaceController back to your template

    ViewData["searchResults"] = mySearchResults;

    but it isn't a nice pattern to work with...

    What the Surface Controller is designed to do is validate the post request and then redirect to a url that will be responsible for returning the data based on your form post criteria.

    If the alias of the document type of your search page is called 'searchPage', then you can create a new MVC controller called

    SearchPageController : RenderMvcController
    

    and override the Index action

    public ActionResult Index(RenderModel model)
        {
       return CurrentTemplate(model);
    }
    

    see https://our.umbraco.com/documentation/reference/routing/custom-controllers for more info (this is called route hijacking in Umbraco)

    Every GET request that comes in for your search page will be routed via this controller.

    You can bind additional parameters eg

        public ActionResult Index(RenderModel model, string searchQuery, int someCategoryId)
            {
    var viewModel = new MyCustomViewModel(model);
    var searchResults = MyGetSearchResultsMethod(searchQuery, someCategoryId);
    viewModel.SearchResults = searchResults;
           return CurrentTemplate(viewModel);
        }
    

    If you create your own 'ViewModel' inheriting from 'RenderModel' then you can add your own properties, during the handling of the request, and send your enriched ViewModel to your View; adjusting the inherits statement to account for your new model

    @inherits Umbraco.Web.Mvc.UmbracoViewPage<MyCustomViewModel>
    
    @foreach (var searchResult in Model.SearchResults){
    //you search results written out here
    }
    

    So your Surface Controller handles the POST of the search criteria, but you return a 'redirect' to your SearchPage, sending the posted values via the querystring eg: if your search form is on the same page as your search results return

     NameValueCollection queryString = new NameValueCollection();
                queryString["searchQuery"] = searchQuery;
                queryString["someCustomId"] = someCustomId;
                return RedirectToCurrentUmbracoPage(queryString);
    

    or if the search form isn't always on the search page then there is another helper to take you to a specific page...

     var searchPage = Umbraco.TypedContent(searchPageId);
         NameValueCollection queryString = new NameValueCollection();
                    queryString["searchQuery"] = searchQuery;
                    queryString["someCustomId"] = someCustomId;
                    return RedirectToUmbracoPage(searchPage,queryString);
    

    And then your hijacked RenderMvcController will do the work of getting the search results, (based on the criteria the SurfaceController has redirected to it) builds a custom ViewModel, and sends it to your View to display.

    Anyway hope that is enough to help you work out a way to make your search work!

    regards

    Marc

Please Sign in or register to post replies

Write your reply to:

Draft