MVC3& JSON.stringify()ModelBinding返回null模型

时间:2011-09-29 13:16:44

标签: c# jquery asp.net json asp.net-mvc-3

我正在尝试使用MVC3和JSON进行模型绑定,但我没有运气......无论我做什么,我似乎都在服务器上获得null模型。

方法签名:

public ActionResult FilterReports(DealSummaryComparisonViewModel model)

Javascript 更新

<script type="text/javascript" language="javascript">

    $(document).ready(function () {
        $('#filter-reports').click(filterReports);
    });

    function filterReports() {
        var filters = {
            SelectedRtoId: $('#SelectedRtoId').val(),
            SelectedPricingPointId: $('#SelectedPricingPointId').val(),
            SelectedLoadTypeId: $('#SelectedLoadTypeId').val(),
            SelectedBlockId: $('#SelectedBlockId').val(),
            SelectedRevisionStatusId: $('#SelectedRevisionStatusId').val()
        }
        var dealSummaries = { SelectedItemIds: $('#SelectedItemIds').val() }
        var model = { ReportingFilters: filters, DealSummaries: dealSummaries }

        $('#selected-items select option').attr("selected", "selected");
        $.ajax({
            url: '@Url.Action("FilterReports")',
            data: model,
            contentType: 'application/json',
            dataType: 'json',
            success: function (data) {
                alert(data);
            }
        }); 
    }
</script>

型号:

public class DealSummaryComparisonViewModel
{
    public ReportingFiltersViewModel ReportingFilters { get; set; }
    public LadderListViewModel DealSummaries { get; set; }
}

public class LadderListViewModel
{
    public MultiSelectList AvailableItems { get; set; }

    public int[] SelectedItemIds { get; set; }
    public MultiSelectList SelectedItems { get; set; }
}

public class ReportingFiltersViewModel
{
    public int? SelectedRtoId { get; set; }
    public ICollection<Rto> Rtos { get; set; }

    public int? SelectedPricingPointId { get; set; }
    public ICollection<PricingPoint> PricingPoints { get; set; }

    public int? SelectedLoadTypeId { get; set; }
    public ICollection<LoadType> LoadTypes { get; set; }

    public int? SelectedBlockId { get; set; }
    public ICollection<Block> Blocks { get; set; }

    public int? SelectedRevisionStatusId { get; set; }
    public ICollection<RevisionStatus> RevisionStatuses { get; set; }

    public bool? DealStatus { get; set; }
}

该模型在客户端看起来很好:

{"ReportingFilters":{
    "SelectedRtoId":"5",
    "SelectedPricingPointId":"20",
    "SelectedLoadTypeId":"55",
    "SelectedBlockId":"21",
    "SelectedRevisionStatusId":"11" 
},"DealSummaries":{
    "SelectedItemIds":["21","22","23","24","25"] 
}}

那么为什么我什么也得不到控制器?过去两天这给了我麻烦所以请帮忙!谢谢!

更新 我已将我的javascript部分更新为我目前正在使用的部分。此部分现在使用ReportingFilers和DealSummaries对象将模型返回给控制器,但其中的所有值都为null。

它可能与作为字符串的值有关吗?如果是这样,我该如何解决这个问题?

5 个答案:

答案 0 :(得分:4)

将$ .getJSON行更改为:

$.ajax({ 
   url: '@Url.Action("FilterReports")',
   data: JSON.stringify(viewModel),
   contentType: 'application/json',
   dataType: 'json',
   success: function (data) { alert(data); }
});

这样MVC知道它正在接收JSON并将它正确地绑定到你的模型。

答案 1 :(得分:3)

您可以尝试以下几种不同的方法:

  • 如果您想使用DefaultModelBinderASP.NET MVC3 JSON Model-binding with nested class,显然您不应在对象中使用可空属性。所以你可以尝试让你的int不可为空,或者如果那不是一个选项,你自己实现IModelBinder

  • 您是否使用SerializableAttribute

  • 标记了您的课程
  • 尝试将ajax方法中的type参数设置为'POST' - 默认情况下将使用'GET'。type: 'POST'

  • 尝试将ajax方法中的contentType参数显式设置为此... contentType: 'application/json; charset=utf-8'

  • 最后,你肯定使用的是MVC 3,而不是MVC 2吗?我问,因为MVC 3将JsonValueProviderFactory加入到框架中,而MVC 2没有这样,如果你使用的MVC 2可以解释你所遇到的问题......

答案 2 :(得分:2)

好的,替换:

{ model: JSON.stringify(viewModel) }

{ model: viewModel }

您正在使用JSON字符串混合对象,因此jQuery将JSON.stringify整个对象。这将对viewModel进行双重编码。

答案 3 :(得分:1)

这是我建议的,在你的控制器中,动作方法应如下所示:

public JsonResult FilterAction(string model)
{
   var viewModel=new JavaScriptSerializer().Deserialize<DealSummaryComparisonViewModel>(model);
}

同时确保您的请求达到正确的操作并查看Firebug。

答案 4 :(得分:0)

试试这个:

var filters = new Object();
filters.SelectedRtoId = $('#SelectedRtoId').val();
filters.SelectedPricingPointId =  $('#SelectedPricingPointId').val();
filters.SelectedLoadTypeId = $('#SelectedLoadTypeId').val();
filters.SelectedBlockId = $('#SelectedBlockId').val();
filters.SelectedRevisionStatusId = $('#SelectedRevisionStatusId').val();

var dealSummaries = new Object(); 
dealSummarties.SelectedItemIds = $('#SelectedItemIds').val();

var viewModel = new Object(); 
viewModel.ReportingFilters = filters;
viewModel.DealSummaries = dealSummaries;

$('#selected-items select option').attr("selected", "selected");
$.getJSON('@Url.Action("FilterReports")', { model: JSON.stringify(viewModel) }, function (data) {
            alert(data);
});