MVC3 远程验证列表中的字段
由于某种原因,每当我尝试远程验证模型中数组内的原始属性时,该属性的值都不会作为参数传递。
例如,当调用我的远程验证方法(UniqueItemNo)时,字符串参数“id”始终为空。如果我要对 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>
}
For some reason, whenever I try to remotely validate a primitive property inside an array within my model, the value of the property is not passed as a parameter.
For example, when my remote validation method (UniqueItemNo) is called, the string parameter "id" is always null. If I were to perform validation on CartNumber instead of ItemNumber, the parameter is passed correctly.
Controller
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;
}
}
Models
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; }
}
View
@{
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>
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
刚刚解决了同样的问题。所以对于我这种将来会遇到这个问题的人来说,这里的解决方案
就是根本原因。
当你执行 @Html.TextBoxFor(x=>xmItems[i].ItemNumber)
它输出类似这样的内容
,然后添加其他验证,例如用于验证的 data-* 属性。例如,远程验证 url data-remot-url 等
现在,当表单得到验证时,它会请求带有 key=xxx[1].propertyname 等数据的远程 url
,并且这不能分配给将接收此属性的远程操作方法中的单个变量。
如果您将操作参数更改为类似的内容,那么它会起作用
,即使如此,也不能保证您,因为它要求参数索引从 0 开始并且没有任何间隙。所以 xxx[1].ItemNumber 永远不会被映射。
唯一剩下的解决方案是从查询字符串中获取属性名称并将其映射到所需的变量。像这样
它将搜索并映射所需的变量。
希望这会有所帮助
just solved the same problem. so for my type of people who are going to have this problem in future, here is the solution
here is the root cause.
when you do
@Html.TextBoxFor(x=>x.m.Items[i].ItemNumber)
it outputs something like this
and then it adds the other validations like data-* attributes for validation. e.g. remote validation url data-remot-url and etc
now when form got validated it requested the remote url with data like key=xxx[1].propertyname
and this is not assignable to a single variable in remote action method that will receive this property.
if you will change the action arguments to something like this, then it will work
and even then you are not guranteed as it requires to have the parameters index start from 0 and without any gap. so xxx[1].ItemNumber will never get maped.
the only remaining solution is to get the property name from querystring and map it to your required variable. like this
it will search and map the required variables.
hope this will help
我希望您已经找到了答案,但如果您没有找到答案,请尝试以下操作:
请注意,@Mamoon ur Rasheed 的答案几乎是正确的,但由于您使用的是 POST,因此您的参数将位于 Form 属性内,而不是 QueryString。
如果您对此仍有任何问题,请告诉我。
顺便说一句,你应该使用 try/catch。我写它并不是为了简单。
I hope you found an answer already, but in case you didn't, try this:
Note that @Mamoon ur Rasheed answer was almost correct, but since you're using POST your parameters will be inside the Form property, not QueryString.
Let me know if you still have any issues regarding this.
Btw, you should use a try/catch. I didn't wrote it just to keep it simple.
尝试更改参数以匹配模型。像这样:
您仍然可以按照正常编码约定以小写字母开头(
itemNumber
而不是ItemNumber
)ActionMethod
参数的名称。编辑:您是否尝试过像这样编码
View
?Try changing the parameter to match the model. Like this:
You can still start the name of the
ActionMethod
parameter with lowercase (itemNumber
instead ofItemNumber
) as per the normal coding conventions.EDIT: Have you tried coding the
View
like this?不幸的是,您没有对此的支持。
在客户端,远程验证由 jquery.validate.unobtrusive.js 处理,因此
您应该注意到,对于每个附加字段,它仅在查询字符串中构造一个参数(如果您确实发布,则在表单中)。因此,您的服务器端远程属性应该看起来像
您在设计时不知道的事实。
您可以使用 js hack 并保留一个名为 ItemNumber 的隐藏字段以及一个串联的 id 列表。在服务器端,您应该将 ItemNumber 数组的类型更改为字符串并拆分值。
我希望这会有所帮助,尽管距离您提问已经很长时间了。
Unfortunately you don't have support for this.
In client side the remote validation is handled by jquery.validate.unobtrusive.js which says
so you should notice that for each additional field it constructs just one parameter in query string (or in form if you do post). because of that you server side remote attribute should look like
fact that you don't know at design time.
you could use a js hack and keep a hidden field named ItemNumber and with value a concatenated list of ids. on server side you should change the type of ItemNumber array into string and split the values.
I hope this helps although it's a long time since you asked.