我在 ASP.NET 中有一个应用程序,我想将这个对象列表传递给我的 Controller。现在应用程序正在做的是通过sql 查询 填充列表,然后将所述列表加载到 View 。接下来,我根据获得的数据将列表分为 4 个颜色类别:红色、蓝色、绿色和黄色(分别)。我在 4 <divs> 上显示了他们每个人的计数.每个 div 都是它自己的 ActionLink,现在将一个字符串发送到包含颜色名称的 Controller。
Controller 然后获取该字符串并将其与查询进行比较,查询返回属于该颜色类别的列表对象;然后我对该列表做任何我想做的事。
但我的问题是,我不得不一遍又一遍地提取这些数据,而且花费的时间太长了。有没有一种方法可以让我只加载一次列表,然后将其传递给我的 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>
我的 Controller :
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);
}
目标 Controller :
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>反对我的目标 Controller 。但是现在,当它到达 Controller 时,我得到的值计数为零 (0)。谁能看到我做错了什么?非常感谢。
请您参考如下方法:
所以你的主要问题是你试图使用一个 Action (这是一个链接,一个 anchor 标记)将一个列表传递给 Controller 。但是 anchor 标记是一个“获取”请求,您通常不会通过获取传递列表(是的,这是可能的,但通常不建议)。您最好为此使用表单发布。这是一个基本大纲:
<!-- 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>
这会为每种颜色创建一个表单,因此当您单击提交按钮时,只会发送该表单中的汽车。请注意,输入名称始终相同。这就是将它们打包在一个列表中的方式。
在你的 Controller 中,使用这样的东西:
[HttpPost, Route("bar/index/{color}")]
public IActionResult Index(string color, List<string> carNames)
{
// do stuff...
return View();
}
color变量将从 url 中获取,carNames 将从帖子中提取。
编辑: 在评论中,添加的问题基本上是“如果我想要汽车名称和对象上的颜色,所以要发布一个 List<Foo> 怎么办?
发布复杂对象的列表有点困惑,但这是您在 View 中需要的:
<!-- 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 loop 给了我们一个索引变量,我们用它来告诉表单哪对值属于一起。另请注意,我实际上创建了一个临时文件 var cars = ...在它上面,这样我就可以遍历较小的列表。现在只需更改其他颜色以匹配此代码并更改您的 Controller 以接受 string color, List<Foo> cars一切就绪!
编辑 2: 如果您想在 ajax 中执行此操作,则在 javascript 中创建一个对象:
var cars = [
{ 'CarName': 'name', 'Color': 'color' },
{ 'CarName': 'name', 'Color': 'color' },
{ 'CarName': 'name', 'Color': 'color' },
{ 'CarName': 'name', 'Color': 'color' },
{ 'CarName': 'name', 'Color': 'color' }
];
您可以填充实际的 name和 color使用 jQuery 的各种方式。然后使用ajax发帖:
$(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);
}
});
});
});
注意:这将是 Controller 中与前一个端点不同的端点。根据您使用的 .net 版本,情况会略有不同。
新 Controller Action :
[HttpPost, Route("stuff/cars/")]
public IActionResult Cars2([FromBody] List<FooViewModel> cars)
{
// do stuff...
return View();
}
注意 [FromBody]标记,在 .net Core 中是必需的,JSON.stringify 也是如此。在ajax调用中。如果您不确定您使用的是哪个版本,请交替添加/删除每个版本。核心可能有点挑剔......
