9

this is my markup: the ajax is supposed to get called when there is a change to my dropdown selection:

this is my ajax jquery:

<script>
    $("#AffiliateList").change(function (e) {
        var textval = $("AffiliateList :selected").text();
        var selected = $("#AffiliateList :selected").val();

        $.ajax({

            type: "GET",
            url: "Website/Controllers/FindAnAffiliateController/getAffiliate",
            data: { id : selected },
            content: "html",
            success: function (response) {
                $("#affiliateDetail").empty();
                $("#affiliateDetail").append(response);
            }


            })
    })
</script>

This is my controller:

namespace Website.Controllers
{
    public class FindAnAffiliateController : Controller
    {
        // GET: findAnAffiliate
        public ActionResult Index()
        {
            return View();
        }

        public ActionResult FindAnAffiliate()
        {
            var dataSourceId = RenderingContext.CurrentOrNull.Rendering.DataSource;
            var dataSourceItem = Sitecore.Context.Database.GetItem(dataSourceId);

            var model = new AffiliateViewModel();
            model.title = dataSourceItem.Fields["Title"].Value;
            model.description = dataSourceItem.Fields["Description"].Value;
            model.affiliateList = model.affiliates();

            var selectedItem = model.affiliateList.FirstOrDefault();


            var affiliateDetail = new Affiliate();

            var affiliateItem = Sitecore.Context.Database.GetItem(selectedItem.Value);
            affiliateDetail.title = affiliateItem.Fields["Affiliate Name"].Value;
            var linkUrl =(Sitecore.Data.Fields.LinkField) affiliateItem.Fields["Affiliate Link"];
            affiliateDetail.linkText = linkUrl.Text != "" ? linkUrl.Text : "No Link Available";
            affiliateDetail.linkUrl = linkUrl.Url != "" ? linkUrl.Url : "#";
            affiliateDetail.description = affiliateItem.Fields["Description"].Value;
            model.affiliate = affiliateDetail;


            return View(model);
        }

        public ActionResult getAffiliate(string id)
        {
            return PartialView();
        }
    }
}

and finally my RouteConfig

namespace Website
{
    public class RouteConfig
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
            );
        }
    }
}

and here is my PartialView that should be returned:

<h4>Testing this stuff</h4>
<p class="media-link">www.alabamawildlife.org</p>
<p>The Alabama Wildlife Federation (AWF) is the oldest and largest non-profit conservation organization in Alabama. The AWF was established by sportsmen in 1935 to promote the conservation and wise use of our wildlife and natural resources and to ensure a high quality of life for future generations of Alabamians.</p>

<div class="col-xs-6">
    <p class="uppercase-headline text-center">Co-certification of Certified Wildlife Habitat</p>
    <img class="center-block" src="images/cwh-icon.png">
</div>

<div class="col-xs-6">
    <p class="uppercase-headline text-center">Ranger Rick Subscription</p>
    <img class="center-block" src="images/ranger-rick-logo-regional.png">
</div>

I am running on my localhost, I don't know if that is part of the problem, but outside of Sitecore, I have build ajax commands off of regular MVC applications with no issues.

9
  • You can try changing Website/Controllers/FindAnAffiliateController/getAffiliate in your js to /FindAnAffiliateController/getAffiliate
    – Teeknow
    Commented Aug 8, 2017 at 13:36
  • I did that, ... that did not work Commented Aug 8, 2017 at 13:41
  • Can you try removing your custom route, have your controller inherit from Sitecore.Mvc.Controllers.SitecoreController, and then try to hit it at /api/sitecore/FindAnAffiliateController/getAffiliate
    – Teeknow
    Commented Aug 8, 2017 at 13:45
  • I am not sure I understand how to change my custom route, I don't want to mess anything up Commented Aug 8, 2017 at 13:47
  • do I need to register the controller in Sitecore Commented Aug 8, 2017 at 13:55

4 Answers 4

6

It's worth mentioning that the route in the question is called out in a setting. The comment above Mvc.IllegalRoutes explains itself a bit.

  <!--  MVC: Pipe separated list of route URL's that are not valid for use with Sitecore.Mvc.
        For instance, the default ASP.NET route ({controller}/{action}/{id}) catches most requests
        that are actually meant to be handled by the default Sitecore route.
        Default: "{controller}/{action}/{id}"
  -->
  <setting name="Mvc.IllegalRoutes" value="|{controller}/{action}/{id}|" />

