Library For JQuery DataTables ASP.NET MVC

喜夏-厌秋 提交于 2019-11-30 10:37:05

I'm using a custom model binder and JsonConverter (for JSON.NET):

Example of a model containing data table request:

public class MyModel
{
   [JsonConverter(typeof(DataTableConverter))]
   public DataTableRequest DataTableRequest { get; set; }
   // other properties 
}

then the action method will look like:

[HttpPost] 
public virtual ActionResult GetDataTableData(MyModel myModel)
{
}

the data table DataTableRequest class. The GetOrderByExpression returns Dynamic Linq expression:

public class DataTableRequest
{
    public int PageIndex { get; private set; }
    public int PageSize { get; private set; }
    public string Search { get; private set; }
    private List<SortBy> SortingColumns { get; set; }

    public int SEcho { get; private set; }

    public DataTableRequest(int pageIndex, int pageSize, string search, List<SortBy> sortingColumns, int sEcho)
    {   
        PageIndex = pageIndex;
        PageSize = pageSize;
        Search = search;
        SortingColumns = sortingColumns;
        SEcho = sEcho;
    }

    public string GetOrderByExpression()
    {
        // could be passed to EntityFramework with DynamicLinq like query.OrderBy(dataTableRequest.GetOrderByExpression())
        var columnDirectionPairs = SortingColumns.Select(c => Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(c.Column.Replace("_", ".")) + " " + c.Direction);
        var orderByExpression = string.Join(", ", columnDirectionPairs);
        return orderByExpression;
    }

    public class SortBy
    {
        public SortBy(string column, string direction)
        {
            Guard.ArgumentNotNullOrEmpty(column, "column");
            Guard.ArgumentNotNullOrEmpty(direction, "direction");

            Column = column;
            Direction = direction;
        }

        public string Column { get; set; }
        public string Direction { get; set; }
    }
}

data table converter (used for serialization to json):

public class DataTableConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(DataTableRequest);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var jArray = JArray.Load(reader);

        var tableValueCollection = jArray.Select(x => new { Name = x["name"].Value<string>(), Value = x["value"].Value<string>() }).ToDictionary(x => x.Name, x => x.Value);

        var numberOfColumns = int.Parse(tableValueCollection["iColumns"], CultureInfo.InvariantCulture);

        var columns = new List<string>();

        for (int i = 0; i < numberOfColumns; i++)
        {
            var queryParamName = string.Format("mDataProp_{0}", i.ToString(CultureInfo.InvariantCulture));
            columns.Add(tableValueCollection[queryParamName]);
        }

        var numberOfSortingColumns = int.Parse(tableValueCollection["iSortingCols"], CultureInfo.InvariantCulture);
        var sortingColumns = new List<DataTableRequest.SortBy>();
        for (int i = 0; i < numberOfSortingColumns; i++)
        {
            var sortColQueryParamName = string.Format("iSortCol_{0}", i.ToString(CultureInfo.InvariantCulture));

            if (tableValueCollection[sortColQueryParamName] != null)
            {
                var sortDirQueryParamName = string.Format("sSortDir_{0}", i.ToString(CultureInfo.InvariantCulture));
                var sortingDirection = tableValueCollection[sortDirQueryParamName];

                var sortingColumnIndex = int.Parse(tableValueCollection[sortColQueryParamName], CultureInfo.InvariantCulture);
                var sortingColumnName = columns[sortingColumnIndex];

                sortingColumns.Add(new DataTableRequest.SortBy(sortingColumnName, sortingDirection));
            }
        }

        var displayStart = int.Parse(tableValueCollection["iDisplayStart"], CultureInfo.InvariantCulture);
        var displayLength = int.Parse(tableValueCollection["iDisplayLength"], CultureInfo.InvariantCulture);
        var pageSize = displayLength;
        var pageIndex = displayStart / displayLength;

        string search = null;

        if (tableValueCollection.ContainsKey("sSearch"))
        {
            search = tableValueCollection["sSearch"];
        }

        var sEcho = int.Parse(tableValueCollection["sEcho"], CultureInfo.InvariantCulture);

        var dataTableRequest = new DataTableRequest(pageIndex, pageSize, search, sortingColumns, sEcho);

        return dataTableRequest;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

