通过MVC操作方法从jQuery ajax发出的空响应



我在这样的布局中有一个库存应用程序:

<body>
<div class="container" style="width: 100%">
        <div id="header"> blahblahblah </div>
        <div class="row">
            <div id="rendermenu" class="col-sm-2">
                @Html.Action("Menu", "Nav")
            </div>
            <div id="renderbody" class="col-sm-10">
                @RenderBody()
            </div>
    </div>
</div>

Home控制器中,有一种操作方法,可以过滤发送到视图的存储库:

public ActionResult Index(string categoria, string marca)
{
    InventarioViewModel viewModel = new InventarioViewModel
    {
        Inventario = repository.GetInventario()
            .Where(i => (categoria == null || i.Item.Categoria == categoria)
                     && (marca == null || i.Item.Marca == marca))
            .OrderBy(i => i.Qta > 0)
            .ThenBy(i => i.Item.Categoria)
            .ThenBy(i => i.Item.Marca)
            .ThenBy(i => i.Item.Modello).ToList(),
        CategoriaCorrente = categoria,
        MarcaCorrente = marca
    };
    return View(viewModel);
}

它可以正常工作,但仅通过在浏览器中键入所需路由。因此,我通过将<select>元素放置给用户提供项目类别,然后将AJAX调用绑定到其change事件,从而编写过滤器。这是菜单视图的标记:

@using Magazzino.Domain.Infrastructure
@using Magazzino.Domain.Entities
@model List<Item>
@{ IEnumerable<Item> items = Model.DistinctBy(x => x.Categoria); }
<div class="text-center">Filtra per:</div>
<hr />
<div class="text-center">Categoria</div>
<select class="form-control lista-categorie" id="lista-categorie" data-action-url="@Url.Action("Index", "Home")" name="categoria">
    <option value>-- seleziona --</option>
    @foreach (Item item in items)
    {
        <option value="@item.Categoria">@item.Categoria</option>
    }
</select>

这是Ajax调用,放入通常的$(文档)。dready(...):

$('#lista-categorie').on('change', function () {
    var e = $(this)[0];
    if (e.selectedIndex > 0) {
        var ajaxRequest = $.ajax({
            url: "/",
            type: "get",
            data: {
                categoria: e.options[e.selectedIndex].value,
                marca: null
            }
        })
        ajaxRequest.done(function (response) {
            $('#renderbody').html(response);
        });
    }
});

我还更改了呈现视图的控制器的一部分:

if (Request.IsAjaxRequest())
{
    return PartialView(viewModel);
}
else
{
    return View(viewModel);
}

但是我只得到一个空字符串。如果尝试获取完整视图,我会发现响应具有整个页面(布局和菜单) index视图:

// previous markups from layout and menu
        <div id="renderbody" class="col-sm-10">


        </div>
    </div>
</div>
// other markups

我确定索引操作方法是触发的,因为我放了一个断点。不过,当我更改以这种方式更改Ajax的时刻,它可以正常工作:

var ajaxRequest = $.ajax({
            url: "/" + e.options[e.selectedIndex].value,
            type: "get"
        })

,但我真的不喜欢这种解决方法,我想拥有一种将数据传递给控制器的更普通,有效的方法。

如何改变此行为?

完全我的坏:我重新编辑了这个问题,因为当我说"我确定ViewModel被填充了"时,这是真实的。我只检查了动作方法是触发的。

我现在检查了ViewModel并发现了问题:我没有考虑到Ajax调用发送的" null"值实际上不是null,而是空字符串。我已经相应地更改了linq表达式,它起作用

InventarioViewModel viewModel = new InventarioViewModel
{
    Inventario = repository.GetInventario()
        .Where(i => (string.IsNullOrEmpty(categoria) || i.Item.Categoria == categoria) 
                 && (string.IsNullOrEmpty(marca) || i.Item.Marca == marca))
        .OrderBy(i => i.Qta > 0)
        .ThenBy(i => i.Item.Categoria)
        .ThenBy(i => i.Item.Marca)
        .ThenBy(i => i.Item.Modello).ToList(),
    CategoriaCorrente = categoria,
    MarcaCorrente = marca
};

尽管是一个琐碎的虫子(这是一个令人尴尬的时刻),但我想回答自己的问题,并为那些可能面临同样问题的人留下来。

欢呼。

$('#lista-categorie').on('change',method_attached_to_event);
function method_attached_to_event(){
  var e = $(this)[0];
  if (e.selectedIndex > 0) {
    var url = '/';
    var obj = {};
    obj.categoria= e.options[e.selectedIndex].value;
    $.ajax({
      url:url,
      method:'POST',
      data:obj,
      success:success,
      error:error
    }); 
  }else{
    // Do something else
  }
}
function success(data,status,jqxhr){
   console.log(data);
}
function error( jqxhr, status, error ){
   console.log(status);
   console.log(error);
   console.log(jqxhr);
}

最新更新