ASP.NET MVC将List <foo>集合从我的View发送到Controller

时间:2018-02-16 19:09:44

标签: c# ajax asp.net-mvc

我在 ASP.NET 中有一个应用程序,我想将此对象列表传递给控制器。现在应用程序正在做的是通过 sql query 填充列表,然后将所述列表加载到视图。接下来,我根据我得到的数据将列表分成4个颜色类别:红色,蓝色,绿色和黄色(分别)。我在4 <divs>上显示每个人的计数。每个div都有自己的 ActionLink ,现在将字符串发送到包含颜色名称的控制器

然后,Controller接收字符串并将其与查询进行比较,在该查询中它返回属于该颜色类别的列表对象;然后我做任何我想做的事情。

但是我的问题是我不得不反复做这个数据,这需要太长时间。有没有办法让我只需加载列表然后将其传递给我的控制器,这样我就不会等待我的查询完成加载?

这是我的模型

using System.Collections.Generic;

namespace Foo.Models
{
  public class FooViewModel
  {
    public List<Foo> FooCollection = new List<Foo>();
    /*Contains two properties
      string CarName {get; set;}
      string Color   {get; set;}
      List<Features> Features = new List<Features>();
    */
  }
}

我的查看

    @model Foo.Models.FooViewModel
    @{
var RedCars = Model.FooCollection.Where(c => c.Color == "Red").ToList();
    ... //{yellow, blue, green}
}
    <div id="FooCollection">
      <section class="no-padding-top no-padding-bottom">
        <div class="container-fluid">
          <div class="public-user-block block">
            <div class="row d-flex align-items-center">

              <!--Red Cars-->
                @using (Ajax.BeginForm("../Bar/Index/Red", null,
new AjaxOptions
{
HttpMethod = "post",
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "CarsList"
}, new { id = "RedCarsForm" }))
  {
        <input type="hidden" name="Cars" value="@RedCars" />
          <div id="status-container" class="col-lg-3 d-flex align-items-center">
            <button type="submit">@RedAlerts.Count</button>
            <strong>Red Cars</strong>
          </div>

          }
          <!-- same structure for yellow, green, blue --!>
      </section>
    </div>

我的控制器

public ActionResult Index()
{

   foreach (var car in db.database.Db_GetCars())
   {
      model.FooCollection.Add(new Foo()
      {
         CarName = car.CarName,
         Color= car.Color
      });
    }
    return View(model);
}  

目标控制器:

    namespace Foo.Controllers
    {
      public class BarController: Controller
      {
        BarViewModel model = new BarViewModel();

[HttpPost, Route("/Bar/Index/{color}")]
        public ActionResult Index(List<Foo> Cars)
        {
          //logic goes here

          return View(model);
        }
      }
    }

我想要的输出是将完整的List<Foo>对象发送到目标控制器。但是现在,当它到达控制器时,我得到的值数为零(0)。谁能看到我做错了什么?非常感谢提前。

1 个答案:

答案 0 :(得分:2)

因此,您的主要问题是您正在尝试使用操作(链接,锚标记)将列表传递给控制器​​。但锚标签是&#34; Get&#34;请求,你通常不通过获取传递列表(是的,这是可能的,但通常不建议)。为此你最好使用表格帖子。这是一个基本概要:

<!-- red cars -->
<form action="/bar/index/red" method="post">

    @foreach(var car in Model.Where(c => c.Color == "red"))
    {
        <input type="hidden" name="carnames" value="@car.CarName" />
    }
    <button class="btn btn-primary" type="submit">Red Cars</button>

</form>

<!-- green cars -->
<form action="/bar/index/green" method="post">

    @foreach(var car in Model.Where(c => c.Color == "green"))
    {
        <input type="hidden" name="carnames" value="@car.CarName" />
    }
    <button class="btn btn-primary" type="submit">Green Cars</button>

</form>

<!-- blue cars -->
<form action="/bar/index/blue" method="post">

    @foreach(var car in Model.Where(c => c.Color == "blue"))
    {
        <input type="hidden" name="carnames" value="@car.CarName" />
    }
    <button class="btn btn-primary" type="submit">Blue Cars</button>

</form>

<!-- yeller cars -->
<form action="/bar/index/yellow" method="post">

    @foreach(var car in Model.Where(c => c.Color == "yellow"))
    {
        <input type="hidden" name="carnames" value="@car.CarName" />
    }
    <button class="btn btn-primary" type="submit">Yellow Cars</button>

</form>

这会为每种颜色创建一个表单,因此当您单击“提交”按钮时,只会在该帖子中发送该表单中的汽车。请注意,输入名称始终相同。这就是你如何将它们组合在一个列表中。

在您的控制器中,使用以下内容:

[HttpPost, Route("bar/index/{color}")]
public IActionResult Index(string color, List<string> carNames)
{
    // do stuff...

    return View();
}

{@ 1}}变量将从网址中获取,而carNames将从帖子中提取。

编辑: 在评论中,添加的问题基本上是&#34;如果我想要对象上的汽车名称和颜色,那么要发布color该怎么办?

发布复杂对象列表有点麻烦,但这是您在视图中需要的内容:

List<Foo>

切换到常规<!-- red cars --> <form action="/stuff/cars/red" method="post"> @{ var cars = Model.Where(c => c.Color == "red").ToList(); for (var i = 0; i < cars.Count; i++) { <text> <input type="hidden" name="cars.Index" value="@i" /> <input type="hidden" name="cars[@i].CarName" value="@cars[i].CarName" /> <input type="hidden" name="cars[@i].Color" value="@cars[i].Color" /> </text> } } <button class="btn btn-primary" type="submit">Red Cars</button> </form> 循环为我们提供了一个索引变量,我们用它来告诉表单哪一个值属于哪一个。另请注意,我实际上在其上方创建了一个临时for,以便我可以遍历较小的列表。现在只需更改其他颜色以匹配此代码,并将控制器更改为接受var cars = ...即可完成设置!

编辑2: 如果你想在ajax中这样做,那么在javascript中创建一个对象:

string color, List<Foo> cars

您可以使用jQuery以各种方式填充实际的var cars = [ { 'CarName': 'name', 'Color': 'color' }, { 'CarName': 'name', 'Color': 'color' }, { 'CarName': 'name', 'Color': 'color' }, { 'CarName': 'name', 'Color': 'color' }, { 'CarName': 'name', 'Color': 'color' } ]; name。然后使用ajax post:

color

注意:这将是控制器中与前一个端点不同的端点。根据您使用的.net版本,事情会略有不同。

新的控制器操作:

$(document).ready(function()
{
    $('#ajaxPost').click(function ()
    {
        $.ajax(
        {
            type: 'POST',
            url: '/stuff/cars',
            contentType: "application/json",
            data: JSON.stringify(cars),
            success: function (data)
            {
                // do stuff
            },
            error: function (e)
            {
                alert(e);

            }

        });
    });
});

请注意.net Core中必需的[HttpPost, Route("stuff/cars/")] public IActionResult Cars2([FromBody] List<FooViewModel> cars) { // do stuff... return View(); } 标记,以及ajax调用中的[FromBody]。如果您不确定自己所使用的版本,请另外添加/删除其中的每个版本。核心可能有点挑剔...