服务器端数据表搜索为字符串项返回 NULL

Serverside DataTables Search returning NULL for string Item

我在 dataTable 上搜索时遇到问题。当我搜索任何错误时

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

这很奇怪,因为它是一个字符串并且确实包含我输入的字符。我在两列上进行搜索,如果我从搜索中删除 PartNumber,它会很好地搜索供应商(名称)。我不确定这是模型问题还是 SQL 问题。它在模型中被标记为字符串。

下面是我的控制器:

    [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);
        }
       
    }

这是我的模型:

 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; }
}

这是我的观点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()));
});

感谢您的帮助!

在你的Where表达式中,你在调用

x.PartNumber.ToLower()

似乎 prodList 中至少有一项的 PartNumernull

您可以尝试像这样添加签到

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

这将在调用 ToLower()

之前首先检查 x.PartNumber 是否为空