Editing multiple rows with an ' in a column values gives me an error

Editing multiple rows with an ' in a column values gives me an error

Jason B JonesJason B Jones Posts: 13Questions: 3Answers: 1

When editing multiple records and one column value has an ' in it, the editor will return an error of A potentially dangerous Request.Form value was detected from the client (data[row_1837][Dealership_Names]="ej's air condition...").'

Also when editing multiple rows with an & the & is replaced with @amp.

I am unable to get debug information due to this error. If I edit the row one at a time it works just fine. I am not sure what to do with this.

I could not find a place to add a test case for editor, if there is one I am happy to use it.

Answers

  • allanallan Posts: 63,542Questions: 1Answers: 10,476 Site admin

    Hi,

    For the first part, checkout this SO post. It is because of the validation being performed. Depending on what .NET methodology you are using and what version, how to resolve it will differ.

    For the second part, have a look at this part of the Editor security manual. It does automatic XSS protection by encoding entities. That might not always be desired, so you can turn it off. If you do so, make sure you use a text renderer in DataTables to protect against XSS attacks.

    Allan

  • Jason B JonesJason B Jones Posts: 13Questions: 3Answers: 1

    I tried the suggestions from both articles and it still gives me the error. Would you like me to post my code and if so which parts?

  • allanallan Posts: 63,542Questions: 1Answers: 10,476 Site admin

    Can you show me your .NET controller please?

    Allan

  • Jason B JonesJason B Jones Posts: 13Questions: 3Answers: 1
    public ActionResult LoadContactExportInfo(string exportflag)
    {
    
        var exportsign = "=";
        if (exportflag == "exported")
            exportsign = "<>";
    
        var formData = HttpContext.Request.Form;
    
        using (var db = new DataTables.Database("sqlserver",
                   ConfigurationManager.ConnectionStrings["DBConnection"].ConnectionString))
        {
            var editor = new Editor(db, "ContactsExport", "id")
                .Model<ContactsExport>()
                .Field(new Field("YEAR")
                .Options(new Options()
                    .Table("DropDownList")
                    .Value("Text")
                    .Label("Text")
                    .Where((q) => q.Where("Dropdownname", "YEAR"))
                ))
                .Field(new Field("TERM")
                .Options(new Options()
                    .Table("DropDownList")
                    .Value("Text")
                    .Label("Text")
                    .Where((q) => q.Where("Dropdownname", "TERM"))
                ))
                .Where("ExportedDate", null, exportsign)
                ;
    
    
            editor.PreEdit += (sender, e) =>
            {
                var newstuff = e.Values;
                int ID = 0;
                ID = Convert.ToInt32(e.Id.ToString());
                if (ID > 0)
                {
                    var grossvalue = newstuff["Gross_Total"];
                    var newtotal = newstuff["NewTotal"];
                    var newrate = Convert.ToDecimal(newtotal.ToString()) / Convert.ToDecimal(grossvalue.ToString());
                    e.Values["DiscountRate"] = newrate;
    
                }
            };
    
            var response = editor.Process(formData).Data();
    
            var jsonResult = Json(response, JsonRequestBehavior.AllowGet);
    
            return jsonResult;
    
            //return Json(editor, JsonRequestBehavior.AllowGet);
        }
    }
    
  • Jason B JonesJason B Jones Posts: 13Questions: 3Answers: 1

    function getContactsExportTable() {

     ContactsExportTableEditor = new $.fn.dataTable.Editor({
         ajax: {
             url: "/Contacts/LoadContactExportInfo?exportflag=" + _export,
             datasrc: ''
    
             //data: function (d) {
             //    d.selectedInvoices = jsonObjects;
             //},
             //error: function (xhr, error, code) {
             //    alert(xhr.responseText);
             //}
         },
         table: "#ContactsExportTable",
         fields: [
             { label: "Account", name: "Account", type: "text" },
             { label: "Dealership_Names", name: "Dealership_Names", type: "text" },
             {
                 label: "Submitted Date",
                 name: "SubmittedDate",
                 type: 'datetime',
                 def: function () { return new Date(); },
                 format: 'MM-DD-YYYY',
                 fieldInfo: 'US style mm-dd-yyyy',
             },
             {
                 label: "Due Date",
                 name: "DueDate",
                 type: 'datetime',
                 def: function () { return new Date(); },
                 format: 'MM-DD-YYYY',
                 fieldInfo: 'US style mm-dd-yyyy',
             },
             { label: "MKTMGR", name: "MKTMGR", type: "text" },
             { label: "MFType", name: "MFType", type: "text" },
             { label: "Reference", name: "Reference", type: "text" },
             { label: "DealerType", name: "DealerType", type: "text" },
             {
                 label: "TERMS", name: "TERM", type: "select",
                 placeholder: "--Select--",
                 placeholderValue: null,
                 attr: {
                     required: true,
                     placeholder: 'TERMS'
                 }
             },
             { label: "YEAR", name: "YEAR", type: "select" },
             { label: "Gross_Total", name: "Gross_Total", type: "text" },
             { label: "DiscountRate", name: "DiscountRate", type: "text" },
             { label: "NewTotal", name: "NewTotal", type: "text" }
         ]
     });
    
     //$('#ContactsExportTable').on('click', 'tbody td:not(:first-child)', function (e) {
     //    editor.inline(this, {
     //        buttons: { label: '&gt;', fn: function () { this.submit(); } }
     //    });
     //});
    
     ContactsExportTable = $("#ContactsExportTable").DataTable({
         processing: true, // for show progress bar
         serverSide: false, // for process server side
         filter: true, // this is for disable filter (search box)
         orderMulti: true, // for disable multiple column at once
         /*    pageResize: true,*/
         scrollCollapse: true,
         pageLength: 15,
         paging: true,
         destroy: true,
         pageResize: true,
         autowidth: false,
         /* scrollX: true,*/
         /*   scrollY: "80vh",*/
         lengthMenu: [[5, 10, 15, 20, 25, 50, 100, 1000, -1], [5, 10, 15, 20, 25, 50, 100, 1000, "All"]],
         responsive: true,
         /*  "deferLoading": 10,*/
         async: true,
         /*  *//* recordsTotal: 50,*/
         select: true,
         /*oSearch: { "sSearch": $('input[type=search]').val() },*/
         lengthChange: true,
    
         dom: '<"ContactsExportheader">lBfrtip',
         ajax: {
             url: "/Contacts/LoadContactExportInfo?exportflag=" + _export,
             type: "POST",
             dataType: "json",
             beforeSend: function (x) {
                 if (x && x.overrideMimeType) {
                     x.overrideMimeType("application/j-son;charset=UTF-8");
                 }
             }
             //error: function (xhr, error, code) {
             //    alert('Contact' + xhr.responseText);
             //}
         },
         columns: [
             { data: "id", visible: false },
             { data: "Contactid" },
             { data: "Account" },
             { data: "Dealership_Names" },
             { data: "Branch" },
             { data: "SubmittedDate" },
             { data: "TERM" },
             { data: "DueDate" },
             { data: "MKTMGR" },
             { data: "MFType" },
             { data: "Reference" },
             { data: "DealerType" },
             { data: "YEAR" },
             { data: "Gross_Total" },
             { data: "DiscountRate" },
             { data: "NewTotal" }
    
         ],
         initComplete: function () {
    
    
             $("div.ContactsExportheader").html("<h2>Contact Exports</h2>");
    
             $('tr#filterContactExportboxrow th').each(function () {
    
                 var name = ($(this).text());
                 var index = $(this).index();
    
                 if ($('#binput' + $(this).index()).length === 0) {
                     $(this).html('<span> ' + name + '</span ><input type="Search" id="binput' + index + '" class="form-control toggle-vis clearable-input" />').css('padding-left', '4px');
                 }
    
                 $(this).on('input keyup change',
                     function () {
                         var val;
    
                         val = $('#binput' + $(this).index()).val();
    
                         var addcol = 1;
    
                         ContactsExportTable.column(index + addcol).search(val).draw();
    
                     });
             });
    
             $("#ContactsExportTable").wrap("<div class='contactwrap'></div>");
    
             $('a.toggle-vis').on('click',
                 function (e) {
                     e.preventDefault();
                     var addcol = 1; // hidden fields
                     var index = parseInt($(this).attr('data-column')) + addcol;
                     // Get the column API object
                     var column = ContactsExportTable.column(index);
                     // Toggle the visibility
    
                     column.visible(!column.visible());
                     if (!column.visible())
                         $(this).addClass("red");
                     else
                         $(this).removeClass("red");
                 });
    
             $("div.Contactsheader").html("<h2 class='Contactsth2'>Contact Export to Sage</h2>");
             $("div.Contactsheader").css({ "height": "0" });
    
    
             if ($("#ddlexport").length === 0) {
                 var ddlexport = '<select id="ddlexport">';
    
                 if (_export === 'exported') {
                     ddlexport += '<option selected value="exported">exported</option>';
                     ddlexport += '<option value="notexported">not exported</option>';
                 }
                 else if (_export === 'not exported' || _export === '') {
                     ddlexport += '<option selected value="exported">exported</option>';
                     ddlexport += '<option value="notexported">not exported</option>';
                 }
                 ddlexport += '</select>';
    
                 $(".dt-buttons").append(ddlexport);
    
                 $("#ddlexport").change(function () {
                     _export = $("#ddlexport option:selected").text();
                     getContactsExportTable();
    
                 });
             }
    
             if (_export === 'not exported' || _export === '')
                 _export = 'notexported';
    
             $("#ddlexport").val(_export);
    
         },
         //select: {
         //    style: 'os',
         //    selector: 'td:first-child'
         //},
         buttons: [
             { extend: "edit", text: "Edit", className: 'button-7', editor: ContactsExportTableEditor },
             {
                 text: 'Export', className: 'button-7 ',
                 action: function (e, dt, node, config) {
    
                     var currentRow = ContactsExportTable.rows({ selected: true }).data();
    
    
                     var ExportList = [{}];
                     //alert(currentRow[0].WriteOffsId);
                     for (var i = 0; i < currentRow.length; i++) {
                         ExportList[i] = { ID: currentRow[i].id };
                     }
    
                     ExportList = JSON.stringify({ 'ExportList': ExportList });
    
                     $.ajax({
                         contentType: "application/json; charset=utf-8",
                         dataType: "json",
                         type: "POST",
                         url: '/Contacts/CreateExport',
                         data: ExportList,
                         success: function (data) {
                             var options = {};
                             options.url = "https://api.apps.siglers.com/Home/MoveMarketingFiles";
                             $.ajax(options);
                             alert("Export was Successful");
                             $('#ContactsExportTable').DataTable().ajax.reload();
                         },
                         error: function (response) {
                             alert("Export was Successful!");
                         }
                     });
                 }
             },
         ]
     });
    
     $('#ContactsExportTable tbody').on('click', 'tr', function () {
         $(this).toggleClass('selected');
         if (!$(this).hasClass("selected")) {
             $('.ContactexcelAll').addClass('show').removeClass('hide');
             $('.ContactexcelSelected').addClass('hide').removeClass('show');
         } else {
             $('.ContactexcelAll').addClass('hide').removeClass('show');
             $('.ContactexcelSelected').addClass('show').removeClass('hide');
    
         }
     });
    

    }

  • Jason B JonesJason B Jones Posts: 13Questions: 3Answers: 1

    <body>
    <table id="ContactsExportTable" class="table table-striped table-bordered dt-responsive ">
    <thead>
    <tr id="filterContactExportboxrow">
    <th>id</th>
    <th>Contact id</th>
    <th>Account</th>
    <th style="min-width:400px;">Dealership Names</th>
    <th>Branch</th>
    <th>Submitted Date</th>
    <th>Terms</th>
    <th>Due Date</th>
    <th>MKTMGR</th>
    <th>MFType</th>
    <th>Reference</th>
    <th>Dealer Type</th>
    <th>YEAR</th>
    <th>Gross Total</th>
    <th>Discount Rate</th>
    <th>New Total</th>
    </tr>
    </thead>
    </table>
    </body>

  • allanallan Posts: 63,542Questions: 1Answers: 10,476 Site admin

    This is for WebAPI is it? What version of .NET are you using?

    In addition to adding this attribute to the controller:

    [HttpPost, ValidateInput(false)]
    

    This SO thread suggests that you need to modify the web.config file as well.

    Allan

  • Jason B JonesJason B Jones Posts: 13Questions: 3Answers: 1

    I am using 4.7.2

  • allanallan Posts: 63,542Questions: 1Answers: 10,476 Site admin

    Oh! You are using .NET Framework? Does the solution from the last SO thread you posted work for you?

    Allan

  • Jason B JonesJason B Jones Posts: 13Questions: 3Answers: 1

    No, it did not

  • Jason B JonesJason B Jones Posts: 13Questions: 3Answers: 1

    I know I should upgrade to ASP Core, having a hard time finding the time. I am on 6 web projects, managing two programmers and I am the only DBA. My goal is to upgrade to ASP Core sometime this year.

  • allanallan Posts: 63,542Questions: 1Answers: 10,476 Site admin

    Haha - I have goals for this year as well. Let's compare notes for how far we got in January 2025 ;)

    Try this one from the SO thread. It specifically is talking about .NET 4.

    Allan

Sign In or Register to comment.