数据表 Ajax url 未命中控制器操作

Posted

技术标签:

【中文标题】数据表 Ajax url 未命中控制器操作【英文标题】:Data tables Ajax url not hitting Controller action 【发布时间】:2021-11-13 05:58:34 【问题描述】:

我有点沮丧,同样的代码在我的项目的其他地方也可以使用。由于某种原因,它没有击中控制器动作。当页面加载时,数据表出现并且只有处理弹出窗口,就像它找不到记录一样。我在控制器动作上放了一个断点,发现它甚至没有命中它。

javascript 代码:

 $(document).ready(function () 
    var oTableMenuPermission = "";
    $("#PartsListTable").dataTable(
        "ajax": 
            "url": "/Home/GetList",
            "type": "POST",
            "datatype": "json",              
        ,
        "responsive": true,
        "bRetrieve": true,
        "bProcessing": true,
        "deferRender": true,
        "dom": 'lBfrtip',
        "serverSide": "true",
        "order": [0, "PartNumber"],
        "language": 
            "processing": "processing...Please wait"
        ,
        "buttons": [
             extend: 'copyhtml5', exportOptions:  columns: ':visible'  
            ,  extend: 'excelHtml5', exportOptions:  columns: ':visible'  
            ,  extend: 'csvHtml5', exportOptions:  columns: ':visible'  
            ,  extend: 'pdfHtml5', exportOptions:  columns: ':visible'  
            ,  extend: 'print', exportOptions:  columns: ':visible'  
            , 'colvis'
        ],
        columnDefs: [ orderable: false, targets: [2, 3, 4, 5, 6] ],

        "aoColumns": [
             "data": "PartNumber", "name": "PartNumber" ,
            
                "data": "PartImage", "aTargets": [0],
                "render": function (data) 
                    if (data === null) return '<img src=Content/Images/Parts/NoImage.png style="width:50px;" />';
                    return '<img src=Content/Images/Parts/' + data + ' class="zoom" style="width:50px;" />';
                
            ,
             "data": "Description", "name": "Description" ,             
            
                "data": "HasUpgrade", "aTargets": [0],
                "render": function (data) 
                    if (data === true) 
                        return '<b style="color:green;">Yes</b>';
                     else 
                        return '<b style="color:red;">No</b>';
                    
                
            ,
            
                "data": "IsUpgrade", "aTargets": [0],
                "render": function (data) 
                    if (data === true) 
                        return '<b style="color:green;">Yes</b>';
                     else 
                        return '<b style="color:red;">No</b>';
                    
                
            ,
            
                "mRender": function (oObj, type, full) 
                    var button = '<div>'
                    button += '<div class="btn-group">';
                    button += '<a class="btn btn-warning btn-sm" href="' + ControlerNameParts + "/Details/" + full.Material + '" data-ajax-update="#SkEdit" data-ajax-success="openModalDialog(\'SkEdit\', \'Edit\')" data-ajax-mode="replace" data-ajax-method="GET" data-ajax-failure="clearModalDialog(\'SkEdit\');alert(\'Ajax call failed\')" data-ajax-begin="prepareModalDialog(\'SkEdit\')" data-ajax="true">Details</a>&nbsp;';
                    button += '</div></div>';
                    return button;
                
            ,

        ],


    );
);

这里是控制器动作:

        [HttpPost]
    public ActionResult GetList()
    
        // Server Side Parameters
        int start = Convert.ToInt32(Request["start"]);
        int length = Convert.ToInt32(Request["length"]);
        string searchValue = Request["search[value]"];
        string sortColumnName = Request["column[" + Request["order[0][column]"] + "][name]"];
        string sortDirection = Request["order[0][dir]"];

        List<PartSearchView> prodList = new List<PartSearchView>();
        using (GeneralEntities db = new GeneralEntities())
        
            prodList = db.PartSearchView.ToList();
            int totalRows = prodList.Count;
            if (!string.IsNullOrEmpty(searchValue))
            
                prodList = prodList.Where(x => x.PartNumber != null && x.PartNumber.ToLower().Contains(searchValue.ToLower())).ToList();
            

            int totalRowsAfterFilteing = prodList.Count;
            // Sorting
            prodList = prodList.OrderBy(sortColumnName + " " + sortDirection).ToList<PartSearchView>();

            prodList = prodList.Skip(start).Take(length).ToList();

            return Json(new  data = prodList, draw = Request["draw"], recordsTotal = totalRows, recordsFiltered = totalRowsAfterFilteing , JsonRequestBehavior.AllowGet);
        

    

