Copied to clipboard

Flag this post as spam?

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


  • CodeCaster 6 posts 27 karma points
    Apr 29, 2013 @ 20:04
    CodeCaster
    0

    Umbraco - MVC integration

    We have two applications: 

    • An Umbraco 6.0.2 site, developed by a third party, over which we have full control. This site is filled with document types, templates (aspx) and content.
    • An ASP.NET MVC 4 application, developed by ourselves, basically a search form (with AJAX autocomplete) and a results page, using Razor (cshtml). 
    Now I'm doing some research on how to integrate the two. We want to show our MVC search form and the search results (two MVC partials) on a publicly visible Umbraco page (node?), not having to host or expose the MVC application itself.
    I understood this can be done, but I'm lost at how. We're having trouble determining the correct approach for this and would like some advice.

     

    How to render?
    Like said above, we want to render a form and a list of search results on an Umbraco page. Ultimately we'd love to do this as partials, so we can drop the "simple search" view (a single textbox and submit button) anywhere and let it post to the advanced search form (multiple textboxes with autocomplete). How to set this up?
    This would look like a job for a macro or partial, but as far as we could grok, the creation of a macro or partial does not run the controller action, which we do need. We cannot simply render a partial, the action method's logic, that is in the controller, has to be executed (it offloads the search query to a WCF service). 

     

     

    What controller? RenderMvcController?
    I tried extending our controller, let's call it `MySearchController`, from `Umbraco.Web.RenderMvcController`. Then I defined a Document Type `MySearch` and a template `SearchForm` and created a node called `MvcSearch`. This worked, up until the part where I tried to set its parent template to our master template, and found you can't use an aspx masterpage as Razor template. 
    Can this part solely be solved by recreating the masterpage as a cshtml template? Then we have to inform our third party they'd have to adjust all their templates to be Razor, or maintain two main templates (one aspx masterpage, one cshtml). Don't like that idea. 
    But then I read about the SurfaceController, which allows for something that looks like "User Control in ASP.Net web forms". Sounds nice, but we could not get this to work yet. Is this the way to go though, then please let us know.

     

     

    AJAX, routes and redirection
    At last we were having trouble determining the URL to let our AJAX client (on the advanced search form) send its request to. As the autocomplete logic is also in the `MySearchController`, how do we "route" the request from Umbraco (say, /autocomplete.aspx?term=)? Do we have to hijack the route? How do we then link this route to the `MySearchController`'s `AutoComplete` action method? 
    Finally our "simple search", that takes one input, merely redirects to the advanced search, placing the input term in the advanced search's "Search term" input box. When calling `RedirectToRoute()` in the controller, it logically claims it cannot find a route for that, as we have never defined such a route in Umbraco. Do we have to, and if so, how?

     

     

    Lost
    There's so many blogs (with so many funny pictures) that all explain a tiny portion of the available technologies, but we cannot figure out what bits to use when. Can anybody please shed a light on this? It will be duly appreciated. 

     

  • Funka! 398 posts 661 karma points
    Jun 14, 2013 @ 02:32
    Funka!
    0

    A beautiful, well-written post asking pretty much most of the same questions I've been struggling with over these last two weeks. A shame there weren't any replies!

  • CodeCaster 6 posts 27 karma points
    Jun 14, 2013 @ 10:02
    CodeCaster
    0

    @Funka!, sorry I didn't come back with my findings, but I didn't feel like it because of the zero replies.

    We have accomplished this. 

    You have to create a controller that inherits from SurfaceController, whose action methods return PartialView(yourmodel) without layout:

    public class FooSurfaceController : SurfaceController
    {
    public ActionResult YourBarMethod(YourModel model)
    {
    // do stuff
    return PartialView(modelOrOtherModel);
    }
    }

    (Retarded forum software). Then just create a view with your own model.

    Now dump only your project binary in Umbraco's bin folder, as the MVC binaries are already present there (but beware if you use log4net, you'll have to reference Umbraco's version and not the NuGet version as that will break stuff), and put the views in Umbraco's Views folder.

    You can now directly call your controller using the URL: /umbraco/Surface/FooSurface/YourBarMethod, to see whether everything works.

    If it does, you can now render this as a partial on an existing Umbraco (.cshtml! not masterpage) template:

    @inherits UmbracoTemplatePage
    @{
        Layout = "~/Views/Master.cshtml";
    
        @Html.Action("YourBarMethod", "FooSurface")
    }
    

    And this works fantastically, until you start to use POST. You have to use Post-Redirect-Get, so something like a POSTing search form won't work; if you call an [HttpPost] method with your own model, it receives the data perfectly, but there is no way to re-render the view in the Umbraco template: your view will be rendered without layout or just blow up because of model mismatch if you return anything else than (RedirectTo)CurrentUmbracoPage(). 

    As this was totally unusable for our search form (use TempData they say), we worked around this by modifying our search form to utilize GET:

    <form>
        <input type="text" name="baz" />
        <input type="submit" value="Search" />
    </form>

    Edit: WTF, retarded forum software again, it destroys escaped HTML when you edit your post again.

     This will do a GET request to the same Umbraco page, which will just re-render your partial, where you can now read the GET parameters (either from your method signature or using Request.QueryString):

    public ActionResult Search(string baz)
    {
        // do search
        var model = PerformSearch(baz);
        return PartialView(model);
    }
    

     

    This stuff should be in the documentation. Good luck.

     

Please Sign in or register to post replies

Write your reply to:

Draft