MVC 4 / AJAX - 传递给控制器的空值,尽管列表中的条目有效
本文关键字:列表 有效 空值 MVC AJAX 控制器 | 更新日期: 2023-09-27 18:33:05
我有一个"创建"表单,我正在处理。其中两个字段是 OriginAirportID 和 DestinationAirportID。
目前可以做的是有人在此字段中键入一串字母,然后页面使用此字符串创建一个 AJAX 请求,以 JSON 格式获取一组数据。然后,此 JSON 数据将被格式化并显示在用户可以单击它的页面上,并将项目名称添加到字段中。
按下提交/创建按钮,我已经在Visual Studio中对其进行了调试,可以看到FromAirport和ToAirport字段显示为空。
很明显,机场 ID 没有被发送回控制器,因此在模型验证时失败。
这样做而不是下拉列表的原因是加载页面变得繁重,尤其是在数据库中的两个字段上有 50,000 个机场(总共 100,000 个选择项目(时。
字段的 HTML 标记为:
<input type="text" name="OriginAirportID" id="OriginAirportID" />
<input type="text" name="DestinationAirportID" id="DestinationAirportID" />
当有人在OriginAirportID字段中输入"LHR"时,将发送以下内容:
term=LHR
这是响应:
[{"AirportID":16420,"Name":"London Heathrow Airport"}]
在我的$.ajax中如下:
$.ajax({
url: "/Flight/<MethodName>",
type: "POST",
dataType: "json",
data: { term: request.term },
success: function (data) {
response($.map(data, function (item) {
return { label: item.Name, value: item.Name };
}))
}
})
如果这不清楚或令人困惑,请告诉我,我将尝试提供更多信息。
编辑:4/12/14 1844 GMT
到目前为止,感谢您对看起来像js对象的模型以及隐藏字段技术的三个回复。我将修改每个建议,看看它最终是否接受该模型。StuartLC - 我想我认为这很聪明,但刚刚意识到您指出的代码没有机场 ID !这肯定会使问题更加复杂。
问题似乎是您使用模型中的实际属性作为用户输入文本的字段,但看起来这些属性实际上应该是整数。一旦模型绑定器开始处理发布的数据,它将尝试将字符串值绑定到 int,但由于像"LHR"这样的东西不能转换为 int,所以你会得到一个 null。你应该做的是这样的:
<input type="text" id="OriginAirport" />
<input type="hidden" name="OriginAirportID" />
用户在文本框中键入内容,该文本框未绑定到任何内容。您的 AJAX 使用它来查找机场 ID,然后使用该标识符有绑定到您的实际属性的隐藏输入。现在,当您发布时,将发布实际的整数 id,模型绑定器将能够将其正确绑定到您的模型。
这就是我要做的:
1( 根据用户输入,您进行 AJAX 调用并获取机场 ID 和其他数据。您可以将机场 ID 保存在隐藏字段中,也可以保存为输入字段的"数据"属性。这没有太大区别,两种选择都有效。假设您使用隐藏字段。
2(与目的地机场相同。
现在您有 2 个隐藏字段,一个用于起点,另一个用于目的地。
3(用户提交:在AJAX调用中,您创建一个JS对象并设置两个ID(源ID和目标ID(。像这样:
var vm = {};
vm.originAirportId = $("#OriginAirportID").val();
vm.destinationAirportId = $("#DestinationAirportID").val();
4( 在 MVC 操作 ASP.NET,您应该有一个与 JS 对象具有相同属性的 ViewModel,如下所述。
public class TripVM {
public int OriginAirportId { get; set; }
public int DestinationAirportId { get; set; }
}
然后,ASP.NET MVC 将为您进行绑定。
这样,您只能将 ID 从客户端发送到服务器。我建议你使用 JSON.stringify 将 JS 对象转换为 JSON 表示形式。请记住,JS 对象的属性名称必须与 C# 类的属性匹配,但比较不区分大小写,因此您可以遵守每种语言命名约定:)