DataTableModelBinder used to deserialize DataTableRequest object:

public class DataTableModelBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var request = controllerContext.HttpContext.Request;
        var contentType = request.ContentType;
        if (!contentType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase))
            return (null);

        request.InputStream.Seek(0, SeekOrigin.Begin);
        var bodyText = new StreamReader(request.InputStream).ReadToEnd();

        if (string.IsNullOrEmpty(bodyText)) return (null);

        var jsonObj = JObject.Parse(bodyText);
        var jArray = (JArray)jsonObj["aoData"];

        var tableValueCollection = jArray.Select(x => new { Name = x["name"].Value<string>(), Value = x["value"].Value<string>() }).ToDictionary(x => x.Name, x => x.Value);

        var numberOfColumns = int.Parse(tableValueCollection["iColumns"], CultureInfo.InvariantCulture);

        var columns = new List<string>();

        for (int i = 0; i < numberOfColumns; i++)
        {
            var queryParamName = string.Format("mDataProp_{0}", i.ToString(CultureInfo.InvariantCulture));
            columns.Add(tableValueCollection[queryParamName]);
        }

        var numberOfSortingColumns = int.Parse(tableValueCollection["iSortingCols"], CultureInfo.InvariantCulture);
        var sortingColumns = new List<DataTableRequest.SortBy>();
        for (int i = 0; i < numberOfSortingColumns; i++)
        {
            var sortColQueryParamName = string.Format("iSortCol_{0}", i.ToString(CultureInfo.InvariantCulture));

            if (tableValueCollection[sortColQueryParamName] != null)
            {
                var sortDirQueryParamName = string.Format("sSortDir_{0}", i.ToString(CultureInfo.InvariantCulture));
                var sortingDirection = tableValueCollection[sortDirQueryParamName];

                var sortingColumnIndex = int.Parse(tableValueCollection[sortColQueryParamName], CultureInfo.InvariantCulture);
                var sortingColumnName = columns[sortingColumnIndex];

                sortingColumns.Add(new DataTableRequest.SortBy(sortingColumnName, sortingDirection));
            }
        }

        var displayStart = int.Parse(tableValueCollection["iDisplayStart"], CultureInfo.InvariantCulture);
        var displayLength = int.Parse(tableValueCollection["iDisplayLength"], CultureInfo.InvariantCulture);
        var pageSize = displayLength;
        var pageIndex = displayStart / displayLength;

        string search = null;

        if (tableValueCollection.ContainsKey("sSearch"))
        {
            search = tableValueCollection["sSearch"];
        }

        var sEcho = int.Parse(tableValueCollection["sEcho"], CultureInfo.InvariantCulture);

        var dataTableRequest = new DataTableRequest(pageIndex, pageSize, search, sortingColumns, sEcho);

        return dataTableRequest;
    }
}

register model binder on Application_Start in Global.asax.cs:

ModelBinders.Binders.Add(typeof (DataTableRequest), new DataTableModelBinder());

I'm using DataTables 1.9.4 and following json model binder:

public class JsonModelBinder : DefaultModelBinder
{
    public static JsonSerializerSettings GlobalSerializerSettings
    {
        get
        {
            return new JsonSerializerSettings()
            {                    
                ContractResolver = new CamelCasePropertyNamesContractResolver(),                    
                Converters = { new IsoDateTimeConverter() }
            };
        }
    }

    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        if (!IsJSONRequest(controllerContext))
        {
            return base.BindModel(controllerContext, bindingContext);
        }
        // Get the JSON data that's been posted
        var request = controllerContext.HttpContext.Request;

        request.InputStream.Seek(0, SeekOrigin.Begin);
        var streamReader = new StreamReader(request.InputStream);
        var jsonStringData = streamReader.ReadToEnd();

        if (string.IsNullOrEmpty(jsonStringData))
            return null;

        return JsonConvert.DeserializeObject(jsonStringData, bindingContext.ModelMetadata.ModelType, GlobalSerializerSettings);
    }

    protected static bool IsJSONRequest(ControllerContext controllerContext)
    {
        var contentType = controllerContext.HttpContext.Request.ContentType;
        return contentType.Contains("application/json");
    }
}

replacing the default model binder:

ModelBinders.Binders.DefaultBinder = new JsonModelBinder();
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!