5

I am making an ASP.net MVC application And I would like it so when a user clicks on a link it performs an ajax call sending data to the controller and then returning other data back to the view.

This is the method I would like to call in my controller:

public JsonResult GetImage(string url)
        {
            Image image = Image.FromFile(url, true);

            byte[] byteImage = converter.ImageToBytes(image);

            return Json(new { byteImage }, JsonRequestBehavior.AllowGet);
        }

And here is the controllers location:

08983ClassLibrary\EpostASP\Controllers\CustomerController.cs

This is my Ajax Call:

$.ajax({
            url: "~/Controllers/CustomerController/GetImage/",
            type: 'POST',
            contentType: 'application/json',
            data: "url="+url,
            success: function (image) {
                document.getElementById("image").src = "data:image/png;base64," + image;
                showImage();
            }
        });

When i place my breakpoints in the code I can see it hitting the ajax call then stepping over it never reaches the controller and doesnt give any errors. Any ideas?

brian4342
  • 1,265
  • 8
  • 33
  • 69
  • Do you really have `"~/Controllers/...` in the JavaScript? Does you route map include `~/{controller}/{action}...` route or you assume somehow page relative Url in JavaScript/HTML will be converted into site relative Url? Consider using some HTTP debugging tools (like Fiddler) to see how exactly request looks like and see if you expect server to handle it. – Alexei Levenkov May 01 '14 at 03:52

8 Answers8

14

The main issue is here -

url: "~/Controllers/CustomerController/GetImage/",

You see, ~ is a server side literal, in other words, when you use this in a ASP.net server side path, it is replaced by the current server application folder location. This was the traditional ASP.Net way. This line has 2 errors -

  1. This url will never work. Because its inside a string in JS and thus ASP.net does not know that it has to replace it with server path. Now comes the second error, even if ASP.net could detect and convert it, it will still not work. Because of the point I described at 2 -

  2. Since you are using ASP.net MVC, it's not a good practice. The more conventional MVC way is to create routes and use those routes. Because in ASP.net you have the option to link to a page (.aspx, .ascx) directly. But MVC controller actions cannot be linked like that. So you have to create routes in your route config (check Global.asax) and then use that route as the url in here. BY default MVC apps will support the following format -

    <host>/{controller}/action

    example -

    'localhost/Home/Index`
    

Notice that I didn't write HomeController, because by default controllers are supposed to ignore the trailing string Controller.

I hope this helped and just incase you are looking for a solution for your current situation try this (I haven't tested but it should be like this) -

 $.ajax({
        url: "Customer/GetImage",
        type: 'POST',
        contentType: 'application/json',
        data: "url="+url,
        success: function (image) {
            document.getElementById("image").src = "data:image/png;base64," + image;
            showImage();
        }
    });

but to be on the safe side, make sure you use -

[HttpPost]
public JsonResult GetImage(string url)
{
}

UPDATE: the maproute (as requested in comment ) will work with any of these routes. But can also work with different routes config. Route config is very very flexible, it is just a matter to setup the routes the way it works for you. -

    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.MapRoute(
            "...",                                              // Route name
            "{controller}/{action}/{id}",                           // URL with parameters
            new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
        );

        routes.MapRoute(
            "...",                                              // Route name
            "{controller}/{action}",                           // URL with parameters
            new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
        );

        routes.MapRoute(
            "...",                                              // Route name
            "{controller}/{action}/{id}",                           // URL with parameters
            new { controller = "Customer", action = "GetImage", id = "" }  // Parameter defaults
        );
        routes.MapRoute(
            "...",                                              // Route name
            "Customer/GetImage/{id}",                           // URL with parameters
            new { controller = "Customer", action = "GetImage", id = "" }  // Parameter defaults
        );
        ..... //all of these mentioned route will land on the same url 
    }

    protected void Application_Start()
    {
        RegisterRoutes(RouteTable.Routes);
    }
brainless coder
  • 6,310
  • 1
  • 20
  • 36
4

Your ajax script says it is looking for a POST action method.

$.ajax({type: 'POST',

Have you decorated the action method with POST?

[HttpPost]
public JsonResult GetImage(string url)
{
}

Also, adjust your ajax data parameter

$.ajax({
    data: {
        "url": url 
        },
Yorro
  • 11,445
  • 4
  • 37
  • 47
3

If you are using chrome you can go the developer tools -> network tab and see all the server requests being made. Hit your button and you will see it pop up and show you the response codes, headers etc. In your case it will be red and will tell you what went wrong

BrendanMcKee
  • 826
  • 7
  • 15
0

If you are using web api... Your method is starting with "Get" GetImages so you need to decorate the method with [HttpPost]

zero7
  • 1,298
  • 8
  • 14
0

I have found that using fiddler is the best way to see what is going on in MVC.

Start up fiddler, run the code again and see what actually came back. Most likely (as mentioned by Yorro) is that you got a 404 error and as you have no error handling in your json call, you wont ever see the error.

0
$.ajax({
     url: '@Url.Action("GetImage", "Customer")',
    type: 'POST',
   contentType: "application/json; charset=utf-8",
    data: "url="+url,
    success: function (image) {
        document.getElementById("image").src = "data:image/png;base64," + image;
        showImage();
    }
});
Cthulhu
  • 5,095
  • 7
  • 46
  • 58
Sk Asraf
  • 45
  • 2
  • 8
  • Hi, welcome to SO. Please don't just dump code as an answer, explain your thoughts so users can better understand what's going on. Thanks. – Cthulhu Apr 04 '16 at 09:49
0

If using IE, and your controller is hitting the first time only add ...

$.ajax({ cache:false, ...

Kenmeister
  • 504
  • 2
  • 9
  • 9
0

Some time it will work or some time not work so don't mention URL such as static "~/Controllers/CustomerController/GetImage/" please follow the dynamic way

So you will change the code snippet such as below

$.ajax({
        url: "@Url.Action("GetImage", "CustomerController")",
        type: 'POST',
        contentType: 'application/json',
        data: "url="+url,
        success: function (image) {
            document.getElementById("image").src = "data:image/png;base64," + image;
            showImage();
        }
    });

hopefully this code will be resolved your problem !!