我已尝试将url 更改为@Url.Action("GetList", "Home")

这可能与路由有关,但我在路由配置中看不到任何有问题的地方。 我尝试直接转到 URL,它会拉出一个 404 页面,这与正在运行的页面不同,它会出错但也会触发控制器操作。

感谢您的帮助!

更新: 以下是我的路线配置。我将页面名称和控制器操作更改为PartSearch,之前它只是Parts。还是同样的问题。这是 Home Controller 的一部分。

 public static void RegisterRoutes(RouteCollection routes)
    
        routes.IgnoreRoute("resource.axd/*pathInfo");

        // routes.MapRoute(
        //    name: "Roles",
        //    url: "Roles/action/id",
        //    defaults: new  controller = "UserAndRole", action = "Index", id = UrlParameter.Optional 
        //);

        routes.MapRoute(
            name: "About",
            url: "About",
            defaults: new  controller = "Home", action = "About" 
        );

        routes.MapRoute(
            name: "Services",
            url: "Services",
            defaults: new  controller = "Home", action = "Services" 
        );

        routes.MapRoute(
           name: "Contact",
           url: "Contact",
           defaults: new  controller = "Home", action = "Contact" 
       );

        routes.MapRoute(
        name: "Quote",
        url: "Quote",
        defaults: new  controller = "Home", action = "Quote" 
       );

        routes.MapRoute(
         name: "MyEquipment",
         url: "MyEquipment/id",
         defaults: new  controller = "MyEquipment", action = "Index" 
        );

       // routes.MapRoute(
       // name: "PartsSearch",
       // url: "Parts",
       // defaults: new  controller = "Home", action = "Parts" 
       //);

        routes.MapRoute(
         name: "MyEquipmentTlj",
         url: "MyEquipment/Parts/id",
         defaults: new  controller = "MyEquipment", action = "Parts" 
        );

        // routes.MapRoute(
        // name: "Dashboard",
        //    url: "Dashboard/id",
        //    defaults: new  controller = "Dashboard", action = "Index", page = UrlParameter.Optional 
        //);

        routes.MapRoute(
        name: "EquipCat",
           url: "Equipment/Category/slug/Catid",
           defaults: new  controller = "Equipment", action = "Index", page = UrlParameter.Optional 
       );
        routes.MapRoute(
          name: "EquipTag",
          url: "Equipment/Tag/slug/Tagid",
          defaults: new  controller = "Equipment", action = "Index", page = UrlParameter.Optional 
      );

        routes.MapRoute(
            name: "EquipPost",
            url: "Equipment/Post/id/slug",
            defaults: new  controller = "Equipment", action = "Post" 
        );

        routes.MapRoute(
            name: "AddUsers",
            url: "Users/Create/CompanyId/AddressId",
            defaults: new  controller = "Users", action = "Create" 
        );

        routes.MapRoute(
            name: "BestenAddUsers",
            url: "UsersManager/Create/CompanyId/AddressId",
            defaults: new  controller = "UsersManager", action = "Create" 
        );

        routes.MapRoute(
            name: "AddMachines",
            url: "Machine/Add/CompanyId/AddressId",
            defaults: new  controller = "Machine", action = "Add" 
        );
        routes.MapRoute(
         name: "EventManagerAdd",
         url: "CalendarManager/Add/companyId/addressId",
         defaults: new  controller = "CalendarManager", action = "Add" 
       );

        routes.MapRoute(
           name: "ListAddresses",
           url: "Addresses/id",
           defaults: new  controller = "Addresses", action = "Index" 
       );

        routes.MapRoute(
           name: "ListOrders",
           url: "Orders/id",
           defaults: new  controller = "Orders", action = "Index" 
       );

        routes.MapRoute(
            name: "UserCreate",
            url: "Users/create/CompanyId/AddressId",
            defaults: new  controller = "Users", action = "Create"
        );

        routes.MapRoute(
            name: "NotesAdd",
            url: "Notes/Add/CompanyId/AddressId",
            defaults: new  controller = "Notes", action = "Add" 
        );

        routes.MapRoute(
            name: "SerialAdd",
            url: "SerialNumbers/AddSerial/SerialNumber/CompanyId/AddressId",
            defaults: new  controller = "SerialNumbers", action = "AddSerial" 
        );

        routes.MapRoute(
           name: "SerialSearch",
           url: "SerialSearch",
           defaults: new  controller = "Home", action = "SerialSearch" 
       );

        routes.MapRoute(
           name: "ExpensesAdd",
           url: "ExpenseReports/Create/CompanyId/AddressId",
           defaults: new  controller = "ExpenseReports", action = "Create" 
       );

        routes.MapRoute(
           name: "InvoiceList",
           url: "Invoice/cmpid",
           defaults: new  controller = "Invoice", action = "Index" 
       );

        routes.MapRoute(
           name: "BInvoiceList",
           url: "InvoiceManager/cmpid",
           defaults: new  controller = "InvoiceManager", action = "Index", cmpid = UrlParameter.Optional 
       );

       routes.MapRoute(
           name: "CInvoiceList",
           url: "InvoiceManager/List/addid",
           defaults: new  controller = "InvoiceManager", action = "List" 
       );

        routes.MapRoute(
           name: "QuoteList",
           url: "Quotes/cmpid",
           defaults: new  controller = "Quotes", action = "Index" 
       );

        routes.MapRoute(
         name: "PurchaseOrderAdd",
         url: "PurchaseOrder/Add/id/RFQID",
         defaults: new  controller = "PurchaseOrder", action = "Add" 
     );

        routes.MapRoute(
          name: "Subjobs",
          url: "SubJobs/id",
          defaults: new  controller = "SubJobs", action = "Index" 
      );

        routes.MapRoute(
           name: "BQuoteList",
           url: "QuotePdfManager/cmpid",
           defaults: new  controller = "QuotePdfManager", action = "Index", cmpid = UrlParameter.Optional 
       );

        routes.MapRoute(
            name: "CQuoteList",
            url: "QuotePdfManager/List/addid",
            defaults: new  controller = "QuotePdfManager", action = "List" 
        );

        routes.MapRoute(
            name: "ConfirmEmail",
            url: "Account/SendEmailConfirm/UserName",
            defaults: new  controller = "Account", action = "SendEmailConfirm" 
        );

        routes.MapRoute(
            name: "ShippingAdd",
            url: "ShippingOrBOLs/Add/companyId/addressId/orderId",
            defaults: new  controller = "ShippingOrBOLs", action = "Add" 
        );
       
        routes.MapRoute(
           name: "EventAdd",
           url: "Calendar/companyId/addressId",
           defaults: new  controller = "Calendar", action = "Index" 
       );

        routes.MapRoute(
          name: "MessagesAdd",
          url: "Messages/Add/user",
          defaults: new  controller = "Messages", action = "Add" 
      );

        routes.MapRoute(
           name: "PastDue",
           url: "InvoiceManager/PastDue/id/pastdue",
           defaults: new  controller = "InvoiceManager", action = "PastDue" 
       );

        routes.MapRoute(
            name: "Default",
            url: "controller/action/id",
            defaults: new  controller = "Home", action = "Index", id = UrlParameter.Optional 
        );
    

