2

我从事一个 ASP.NET MVC 项目,该项目需要能够以可扩展的方式过滤数据。我决定使用一个类来表示单个过滤条件(我知道Dictionary此时它可能是一个,但我可能需要稍后添加其他属性):

public class FilterCriterion
{
    public string FilterName { get; set; }

    public string FilterValue { get; set; }
}

这是我想到的控制器方法签名,它将返回过滤后的数据:

public JsonResult GetMultipleShowDetailsByFilter(IEnumerable<FilterCriterion> filters, int pageNumber, int itemsPerPage)

该方法将从网页调用(使用 JavaScript),并返回一个 JSON,其中包含一组实体,然后将显示在页面上。

我假设我需要某种转换器来接受原始状态的参数并创建和实现可枚举的对象IEnumerable<FilterCriterion>。也许我可以使用 a ModelBinder,但我不确定如何使用。

你能把我推向正确的方向吗?谢谢。

编辑:我没有按照建议传递数组。当我进入控制器时,里面有正确数量的项目filters,但它们的属性(FilterName 和 FilterValue)都是 null。下面我发布完整的代码以及客户端过滤器对象的内容。我究竟做错了什么?Javascript代码:

function filterChanged() {
    var activeFilters = $(':checked');
    var filters = new Array();
    $.each(activeFilters, function (i, val) {
        var newItem = new Object();
        newItem.FilterName = $(val).attr('data-filter-type');
        newItem.FilterValue = $(val).attr('data-filter-value');
        filters[i] = newItem;
    });

    $.getJSON('../DatabaseApi/GetMultipleShowDetailsByFilter',
        {
            'filters': filters,
            'pageNumber': 1,
            'itemsPerPage': 10
        },
        function(data) {
            fill(data);
        });
}

创建的对象看起来如何(证明有数据,取自 VS Immediate Window):

?filters
[[object Object],[object Object]]
    [0]: {...}
    [1]: {...}
    [prototype]: []
?filters[0]
{...}
    [prototype]: {...}
    FilterName: "Genre"
    FilterValue: "Animation"
4

2 回答 2

3
  1. 将您的控制器签名更改为

    public JsonResult GetMultipleShowDetailsByFilter(FilterCriterion[] filters, int pageNumber, int itemsPerPage)
    
  2. 使用以下POST结构:

    filters[0].FilterName = 'aaa'
    filters[0].FilterValue = 'bbbb'
    filters[1].FilterName = 'ccc'
    filters[1].FilterValue = 'ddd'
    ...
    filters[n].FilterName = 'xxx'
    filters[n].FilterValue = 'yyy'
    

    (你可以很容易地用 jQuery 做到这一点)

一个警告:您的索引编号应该是连续的,即没有间隙。

更新主题启动器的更新:您必须非常小心POST结构。嵌套的 JavaScript 对象不行。尝试使用这个:

function filterChanged() {
    var activeFilters = $(':checked');
    var data = {
        'pageNumber': 1,
        'itemsPerPage': 10
    }
    $.each(activeFilters, function (i, val) {
        data['filters[' + i + '].FilterName'] = $(val).attr('data-filter-type');
        data['filters[' + i + '].FilterValue'] = $(val).attr('data-filter-value');
    });

    $.getJSON('../DatabaseApi/GetMultipleShowDetailsByFilter',
        data,
        function(data) {
            fill(data);
        });
}
于 2012-07-28T19:53:28.547 回答
2

看到这个链接,在这里你可以看到插件ToDictionary工作得很好并且解决了这些问题,让我们的代码更干净:

JS:

function filterChanged() {

    var filters = [];
    $(':checked').each(function (i, el) {
        filters.push({
            'FilterName': $(this).data('filter-type'),
            'FilterValue': $(this).data('filter-value')
        });
    });

    var data = $.toDictionary({
        'filters': filters,
        'pageNumber': 1,
        'itemsPerPage': 10
    });

    var response = function (data) {
        fill(data);
    };

    $.getJSON('../DatabaseApi/GetMultipleShowDetailsByFilter', data, response);
}

根据回复:链接

于 2012-07-28T22:03:43.917 回答