Data Tables Editor MVC Routing & Ajax Error

Data Tables Editor MVC Routing & Ajax Error

dpanscikdpanscik Posts: 202Questions: 47Answers: 0

I have a proof of concept successfully working from Editor Generator.

Now I'm pushing forward trying to integrate editor into an existing project, here is the latest challenge.

I need help.

I am getting the following error in the bowser that tells me AJAX request isn't making it to the controller.

Here is the error in the browser.

I am using two routers. The original MVC router, plus now Ive added in the router for the datatable editor api. I don't quite understand why datatable editor needs a router different than the stock MVC router, so I decided to not question the reason and include both routers in my MVC project.

Here is the original MVC router (filename: App_Start/RouteConfig.cs)

// ----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
// ----------------------------------------------------------------------------

namespace AppOwnsData
{
    using System.Web.Mvc;
    using System.Web.Routing;

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

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

and here is the router for DataTable editor (filename: App_Start/WebApiConfig.cs)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;

namespace AppOwnsData
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }
    }
}

Here is my controller (filename Controller/OnCallController.cs):
I put a program break on line 22, and its not getting triggered so I know the AJAX request isn't making it to the controller.

namespace AppOwnsData.Controllers
{
    public class OnCallController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }
    }
    public class OnCallDataController : ApiController
    {
        [System.Web.Http.Route("api/OnCallData")]
        [System.Web.Http.HttpGet]
        [System.Web.Http.HttpPost]
        public IHttpActionResult DataTransport()
        {
            var settings = Properties.Settings.Default;
            var request = HttpContext.Current.Request;


            using (var db = new Database(settings.DbType, settings.DbConnection))
            {
                var response = new Editor(db, "Flex_OnCal", "TableID")
                    .Model<Flex_OnCall>()
                    .Field(new Field("day")
                            .Validator(Validation.DateFormat(Format.DATE_ISO_2822))
                            .GetFormatter(Format.DateSqlToFormat(Format.DATE_ISO_2822))
                            .SetFormatter(Format.DateFormatToSql(Format.DATE_ISO_2822))
                    )
                        .Process(request)
                    .Data();

                return Json(response);
            }
        }
    }
}

and here is my view. Filename(View/OnCall/index.cshtml)