我更改了名称,因为我有一个 PartsController。 PartsController 用于后端,需要登录凭据。所以我不能用它来做这个。

更新:

我找到了我的问题。尽管这看起来很愚蠢,但它没有击中控制器的全部原因是因为在我有 columnDefs: [ orderable: false, targets: [2, 3, 4, 5, 6] ], 的那一行中,可能有 1 列,有 6 列,但我忘记将第一列计为 0。我有过去在使用foreach 语句而不是server side 时发现了这一点,因为格式不会出现在加载时 - 意思是按钮、搜索、记录数等。但仍会填充记录。在server side 中,我猜它在记录生成之前出现故障。所以它根本与路由无关。而我得到的错误,我认为它与它没有任何关系,因为它说明了一些关于风格的东西。我在dataTables 论坛上找到了答案。感谢所有为此提供帮助的人。

【问题讨论】:

“我试图直接转到 URL 并且它会拉出一个 404 页面” - 简而言之:您的 URL“/Home/GetList”返回 404 并且您的操作未被调用。如果您添加有关路由设置的信息,这将有所帮助(您帖子中的大多数其他代码都无助于解决此问题)。例如。 Startup.cs中的路由部分,控制器名称+控制器路由属性。 这可能会有所帮助:***.com/questions/28435734/… 这个 DataTables 选项看起来很奇怪:"order": [0, "PartNumber"]。我希望它是"order": [0, "asc"]"order": [0, "desc"]。见here。 @andrewjames 是的,我不知道我为什么这样做,但它就像在另一个有效的页面中一样。自从我写代码以来已经有一段时间了。但你是对的,不应该那样。它可能只是在有效的代码中跳过它。这意味着它不会阻碍它,它只是没有排序。生病改变它,看看它是否有所作为。 你是对的:DataTables 倾向于忽略未知选项(并非总是如此,但经常如此)。因此,这不是解决您问题的方法,但应该予以纠正。 【参考方案1】:

您不需要 GetList 的发布操作,因为您不发送任何参数。删除 [post] 并仅用于测试尝试属性路由

在 IgnoreRoute 之后将此添加到您的配置中

 routes.IgnoreRoute("resource.axd/*pathInfo");

routes.MapMvcAttributeRoutes();

和控制器

[Route("~/home/getlist")]
public ActionResult GetList()

恕我直言,在 ajax 中将“type”:“POST”转为“GET”。

【讨论】:

我之前确实在 Parts 下尝试过,但并没有什么不同。当我将其更改为 PartSearch 并删除 [HttpPost] 时,我可以导航到它并点击控制器。我只是在 chtml 视图 ajax 中将其更改为 GET。它仍然没有击中控制器。我按照你说的添加了到控制器的路由,仍然没有打到控制器,我可以直接去,但是ajax没有打到它。 注意:当你使用"serverSide": "true"时,参数是automatically sent从DataTable到服务器。这些用于使服务器知道如何执行排序、过滤和分页。但是,是的,话虽如此,这并不意味着您需要使用POST。你当然可以使用GET @ScottPurtan 很抱歉,零件与 getlist 有什么关系?你用什么网址直接去? @serge 我之前有一个名为 Parts 的页面,我将其更改为 PartSearch。我使用 Url /Home/GetList 直接访问它。它确实会执行此操作,但也会出错,因为它正在寻找一个参数 - searchValue,它存在于数据表中,但如果您直接执行操作而不使用 chtml 页面来执行操作,则不会。我确实使用了 get,现在已将名称更改为 GetGrid。还是不行。 @ScottPurtan 很抱歉,我没有注意到您使用的是旧版本。我更新了我的答案。将属性路由添加到您的路由配置中。

以上是关于数据表 Ajax url 未命中控制器操作的主要内容,如果未能解决你的问题,请参考以下文章

来自弹出表单的 ajax 数据发布未命中控制器方法 ASP.NET MVC

Ajax 调用数据在 POST 期间未传递给控制器

jQuery Datatables AJAX 请求未正确命中 Web API

路由未命中控制器

在新页面上加载 ajax 成功数据

MVC .NET 表单提交未命中控制器操作