Another thing to note is that Sitecore will try to register your controllers at /api/sitecore/{Controller}/{Action}. There can be issues if there's ever an overlap though.

2
  • you have to use url: "api/Sitecore/{controller}/{action}/{id} Commented Aug 8, 2017 at 17:54
  • Great post and a very good point about the Mvc.IllegalRoutes! Great catch! +1 Commented Aug 8, 2017 at 18:11
4

First off, @PatrickBarron is absolutely correct about your route. However, there is one other issue that I see. Have you tried dropping the word "Controller" off the name of your controller when making the request? By default, the word Controller will be appended for you.

In other words, you are currently requesting this URL:

"Website/Controllers/FindAnAffiliateController/getAffiliate"

for this route (corrected, based on Patrick Barron's solution):

"Website/Controllers/{controller}/{action}/{id}"

in an attempt to make a request that invokes the specified controller and action with the specified value for the ID argument (which can be null), as described below:

Controller: FindAnAffiliateController
Action:     getAffiliate
ID:         null

However, because word "Controller" is automatically appended to the name of the requested controller when attempting to resolve it, what you are effectively doing is making a request that invokes the following:

Controller: FindAnAffiliateControllerController
Action:     getAffiliate
ID:         null    

Solution

  1. Update your route, as described by @PatrickBarron, to: "Website/Controllers/{controller}/{action}/{id}"
  2. Change your AJAX call to instead request the following URL: "Website/Controllers/FindAnAffiliate/getAffiliate"

For updating your route, you don't want to change the default route. Instead, what you want to do is add the route suggested by Patrick Barron as a new route, like so:

routes.MapRoute(
    name: "Default",
    url: "Website/Controllers/{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

Thus, your RegisterRoutes method should look something like the following:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}/{id}",
        defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
    );

    routes.MapRoute(
        name: "Default",
        url: "Website/Controllers/{controller}/{action}/{id}",
        defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
    );
}
4
  • I am not comfortable changing the Routeconfig ... do I change the default or do I add a new line Commented Aug 8, 2017 at 16:03
  • You shouldn't be changing the default route, you should be adding your own. I'll update my solution in a moment with the route that you should add Commented Aug 8, 2017 at 16:04
  • 1
    And you should use a Initialize pipeline processor to do this just before the Sitecore routes are applied.
    – Richard Seal
    Commented Aug 8, 2017 at 16:09
  • @RichardSeal is exactly right! Commented Aug 8, 2017 at 16:10
1

It looks like the URL you are sending the request to doesn't match your route configuration.

Your URL is /Website/Controllers/FindAnAffiliateController/getAffiliate and your rout is {controller}/{action}/{id} so it's looking for /FindAnAffiliateController/getAffiliate

I would update your route to be Website/Controllers/{controller}/{action}/{id}

3
  • well, I only put in the "website/Controllers/FindAnAffiliateController/getAffiliate", because "FindAnAffiliateController/getAffiliate" didn't work either Commented Aug 8, 2017 at 13:42
  • do you know how I can see the url that is it loading? meaning localhost:8990/home/item/controller/ etc. Commented Aug 8, 2017 at 13:54
  • +1 for the update to the route! Definitely a change that needs to be applied Commented Aug 8, 2017 at 15:50
1

In sitecore MVC always use /api/Sitecore/{controller}/{action}. It should work if you are call from ajax.

Sample code:

jQuery.ajax({
            type: "POST",
            url: "/api/sitecore/{controller}/{action}",
            data: '{url: "' + _url + '" }',
            contentType: "application/json; charset=utf-8",
            dataType: "html",
            success: function (response) {

            },                
            error: function (response) {

            }
        });
3
  • Its working for fine for me.
    – Agent47
    Commented Jun 13, 2018 at 9:11
  • this is returning error : Attempt to retrieve context object of type 'Sitecore.Mvc.Presentation.RenderingContext' from empty stack. Commented Jun 24, 2019 at 9:22
  • Yep this is what I needed. My AJAX works, hits my custom controller action (and in my case... It's still able to authenticate.login to log the user into Sitecore extranet) Commented Dec 30, 2019 at 2:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.