Routing an AJAX POST to a module

Topics: Writing modules
Aug 23, 2011 at 12:13 AM

I built a normal MVC 2 website that contains a controller that will receive AJAX posts that get a user signed up for an email subscription list via MailChimp. That controller works fine and has been deployed for 6 weeks or so. What I want to do now is create a custom Orchard module that does the same thing.

So I've created a custom module, got everything wired up, and I'm having a few problems. Specifically, I can't seem to get the routing right to actually catch the POST inside my controller. Here's my controller:

 

public class EmailSignupController : Controller
    {
        IMailChimpHelper _mailChimpHelper;

        public EmailSignupController()
            : this(new MailChimpHelper()) { }

        public EmailSignupController(IMailChimpHelper mailChimpHelper)
        {
            _mailChimpHelper = mailChimpHelper;
        }

        //
        // AJAX: AddEmail
        [HttpPost]
        public ActionResult AddEmail(string emailText)
        {
            string responseStatus = "error";
            string responseMessage = "Unknown Error";

            /* a bunch of code here */

            return Json(new { status = responseStatus, message = responseMessage });
        }
    }

 

 

And here's my Routes.cs file:

 

using System;
using System.Collections.Generic;
using System.Web.Mvc;
using System.Web.Routing;
using Orchard.Mvc.Routes;

namespace EmailSignup
{
    public class Routes : IRouteProvider
    {
        public void GetRoutes(ICollection<RouteDescriptor> routes)
        {
            foreach (var routeDescriptor in GetRoutes())
                routes.Add(routeDescriptor);
        }

        public IEnumerable<RouteDescriptor> GetRoutes()
        {
            return new[] {
                new RouteDescriptor {
                    Priority = 5,
                    Route = new Route(
                        "EmailSignup/AddEmail/",
                        new RouteValueDictionary {
                            {"area", "EmailSignup"},
                            {"controller", "EmailSignup"},
                            {"action", "AddEmail"}
                        },
                        new RouteValueDictionary(),
                        new RouteValueDictionary {
                            {"area", "EmailSignup"}
                        },
                        new MvcRouteHandler())
                }
            };
        }
    }
}

 

For whatever reason, I'm not catching the POST when it's made to http://www.mywebsite.com/EmailSignup/AddEmail

I've created a GET handler, typed in the same URL via the browser address bar, and sure enough I can catch that request (as I would expect) telling me my routing is either correct or pretty close. However, when I make the POST (from an AJAX call) I get the following error (via Chrome's developer console):

 

XHR finished loading: "http://localhost:30320/EmailSignup/AddEmail".

 

Obviously, localhost:30320 is my local server. Again, using the same URL and doing a GET routes to my GET handler (which I omitted from my code above). No special wiring was required in my previous MVC project where it all worked automagically. Any thoughts? Is the problem with routing or should I be looking elsewhere?

Coordinator
Aug 23, 2011 at 12:25 AM

This looks like it should work. Does it if you remove the HttpPost attribute (not that it should, just for the sake of experimenting)?

Aug 23, 2011 at 12:38 AM

Doh. Take a look at the response for Chrome. It's missing "OrchardLocal". It's no wonder I couldn't catch the request.

Kids, this is why good programmers ALWAYS CHECK THEIR ASSUMPTIONS FIRST.

Thanks for the look at this, Bertrand. Feel free to kill the thread if it clutters the board.

Sep 6, 2011 at 12:35 PM

Hi trentnix,

thanks for your post, it helped me out with my routing. But what did you mean by:

    Take a look at the response for Chrome. It's missing "OrchardLocal"?

Could you explain?

Thanks, Oliver

Sep 6, 2011 at 12:59 PM

Hey Oliver,

Sorry I didn't more clearly explain what that meant. Look at my original URL:

http://localhost:30320/EmailSignup/AddEmail

It's incorrect! In my development environment, it should be:

http://localhost:30320/OrchardLocal/EmailSignup/AddEmail

So it's no wonder that I wasn't catching the POST considering it wasn't pointing at the right URL. So remember to always check your assumptions.

Sep 12, 2011 at 9:04 PM

Thanks trentnix for following up on this. Now I understand what you meant :-)