【问题标题】:MVC/AJAX - sent current Model collection to controllerMVC/AJAX - 将当前模型集合发送到控制器
【发布时间】:2014-09-09 11:02:52
【问题描述】:

在强类型列表视图中,我试图通过 Ajax 将当前数据(作为模型列表)传递给我的控制器,以便它可以使用它。

我面临的问题是,我似乎无法将当前视图中的数据列表传递给我的控制器。使用不带参数的 AJAX 方法有效(但我需要使用参数,或者是否有其他方法可以向我的控制器提供所述信息?)。

我也尝试在构建视图时创建一个列表(测试),然后将该变量用作参数,但显然在构建后变量为空?

索引视图

@model IEnumerable<databaseModel.cbms>

@{
    ViewBag.Title = "Cbms Home";
    List<databaseModel.cbms> test = Model.ToList();
}

@Ajax.ActionLink("productId", "AJX_SortByProductId", new { cbmsModel = test }, new AjaxOptions()
                    {
                        HttpMethod = "GET",
                        UpdateTargetId = "divCbms",
                        InsertionMode = InsertionMode.Replace
                    })

控制器

public PartialViewResult AJX_SortByProductId(List<cbms> cbmsModel)
        {            
            //Retrieves the data
            List<cbms> model = cbms.SortByProductId();
            //Returns the partial view
            return PartialView("_Cbms", model);
        }

所以,当我进入控制器时,List cbmsModel 是空的,我不能将它用作参数。我可以毫无问题地传递一个字符串,但我想在我的视图中列出当前模型数据。

编辑:

以下也不起作用:

型号

@model IEnumerable<databaseModel.cbms>

@{
    ViewBag.Title = "Cbms Home";
    List<databaseModel.cbms> test = Model.ToList();  
    List<databaseModel.cbms> cbmsModel = new List<databaseModel.cbms>();    
    int i = 0;
    foreach (databaseModel.cbms value in test)
    {
        i++;
        TempData.Add(i.ToString(), value);
    }        
}


@Ajax.ActionLink("productId", "AJX_SortByProductId", new { cbmsModel = TempData.Values.ToList() }, new AjaxOptions()
               {
                   HttpMethod = "GET",
                   UpdateTargetId = "divCbms",
                   InsertionMode = InsertionMode.Replace
               })

这仍然导致参数为空。我真的不明白为什么......

【问题讨论】:

  • 要么将列表存储在 ViewBag 中并在控制器中使用它,要么在将数据发送到服务器之前在视图上对数据进行字符串化。
  • 我尝试将其存储在 Viewbag 中(例如 Viewbag.Temp, ViewBag.Temp = test OR ViewBag.Temp = Model.ToList();),但 Viewbag.Temp 也是空的,当我在我的 Ajax 方法中传递它。
  • 经过一些广泛的调试后,我发现 cbmsModel 在视图加载后被处理掉了,包括除了 TempData 之外的所有其他变量。现在的问题是,如何使用 TempData 传递变量?由于使用@Ajax.ActionLink("productId", "AJX_SortByProductId", new { cbmsModel = TempData.Values.ToList() }, new AjaxOptions() { HttpMethod = "GET", UpdateTargetId = "divCbms", InsertionMode = InsertionMode.Replace }) 不起作用。

标签: jquery asp.net-mvc asp.net-mvc-3 asp.net-ajax


【解决方案1】:

我看到你使用 Ajax.ActionLink,这很危险,因为它会生成一个链接 => HTTP 请求 GET 并且这些请求有限制:Get request limitations

如果您想通过 Ajax 发送“复杂”模型,我建议使用没有限制的 POST 请求。 我看到您没有表格,如果我理解得很好,您希望查看显示信息的视图和将这些信息发送到下一个操作的按钮。我能想到的唯一方法是使用 jquery ajax 请求并在 json 中序列化对象。序列化可以使用一些帮助程序或 JSON.NET 直接在视图中完成,或者您可以在表格中显示结果并使用 javascript 获取信息。

$.ajax({
url : ""AJX_SortByProductId/productId",
type: "POST",
data : formData, //the data you want to send
success: function(data, textStatus, jqXHR)
{
    //data - response from server
}

});

如果你还想使用@Ajax.ActionLink,你要注意url,看看模型序列化是否正确,生成的html可以提供帮助。

【讨论】:

  • 将方法更改为:HttpMethod = "POST" 不能解决问题。数据当前显示正常,问题是我在视图中声明的包含数据的变量在创建视图时填充(因此它确实包含数据),但是当我单击与它(在本例中为 Ajax ActionLink),变量为空。
  • Ajax.ActionLink 不太推荐发送复杂的对象,它会生成一个 URL,所以属性 HttpMethod = "POST" 将无用。我保存的太快了,我没有提供足够的细节。
  • Ajax.ActionLink 将生成一个部分视图,我只想将一个变量传递给我的控制器中的一个方法,该方法将该变量传递给我的模型中的一个方法,然后返回一个列表模型到我的控制器,然后将结果重定向到部分视图。只是为了澄清:视图(带有数据)>控制器(数据)>模型(数据)>控制器(数据)>部分视图。编辑:保存答案太快没问题 ;-)
  • 我认为“GET”限制没有受到影响,因为如果我在 Ajax.ActionLink 中声明它,我可以传递其中包含“test”的字符串变量。但不知何故,当前视图页面上的模型列表变成了 0。
  • 好的,最好看看使用@Ajax.ActionLink 生成了什么
【解决方案2】:

编辑:请在阅读答案之前查看此答案下方的评论,因为此处提供的答案仅适用于特定情况,前提是最多只有 1 个用户与网站交互。

我通过以下方式解决了这个问题。这是一种肮脏的方式,但可以解决问题。它将 TempData 传递给控制器​​,您只需列出 TempData 中的项目。

查看

@model IEnumerable

@{   
    ViewBag.Title = "Cbms Home";

    if (TempData != null)
    {
        TempData.Clear();
    }
    int i = 0;
    foreach (databaseModel.cbms value in Model.ToList())
    {
        i++;
        TempData.Add(i.ToString(), value);
    }    
}

控制器

public PartialViewResult AJX_SortByProductId()
    {            
        //Retrieves the data
        List<object> viewDataList = TempData.Values.ToList();
        TempData.Clear();
        List<cbms> dataList = new List<cbms>();
        if (viewDataList != null)
        {
            foreach (cbms cbmsEntry in viewDataList)
            {
                dataList.Add(cbmsEntry);
            }
        }
        List<cbms> model = cbms.SortByProductId(dataList);

        //Returns the partial view
        return PartialView("_Cbms", model);
    }

【讨论】:

  • 我发现,如果您使用此答案并通过多种方式浏览到该站点,则缓存每次都会刷新,这当然不是它应该工作的方式,尤其是当您需要多个用户与网站交互。在清除缓存之前,我尝试检查 SessionID(因此检查是否已经添加了 SessionId),但是在同一台计算机上,这会产生同样的问题。所以,没有解决它。所以这个问题还没有解决 - 还......
  • 实际上,如果您使用 SessionID 作为标识符,通过不同的浏览器浏览网站不会产生问题...仍在测试中...
猜你喜欢
  • 2020-12-30
  • 2011-08-09
  • 1970-01-01
  • 1970-01-01
  • 2020-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-13
相关资源
最近更新 更多