出于某种原因,每当我尝试远程验证模型中数组内的基本属性时,该属性的值不会作为参数传递。
例如,当调用我的远程验证方法(UniqueItemNo)时,字符串参数“id”始终为null。如果我要在CartNumber而不是ItemNumber上执行验证,则参数将正确传递。
public class HomeController : Controller
{
public ActionResult Index()
{
CartModel cart = new CartModel();
cart.Items.Add(new ItemModel() { ItemNumber = "12345" });
return View(cart);
}
[HttpPost]
public JsonResult UniqueItemNo(string id)
{
/** Do Work **/
return null;
}
}
public class ItemModel
{
[Remote("UniqueItemNo", "Home", HttpMethod="POST")]
public string ItemNumber { get; set; }
}
public class CartModel
{
public CartModel()
{
Items = new List<ItemModel>();
}
public List<ItemModel> Items { get; set; }
public string CartNumber { get; set; }
}
@{
ViewBag.Title = "Home Page";
}
<h2>@ViewBag.Message</h2>
@using(Html.BeginForm()) {
<p>
@for(int i = 0; i < Model.Items.Count; i++)
{
@Html.TextBoxFor(m => m.Items[i].ItemNumber);
@Html.ValidationMessageFor(m => m.Items[i].ItemNumber);
}
</p>
}
答案 0 :(得分:6)
刚刚解决了同样的问题。所以对于我将来会遇到这个问题的那类人来说,这就是解决方案
这是根本原因。
当你@Html.TextBoxFor(x=>x.m.Items[i].ItemNumber)
时
它输出类似这样的东西
<input type=text value='value' name='items[index].ItemNumber' ...
然后它添加其他验证,如data- *属性进行验证。例如远程验证url data-remot-url等
现在,当表单得到验证时,它请求远程URL,其中包含key = xxx [1] .propertyname
等数据并且这不能分配给将接收此属性的远程操作方法中的单个变量。
如果您将动作参数更改为类似的内容,那么它将起作用
public JsonResult UniqueItemNo(list<string> propertyname)
即便如此,您也不需要保证,因为它需要让参数索引从0开始并且没有任何间隙。所以xxx [1] .ItemNumber永远不会被maped。
唯一剩下的解决方案是从querystring获取属性名称并将其映射到您需要的变量。像这样
if(Request.QueryString.AllKeys.FirstOrDefault(p => p.ToLower().Contains("propertyname"))!=null)
{
propertyname = Request.QueryString[Request.QueryString.AllKeys.First(p => p.ToLower().Contains("propertyname"))];
}
它将搜索并映射所需的变量。
希望这会有所帮助
答案 1 :(得分:1)
我希望你已经找到了答案,但如果你没有,请试试这个:
[HttpPost]
public JsonResult UniqueItemNo()
{
var itemNumber = Request.Form[Request.Form.AllKeys.First(p => p.Contains("ItemNumber"))];
/** Do Work **/
return Json(true);
}
请注意@Mamoon你的Rasheed答案几乎是正确的,但由于你正在使用POST,你的参数将在Form属性中,而不是QueryString。
如果您对此仍有任何疑问,请与我们联系。
顺便说一句,你应该使用try / catch。我没有写它只是为了保持简单。
答案 2 :(得分:0)
尝试更改参数以匹配模型。像这样:
[HttpPost]
public JsonResult UniqueItemNo(ItemModel itemModel)
{
// look at itemModel.ItemNumber...
/** Do Work **/
return null;
}
您仍然可以按照正常的编码惯例以小写(ActionMethod
而不是itemNumber
)开始ItemNumber
参数的名称。
编辑:您是否尝试过这样编码View
?
@{
ViewBag.Title = "Home Page";
}
<h2>@ViewBag.Message</h2>
@foreach (var item in Items)
{
@using(Html.BeginForm()) {
<p>
@Html.HiddenFor(m=>m.CartNumber)
@Html.TextBoxFor(m => item.ItemNumber);
@Html.ValidationMessageFor(m => item.ItemNumber);
</p>
}
}
答案 3 :(得分:0)
不幸的是,你没有这方面的支持。
在客户端,远程验证由jquery.validate.unobtrusive.js处理,后面写着
...
$.each(splitAndTrim(options.params.additionalfields || options.element.name), function (i, fieldName) {
var paramName = appendModelPrefix(fieldName, prefix);
value.data[paramName] = function () {
return $(options.form).find(":input[name='" + escapeAttributeValue(paramName) + "']").val();
};
});
...
因此您应该注意到,对于每个附加字段,它只在查询字符串中构造一个参数(如果您发布,则在表单中)。因为你的服务器端远程属性应该看起来像
[Remote("UniqueItemNo", AdditionalFields = "ItemNumber[0],ItemNumber[1],...")]
事实上你在设计时并不知道。
你可以使用一个js hack并保留一个名为ItemNumber的隐藏字段,并且值为一个连接的id列表。在服务器端,您应该将ItemNumber数组的类型更改为字符串并拆分值。
我希望这会有所帮助,尽管你问过很长时间。