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.

  • You can try changing Website/Controllers/FindAnAffiliateController/getAffiliate in your js to /FindAnAffiliateController/getAffiliate – Teeknow Aug 8 '17 at 13:36
  • I did that, ... that did not work – Paul T. Rykiel Aug 8 '17 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 Aug 8 '17 at 13:45
  • I am not sure I understand how to change my custom route, I don't want to mess anything up – Paul T. Rykiel Aug 8 '17 at 13:47
  • do I need to register the controller in Sitecore – Paul T. Rykiel Aug 8 '17 at 13:55
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.

| improve this answer | |
  • you have to use url: "api/Sitecore/{controller}/{action}/{id} – Paul T. Rykiel Aug 8 '17 at 17:54
  • Great post and a very good point about the Mvc.IllegalRoutes! Great catch! +1 – Zachary Kniebel Aug 8 '17 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 }
    );
}
| improve this answer | |
  • I am not comfortable changing the Routeconfig ... do I change the default or do I add a new line – Paul T. Rykiel Aug 8 '17 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 – Zachary Kniebel Aug 8 '17 at 16:04
  • 1
    And you should use a Initialize pipeline processor to do this just before the Sitecore routes are applied. – Richard Seal Aug 8 '17 at 16:09
  • @RichardSeal is exactly right! – Zachary Kniebel Aug 8 '17 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}

| improve this answer | |
  • well, I only put in the "website/Controllers/FindAnAffiliateController/getAffiliate", because "FindAnAffiliateController/getAffiliate" didn't work either – Paul T. Rykiel Aug 8 '17 at 13:42
  • do you know how I can see the url that is it loading? meaning localhost:8990/home/item/controller/ etc. – Paul T. Rykiel Aug 8 '17 at 13:54
  • +1 for the update to the route! Definitely a change that needs to be applied – Zachary Kniebel Aug 8 '17 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) {

            }
        });
| improve this answer | |
  • Its working for fine for me. – Agent47 Jun 13 '18 at 9:11
  • this is returning error : Attempt to retrieve context object of type 'Sitecore.Mvc.Presentation.RenderingContext' from empty stack. – Sunil Kumar Jun 24 '19 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) – Don Cheadle Dec 30 '19 at 2:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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