@{ ViewBag.Title = "On Call"; Layout = "~/Views/Shared/_Layout.cshtml"; } <h2>On Call</h2> <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.13.3/css/jquery.dataTables.min.css"> <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/buttons/2.3.5/css/buttons.dataTables.min.css"> <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/select/1.6.1/css/select.dataTables.min.css"> <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/datetime/1.3.1/css/dataTables.dateTime.min.css"> <link href="~/Content/style/editor.dataTables.css" rel="stylesheet" /> <script src="https://code.jquery.com/jquery-3.5.1.js"></script> <script src="https://cdn.datatables.net/1.13.3/js/jquery.dataTables.min.js"></script> <script src="~/scripts/dataTables.responsive.min.js"></script> <script src="https://cdn.datatables.net/buttons/2.3.5/js/dataTables.buttons.min.js"></script> <script src="https://cdn.datatables.net/select/1.6.1/js/dataTables.select.min.js"></script> <script src="https://cdn.datatables.net/datetime/1.3.1/js/dataTables.dateTime.min.js"></script> <script type="text/javascript" src="~/scripts/dataTables.editor.min.js"></script> <style> </style> <script> var editor; $(document).ready(function () { editor = new $.fn.dataTable.Editor({ ajax: { create: { type: 'POST', url: 'api/OnCallData' }, edit: { type: 'PUT', url: 'api/OnCallData' }, remove: { type: 'DELETE', url: 'api/OnCallData' } }, table: "#onCall", fields: [{ label: "TableID", name: "TableID" }, { label: "Day", name: "Day" }, { label: "Shop", name: "Shop" }, { label: "Name", name: "Name" }, { label: "Phone", name: "Phone" }, { label: "Email", name: "Email" } ] }); $("#onCall").DataTable({ dom: "Bfrtip", order: [[2, 'asc']], "responsive": true, "processing": true, // for show progress bar "serverSide": true, // for process server side "filter": true, // this is for disable filter (search box) "orderMulti": false, // for disable multiple column at once "pageLength": 25, "ajax": { "url": "/api/OnCallData", "type": "POST", "datatype": "json", "data": function (d) { return $.extend({}, d, { "start_date": $('#datemin').val(), "form_id": "InboundGrid", }); } }, "columnDefs": [ { "defaultContent": "-", "targets": "_all" }, { "targets": [0], "visible": false, "searchable": false, "orderable": true, }, { "targets": [1], "visible": true, "searchable": true, "orderable": true, "type": "date", }, ], "columns": [ { "data": "TableID", "name": "ID", "title": "ID", "autoWidth": true }, { "data": "Day", "title": "Day", "name": "Day", "autoWidth": true, "type": "datetime", "format": "dddd, DD-MM-YY", "render": function (value) { if (value === null) return ""; const date = new Date(parseInt(value.replace(/\/+Date\(([\d+-]+)\)\/+/, '$1'))); const formattedDate = date.toLocaleDateString('en-GB', { day: 'numeric', month: 'short', year: 'numeric' }).replace(/ /g, '-'); return formattedDate; } }, { "data": "Shop", "title": "Shop", "name": "Shop", "autoWidth": true }, { "data": "Name", "title": "Name", "name": "Name", "autoWidth": true }, { "data": "Phone", "title": "Phone", "name": "Phone", "autoWidth": true }, { "data": "Email", "title": "Email", "name": "Email", "autoWidth": true }, ], select: true, buttons: [ { extend: "create", editor: editor }, { extend: "edit", editor: editor }, { extend: "remove", editor: editor } ] }); }); </script> </head> <body> <div class="container"> <br /> <div style="width:90%; margin:0 auto;"> <table border="0" class="display nowrap" style="width:100%" cellspacing="5" cellpadding="5"> <tbody> </tbody> </table> <table id="onCall" class="row-border table-striped table-bordered dt-responsive nowrap" width="100%" cellspacing="0"> <thead> <tr> <th></th> <th></th> <th></th> <th></th> <th></th> <th></th> <th></th> </tr> </thead> </table> </div> </div> </body> </html>

Answers

  • kthorngrenkthorngren Posts: 21,342Questions: 26Answers: 4,954

    Did you follow the troubleshooting steps at the link in the error?
    https://datatables.net/manual/tech-notes/7

    Basically use the browser's network inspector tool to see the request and more importantly the response. Let us know what you find.

    Kevin

  • dpanscikdpanscik Posts: 202Questions: 47Answers: 0
    edited March 2023

    Hi Kevin,

    I don't believe this is going to be the response from me that you were anticipating.

    As I stated above I am not getting into the controller.

    Therefore here is the response showing error where otherwise a successful ajax query one would expect to see a nice array.

    Here is a visual of the network inspector;

    and here is the response of OnCallData

    <html>
        <head>
            <title>The resource cannot be found.</title>
            <meta name="viewport" content="width=device-width" />
            <style>
             body {font-family:"Verdana";font-weight:normal;font-size: .7em;color:black;} 
             p {font-family:"Verdana";font-weight:normal;color:black;margin-top: -5px}
             b {font-family:"Verdana";font-weight:bold;color:black;margin-top: -5px}
             H1 { font-family:"Verdana";font-weight:normal;font-size:18pt;color:red }
             H2 { font-family:"Verdana";font-weight:normal;font-size:14pt;color:maroon }
             pre {font-family:"Consolas","Lucida Console",Monospace;font-size:11pt;margin:0;padding:0.5em;line-height:14pt}
             .marker {font-weight: bold; color: black;text-decoration: none;}
             .version {color: gray;}
             .error {margin-bottom: 10px;}
             .expandable { text-decoration:underline; font-weight:bold; color:navy; cursor:pointer; }
             @media screen and (max-width: 639px) {
              pre { width: 440px; overflow: auto; white-space: pre-wrap; word-wrap: break-word; }
             }
             @media screen and (max-width: 479px) {
              pre { width: 280px; }
             }
            </style>
        </head>
    
        <body bgcolor="white">
    
                <span><H1>Server Error in '/' Application.<hr width=100% size=1 color=silver></H1>
    
                <h2> <i>The resource cannot be found.</i> </h2></span>
    
                <font face="Arial, Helvetica, Geneva, SunSans-Regular, sans-serif ">
    
                <b> Description: </b>HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. &nbsp;Please review the following URL and make sure that it is spelled correctly.
                <br><br>
    
                <b> Requested URL: </b>/api/OnCallData<br><br>
    
                <hr width=100% size=1 color=silver>
    
                <b>Version Information:</b>&nbsp;Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.8.4330.0
    
                </font>
    
        </body>
    </html>
    

    -David

  • kthorngrenkthorngren Posts: 21,342Questions: 26Answers: 4,954

    This is in the response:

    HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable.  Please review the following URL and make sure that it is spelled correctly.

    That suggests the URL is incorrect or a misconfiguration in your server code. This is not an error with the Editor.

    Kevin

  • dpanscikdpanscik Posts: 202Questions: 47Answers: 0
    edited March 2023

    double post removed

  • dpanscikdpanscik Posts: 202Questions: 47Answers: 0
    edited March 2023

    Hi Kevin,

    I believe the issue is the router is not delivering the ajax request to the proper controller.

    I cant figure out why "editor generator" (https://editor.datatables.net/generator/) uses a custom router that is not the stock MVC router.

    I attempted to combine both the stock router (which is in use in my existing solution across 5 different data tables) and the router provided with "editor generator". It would appear the router provided via "editor generator" is not routing.

    I think I do not understand how to have two routers in one MVC project. The stock MVC router for general MVC controllers and datatables without an editor and a 2nd router for editor controllers.

  • dpanscikdpanscik Posts: 202Questions: 47Answers: 0

    Im so smart. I figured it out.

    In the file global.axas.cs

    change this;

    protected void Application_Start()
    {
    
    
    
     
        RouteConfig.RegisterRoutes(RouteTable.Routes);
    }
    

    to this

            protected void Application_Start()
            {
                //Route API
                GlobalConfiguration.Configure(WebApiConfig.Register);
    
                RouteConfig.RegisterRoutes(RouteTable.Routes);
            }
    
  • allanallan Posts: 63,523Questions: 1Answers: 10,473 Site admin

    Nice one - thanks for posting back. I'll look into how Generator is setting up routing - I was under the impression that it was fairly stock.

    Allan

Sign In or Register to comment.