Search code examples
c#asp.net-mvcdatatablesserver-side

Serverside DataTables Search returning NULL for string Item


I am having an issue with my search on the dataTable. When I search for anything it errors with

System.NullReferenceException: 'Object reference not set to an instance of an object.'
MyProject.GeneralDTO.Entities.ProductMastView.PartNumber.get returned null.

This is strange because it is a string and it does contain the character that I am typing in. I am searching on two columns, if I eliminate the PartNumber from the search it searches the Vendor (Name) just fine. I am not sure if this is a model issue or a SQL issue. It is marked string in the model.

Below is my controller:

    [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<ProductMastView> prodList = new List<ProductMastView>();
        using (GeneralEntities db = new GeneralEntities())
        {
            prodList = db.ProductMastView.ToList();
            int totalRows = prodList.Count;
            if (!string.IsNullOrEmpty(searchValue))
            {
                prodList = prodList.Where(x => x.PartNumber.ToLower().Contains(searchValue.ToLower()) || x.Name.ToLower().Contains(searchValue.ToLower())).ToList();
            }
            int totalRowsAfterFilteing = prodList.Count;
            // Sorting
            prodList = prodList.OrderBy(sortColumnName + " " + sortDirection).ToList<ProductMastView>();

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

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

Here is my Model:

 public class ProductMastView
{
    [Key]
    public Guid ProductMasterId { get; set; }

    [Display(Name = "Vendor")]
    public string Name { get; set; }

    [Display(Name = "Part #")]
    public string PartNumber { get; set; }

    [Display(Name = "Image")]
    public string PartImage { get; set; }

    [Display(Name = "V Key")]
    public string VendorKey { get; set; }

    [Display(Name = "V Ref")]
    public string VendorRef { get; set; }

    [Display(Name = "Created")]
    [DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = false)]
    public DateTime? CreatedDate { get; set; }

    [Display(Name = "Created By")]
    public string CreatedBy { get; set; }

    [Display(Name = "Updated")]
    [DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = false)]
    public DateTime? LastUpdated { get; set; }

    [Display(Name = "Updated By")]
    public string UpdatedBy { get; set; }

    [Display(Name = "UOM")]
    public string UnitOfMeasure { get; set; }
    //[Display(Name = "Sell Price")]
    //public decimal SellingPrice { get; set; }
    [Display(Name = "Standard")]
    public decimal StandardCost { get; set; }

    [Display(Name = "Average")]
    public decimal AverageCost { get; set; }

    [Display(Name = "Last")]
    public decimal LastCost { get; set; }

    public bool IsPrimary { get; set; }

    [Display(Name = "Lead")]
    public string LeadTime { get; set; }

    [Display(Name = "Sell Price")]
    [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
    public decimal SellingPrice { get; internal set; }
}

Here is my view javascript:

   $(document).ready(function () {
    var oTableMenuPermission = "";
    var ControlerNameProductMasters = "@Url.Content("~/ProductMasters")";
    //var oTableMenuPermission = "";
    //oTableMenuPermission =
    $("#PartsListTable").dataTable({
        "ajax": {
            "url": "/ProductMasters/GetList",
            "type": "POST",
            "datatype": "json"
        },
        "responsive": true,
        "bRetrieve": true,
        "bProcessing": true,
        "deferRender": true,
        "dom": 'lBfrtip',
        "serverSide": "true",
        "order": [0, "PartNumber"],
        //"processing": "true",
        "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: [/*{ visible: false, targets: [3] },*/ { orderable: false, targets: [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13] }],
        //"pageLength": 10,
        //"lengthMenu": [[5, 10, 25, 50, -1], [5, 10, 25, 50, "All"]],

        "aoColumns": [
            { "data": "PartNumber", "name": "PartNumber" },
            { "data": "PartImage", "name": "PartImage" },
            { "data": "Name", "name": "Name" },
            { "data": "VendorRef", "name": "VendorRef" },
            {
                "data": "CreatedDate", "render": function (value) {
                    if (value === null) return "";
                    return moment(value).format('MM/DD/YYYY');
                }
            },
            { "data": "CreatedBy", "name": "CreatedBy" },
            {
                "data": "LastUpdated", "render": function (value) {
                    if (value === null) return "";
                    return moment(value).format('MM/DD/YYYY');
                }
            },
            { "data": "UpdatedBy", "name": "UpdatedBy" },
            { "data": "UnitOfMeasure", "name": "UnitOfMeasure" },
            { "data": "StandardCost", "name": "StandardCost" },
            { "data": "AverageCost", "name": "AverageCost" },
            { "data": "LastCost", "name": "LastCost" },
            { "data": "IsPrimary", "name": "Isprimary" },
            {
                "mRender": function (oObj, type, full) {
                    var buttons = '<div>'
                    buttons += '<div class="btn-group">';
                    buttons += '<a class="btn btn-info btn-sm" href="' + ControlerNameProductMasters + "/Details/" + full.ProductMasterId + '" 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;'
                    buttons += '</div>';
                    buttons += '<div class="btn-group">';
                    buttons += '<a class="btn btn-warning btn-sm" href="' + ControlerNameProductMasters + "/Edit/" + full.ProductMasterId + '" 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">Edit</a>&nbsp;';
                    buttons += '</div>';
                    buttons += '<div class="btn-group">';
                    buttons += '<a class="btn btn-danger btn-sm" href="' + ControlerNameProductMasters + "/Delete/" + full.ProductMasterId + '" data-ajax-update="#SkDelete" data-ajax-success="openModalDialog(\'SkDelete\', \'Delete\')" data-ajax-mode="replace" data-ajax-method="GET" data-ajax-failure="clearModalDialog(\'SkDelete\');alert(\'Ajax call failed\')" data-ajax-begin="prepareModalDialog(\'SkDelete\')" data-ajax="true"> Delete</a>';
                    buttons += '</div></div>';
                    return buttons;
                }
            },

        ],


    });
    //table.buttons().container()
    //    .appendTo($('.col-lg-8:eq(0)', table.table().container()));
});

Thank you for your help!


Solution

  • In your Where expression, you you are calling

    x.PartNumber.ToLower()
    

    It seems that at least one of the items in prodList has a PartNumer of null

    You could try adding a check in like this

    prodList = prodList.Where(x 
        => x.PartNumber != null
        && x.PartNumber.ToLower().Contains(searchValue.ToLower()) ...
    

    This will first check that x.PartNumber is not null before calling ToLower()