Copied to clipboard

Flag this post as spam?

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


  • Mark 255 posts 612 karma points
    Oct 27, 2013 @ 22:23
    Mark
    0

    Calling Surface Controller From Ajax

    Umbraco 6.1.4

    I'm trying to call a surface controller action using ajax. I have the following surface controller created:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;

    namespace MyApp.Web.Controllers
    {
        public class JobSearchController : Umbraco.Web.Mvc.SurfaceController
        {
            [HttpPost, Umbraco.Web.Mvc.NotChildAction]
            public ActionResult GetOpportunityCount()
            {
                return Json(new { Count = 0 });
            }
        }
    }

    I have the following jquery snippet in a .js file that gets inserted into an Umbraco document view:

    var posting = $.post('/umbraco/surface/JobSearch/GetOpportunityCount/', null);

                // post success
                posting.done(function (data) {
                    $(opportunitiesCountElement).val(data.Count);
                });

                // post error - should not happen
                posting.fail(function (data) {
                    alert('Error connecting to server');
                });

    But when I call the action I get a 404 error for url: /umbraco/surface/jobsearch/getopportunitycount

    If I try to embed the action into a view using:

    @Html.Action("GetOpportunityCount", "JobSearch")

    I get the following error:

     

    A public action method 'GetOpportunityCount' was not found on controller 'MyApp.Web.Controllers.JobSearchController'.

    I'm obviously doing something wrong or something that I'm not supposed to. Can anyone see the problem with what I'm trying to accomplish?

  • Sebastiaan Janssen 5018 posts 15341 karma points MVP admin hq
    Oct 28, 2013 @ 11:15
    Sebastiaan Janssen
    0

    I would recommend you use UmbracoApiControllers for this instead. They are standard ASP.NET Web API controllers with a little bit of Umbraco sprinkled on top of them (easy access to Umbraco APIs and an easy way to add Umbraco authentication). Docs here: http://our.umbraco.org/documentation/Reference/WebApi/

  • Mark 255 posts 612 karma points
    Oct 28, 2013 @ 14:13
    Mark
    0

    Thanks, Sebastiaan. I'lll take a look. Can you tell me what's wrong with using Surface Controllers in this case? I'd like to know in what situation Surface Controllers "should" be used to avoid making this mistake again.

  • Sebastiaan Janssen 5018 posts 15341 karma points MVP admin hq
    Oct 28, 2013 @ 14:26
    Sebastiaan Janssen
    0

    I would use Surface Controllers for actual forms on a page. Anything that you want to do asynchronously / from javascript is much easier if it's going through an Umbraco Api Controller.

    Make sure to check out our TV episodes on this as well: http://umbraco.tv/videos/developer/fundamentals/api-controllers/introduction/

  • Herman van der Blom 10 posts 83 karma points
    May 16, 2017 @ 11:02
    Herman van der Blom
    0

    Easier to say: - Use Web API for Data - Use MVC for Views - Or Use MVC for both DATA and Views if you don't want to use Web API

  • Mark 255 posts 612 karma points
    Oct 28, 2013 @ 17:19
    Mark
    0

    Okay, trying to reference UmbracoApiController but can't find it. Which DLL should I be referencing? I'm referencing all the usual ones, i.e. umbraco, interfaces, businesslogic, Umbraco.Core, Umbraco.Web.UI...

  • Sebastiaan Janssen 5018 posts 15341 karma points MVP admin hq
    Oct 28, 2013 @ 17:25
    Sebastiaan Janssen
    0

    Make sure to read the docs, quote:

    to create an Umbraco Api controller, you simply inherit from the class Umbraco.Web.WebApi.UmbracoApiController

  • Mark 255 posts 612 karma points
    Oct 28, 2013 @ 17:37
    Mark
    0

    Thanks Sebastiaan, I've read the docs, but unfortunately I can't reference the class Umbraco.Web.WebApi.UmbracoApiController inside my Visual Studio project. What DLL should I reference to get access to that controller? There is no Umbraco.Web.WebApi.DLL in the webroot/bin folder so I assume it must be in another library

  • Sebastiaan Janssen 5018 posts 15341 karma points MVP admin hq
    Oct 28, 2013 @ 19:22
    Sebastiaan Janssen
    0

    I think it's in the umbraco.presentation dll.

    I can recommend you install the UmbracoCms.Core NuGet package, it will add references to all required dlls automaticallly so you don't have to hunt around.

  • Andy Butland 410 posts 2298 karma points MVP 4x hq c-trib
    Oct 28, 2013 @ 20:37
    Andy Butland
    0

    In additions to Sebastiaan's advice... just going back to your original post Mark, I've got surface controllers working in this way.  I think part of the issue you have is that you've decorated it with [HttpPost] - which means you can't call it in Html.Action or pull up the URL in the browser.  That would explain the 404.

    Not quite clear why your jquery doesn't work but I'm wondering about the null being passed as the second parameter or maybe the fact that you are saving to the variable posting.  Both may be fine but might be worth checking the syntax here and following one of the examples, just to exclude something around that.

    Andy

  • Mark 255 posts 612 karma points
    Oct 28, 2013 @ 22:01
    Mark
    1

    Andy, thanks for your comments. I now have the SurfaceController working. Essentially my code didn't work before I'd put in the NotChildAction attribute, but by that point I was testing the URL and Action which, as you rightly pointed out, wouldn't work as it uses Get rather than Post. Then I didn't actually check the jQuery method again after adding NotChildAction, so it was working and I didn't know it. Silly of me, I know, but I'd clearly got myself in a muddle... :-)

    Anyway, great that it's now working. Thanks also to Sabastiaan. I think I'll stick with the Surface Controller method for now as it means I don't need to update the code. In future I'll definitely consider the WebApi method, although I have to say I'm still not clear why one should be used over the other. Anyway, that's another post...

  • Andy Butland 410 posts 2298 karma points MVP 4x hq c-trib
    Oct 29, 2013 @ 11:33
    Andy Butland
    2

    Just on this Mark...  I'm still not clear why one should be used over the other...

    It's certainly in part personal preference I think.  But FWIW the rule of thumb I'm currently working to is if I'm creating an API only - i.e. probably a JSON based end-point that I'll call from JavaScript - or I need WebAPI features like content negotiation - then WebAPI would be what I would use.  However if I'm creating surface controllers for the purposes of handling normal form posts and rendering partials, and I need to handle some related AJAX requests too, then I'll put them in the surface controller.

    Andy

  • Sebastiaan Janssen 5018 posts 15341 karma points MVP admin hq
    Oct 29, 2013 @ 13:01
    Sebastiaan Janssen
    0

    @Andy Yup, that's my rule of thumb as well, you just explained it much better than I did! ;)

  • Shannon Deminick 1523 posts 5256 karma points MVP
    Nov 07, 2013 @ 02:25
    Shannon Deminick
    1

    @Mark - you're nearly there... only thing that is missing is setting up jquery properly to have the correct request settings.

    try chucking this in your JS script to set the default ajax options for jquery:

    //sets defaults for ajax
    $.ajaxSetup({
        dataType: 'json',
        contentType: 'application/json; charset=utf-8'
    });
    

    Also, my advise for testing stuff like this is to install the PostMan chrome dev plugin, makes ajax testing super easy.

  • Mark 255 posts 612 karma points
    Nov 07, 2013 @ 12:14
    Mark
    0

    Thanks @Shannon. I wasn't aware of the ajax defaults. I'll install PostMan too. To date I've always used Firefox and Firebug when developing, but I'm finding it crashes more and more these days. Maybe I'll use Chrome from now on. Just need to familiarise myself with the development tools...

Please Sign in or register to post replies

Write your reply to:

Draft