【问题标题】:Asp.net MVC Ajax call not calling controller methodAsp.net MVC Ajax 调用不调用控制器方法
【发布时间】:2014-06-17 13:51:23
【问题描述】:

我正在制作一个 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)来查看请求的确切外观,并查看您是否希望服务器处理它。

标签: c# jquery asp.net ajax asp.net-mvc


【解决方案1】:

主要问题在这里 -

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

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

  1. 这个网址永远不会起作用。因为它在 JS 中的字符串中,因此 ASP.net 不知道它必须用服务器路径替换它。现在出现第二个错误,即使 ASP.net 可以检测并转换它,它仍然无法正常工作。由于我在 2 中描述的点 -

  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 应该是什么样子??
【解决方案2】:

您的 ajax 脚本说它正在寻找 POST 操作方法。

$.ajax({type: 'POST',

你用 POST 修饰过 action 方法吗?

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

另外,调整你的 ajax 数据参数

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

【讨论】:

  • 装饰是可选的。
【解决方案3】:

如果您使用的是 chrome,您可以转到开发人员工具 -> 网络选项卡并查看所有正在发出的服务器请求。点击你的按钮,你会看到它弹出并显示响应代码、标题等。在你的情况下,它会是红色的,会告诉你出了什么问题

【讨论】:

    【解决方案4】:

    如果您使用的是 web api... 您的方法以“Get”GetImages 开头,因此您需要使用 [HttpPost] 装饰该方法

    【讨论】:

    • +0:你需要说“如果你正在使用 WebAPI...”,这在问题的任何地方都没有提到。
    【解决方案5】:

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

    启动 fiddler,再次运行代码,看看实际返回了什么。最有可能(正如 Yorro 所提到的)是您遇到 404 错误,并且由于您在 json 调用中没有错误处理,因此您永远不会看到该错误。

    【讨论】:

      【解决方案6】:
      $.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。请不要只是转储代码作为答案,请解释您的想法,以便用户更好地了解正在发生的事情。谢谢。
      【解决方案7】:

      如果使用 IE,并且您的控制器是第一次点击,则只需添加...

      $.ajax({ 缓存:假, ...

      【讨论】:

        【解决方案8】:

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

        所以你将代码sn-p更改如下

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

        希望这段代码能解决您的问题!

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2023-03-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多