ASP.NET MVC Ajax调用未调用控制器方法

5

我将要制作一个ASP.net MVC应用程序,并希望当用户点击链接时,它可以执行一个ajax调用,向控制器发送数据,然后返回其他数据到视图。

这是我想在我的控制器中调用的方法:

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

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

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

这里是控制器的位置:

08983ClassLibrary\EpostASP\Controllers\CustomerController.cs

这是我的 Ajax 调用:
$.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();
            }
        });

当我在代码中放置断点时,我可以看到它触发了ajax调用,然后跳过它,从未到达控制器且没有任何错误信息。有什么想法吗?


你的 JavaScript 代码中真的有 "~/Controllers/... 吗?你的路由映射包括 ~/{controller}/{action}... 路由吗?还是你假设 JavaScript/HTML 中的页面相对 URL 会被转换为站点相对 URL?考虑使用一些 HTTP 调试工具(如 Fiddler)来查看请求的确切样子,并确定是否希望服务器处理它。 - Alexei Levenkov
8个回答

14

主要问题在于这里 -

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

你看,~是一个服务器端字面量,换句话说,在ASP.NET服务器端路径中使用它时,它将被替换为当前服务器应用程序文件夹的位置。这是传统的ASP.NET方式。这行有两个错误 -

  1. 这个URL永远不会工作,因为它在JS字符串内部,所以ASP.NET不知道它必须用服务器路径替换它。现在出现第二个错误,即使ASP.NET可以检测和转换它,它仍然无法工作。因为我在第二点描述的原因 -

  2. 由于您正在使用ASP.NET MVC,这样做不是一个好习惯。更常规的MVC方式是创建路由并使用这些路由。因为在ASP.NET中,您可以直接链接到页面(.aspx,.ascx)。但是MVC控制器操作无法像那样链接。因此,您必须在路由配置中创建路由(请检查Global.asax),然后将该路由用作此处的URL。默认情况下,MVC应用程序将支持以下格式 -

    <host>/{controller}/action

    例如 -

    'localhost/Home/Index`
    
    请注意,我没有写HomeController,因为默认情况下控制器应该忽略尾部的字符串Controller。 希望这可以帮到您,如果您正在寻找当前情况的解决方案,请尝试这个(我没有测试过,但应该是这样的)-
     $.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();
            }
        });
    

    但为了保险起见,请确保您使用 -

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

    更新:如评论中所请求,maproute将适用于任何这些路由。但也可以与不同的路由配置一起使用。路由配置非常灵活,只需要根据自己的需求设置路由即可。-

        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);
        }
    

在这种情况下,MapRoute应该长什么样子? - usefulBee

4
你的ajax脚本指定需要一个POST方法。
$.ajax({type: 'POST',

你是否已经在动作方法上使用了POST?

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

另外,调整您的ajax数据参数。

$.ajax({
    data: {
        "url": url 
        },

2
装饰器是可选的。 - Erik Philips

3

如果您正在使用Chrome浏览器,可以进入开发者工具->网络选项卡,查看所有服务器请求记录。点击按钮后,您将看到它弹出并显示响应代码、头部信息等。在您的情况下,它将是红色,并告诉您出了什么问题。


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();
    }
});

嗨,欢迎来到SO。请不要仅仅把代码作为答案抛出,解释一下你的想法,这样用户就能更好地理解发生了什么。谢谢。 - Cthulhu

0
如果使用IE,并且您的控制器仅第一次命中,请添加以下代码... $.ajax({ cache:false, ...

0
如果您正在使用 Web API... 您的方法以 "Get" 开头,例如 GetImages,因此您需要使用 [HttpPost] 来装饰该方法。

+0:你需要说“如果你正在使用WebAPI...”,这在问题中没有提到。 - Alexei Levenkov

0

我发现使用Fiddler是查看MVC中发生了什么的最佳方式。

启动Fiddler,再次运行代码并查看实际返回的内容。很可能(正如Yorro所提到的),您会收到404错误,并且由于您的JSON调用中没有错误处理,因此您永远不会看到该错误。


0

有时它会工作,有时它不会工作,所以请不要提及静态的URL,例如"~/Controllers/CustomerController/GetImage/",请遵循动态方式

因此,您需要更改以下代码片段

$.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();
        }
    });

希望这段代码可以解决你的问题!!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接