所需的属性不外键下拉列表上工作 [英] Required Attribute does not work on foreign key dropdown list
问题描述
我一直在使用数据库第一种方法创建了一个项目中,我的表
城 - 具有以下的列
City_Id
城市名
STATE_ID
STATE_ID是一个外键状态表。
现在所有的验证和一切工作,直到我把[必填]注释过STATE_ID在我City.cs模型文件这是本
// ------------------------------------ ------------------------------------------
//<自动生成>
//这个code是从模板生成。
//
//这个文件的手动更改可能会导致应用程序意外行为。
//如果code再生此文件的手动更改将被覆盖。
//< /自动生成>
// ------------------------------------------------ ------------------------------
命名空间SS.Models
{
使用系统;
使用System.Collections.Generic;
使用System.ComponentModel;
使用System.ComponentModel.DataAnnotations;
使用System.Web.Mvc;
公共部分类城市
{
[System.Diagnostics程序codeAnalysis.Sup pressMessage。(Microsoft.Usage,CA2214:DoNotCallOverridableMethodsInConstructors)]
公众城()
{
this.Areas =新的HashSet<面积和GT;();
} 公众诠释City_Id {搞定;组; } [需要]
[DisplayName的(城市名称)]
[StringLength(50的ErrorMessage =城市名称超过50个字符限制)
[RegularEx pression(@[A-Z] [A-Z] +的ErrorMessage =输入格式不正确)]
[远程(CheckDuplicateInState,城市,AdditionalFields =STATE_ID的ErrorMessage =目前不能在同一状态的重复的城市名称)]
公共字符串CITY_NAME {搞定;组; }
[显示名称(国家名称)]
公众诠释STATE_ID {搞定;组; } [System.Diagnostics程序codeAnalysis.Sup pressMessage(Microsoft.Usage,CA2227:CollectionPropertiesShouldBeReadOnly)。]
公共虚拟的ICollection<面积和GT;地区{搞定;组; } 公共虚拟州州立{搞定;组; }
}
}
当我把[必填]在STATE_ID和preSS按钮的形式提交在创建视图没有任何反应,即使我从下拉无回后选择一个正确的状态发生或我只是选择然后也没有显示任何错误的选择国家默认显示值。
我的看法如下:
@model SS.Models.City@ {
ViewBag.Title =创建;
}< H2>创建< / H>
@using(Html.BeginForm())
{
@ Html.AntiForgeryToken() < DIV CLASS =形横>
< H4>城市< / H4>
<小时/>
@ Html.ValidationSummary(真,新{@class =TEXT-危险})
< DIV CLASS =表单组>
@ Html.LabelFor(型号=> model.City_Name,htmlAttributes:新{@class =控制标签COL-MD-2})
< DIV CLASS =COL-MD-10>
@ Html.EditorFor(型号=> model.City_Name,新{htmlAttributes = {新@class =表格控}})
@ Html.ValidationMessageFor(型号=> model.City_Name,新{@class =TEXT-危险})
< / DIV>
< / DIV> < DIV CLASS =表单组>
@ Html.LabelFor(型号=> model.State_Id,htmlAttributes:新{@class =控制标签COL-MD-2})
< DIV CLASS =COL-MD-10>
@ Html.DropDownList(STATE_ID,NULL,选择国家,htmlAttributes:新{@class =表格控})
@ Html.ValidationMessageFor(型号=> model.State_Id,新{@class =TEXT-危险})
< / DIV>
< / DIV> < DIV CLASS =表单组>
< DIV CLASS =COL-MD-偏移2 COL-MD-10>
<输入类型=提交值=创建类=BTN BTN-默认的/>
< / DIV>
< / DIV>
< / DIV>
}< DIV>
@ Html.ActionLink(返回目录,索引)
< / DIV>@section脚本{
@ Scripts.Render(〜/包/ jqueryval)
}
和我的控制器(相关code)如下:
使用系统;
使用System.Collections.Generic;
使用System.Data这;
使用System.Data.Entity的;
使用System.Linq的;
使用System.Net;
使用的System.Web;
使用System.Web.Mvc;
使用SS.Models;命名空间SS.Controllers.Admin
{
公共类CitiesController:控制器
{
私人SS DB =新SSDatabaseEntities(); // GET:城市/创建
公众的ActionResult的Create()
{
ViewBag.State_Id =新的SelectList(db.States,STATE_ID,STATE_NAME);
返回查看();
} // POST:城市/创建
//从overposting攻击保护,请启用要绑定到特定的属性,
//更多详情请参阅http://go.microsoft.com/fwlink/?LinkId=317598。
[HttpPost]
[ValidateAntiForgeryToken]
公众的ActionResult创建([绑定(包括=City_Id,CITY_NAME,STATE_ID)]城市)
{
如果(ModelState.IsValid)
{
db.Cities.Add(市);
db.SaveChanges();
返回RedirectToAction(「指数」);
} 返回查看(市);
} 公共JsonResult CheckDuplicateInState(字符串CITY_NAME,诠释STATE_ID)
{
国家ST = db.States.Find(STATE_ID); 如果(st.Cities.Any(X => x.City_Name == CITY_NAME))
返回JSON(假,JsonRequestBehavior.AllowGet);
其他
返回JSON(真,JsonRequestBehavior.AllowGet);
}
}
}
在把[必填]上STATE_ID在City.cs数据-VAL-所需的必需属性在下拉HTML上观看网页的源代码,不产生。
< DIV CLASS =表单组>
<标签类=控制标签COL-MD-2=STATE_ID>国家名称和LT; /标签>
< DIV CLASS =COL-MD-10>
<选择类=表格控ID =STATE_IDNAME =STATE_ID><期权价值=>选择国家< /选项>
<期权价值=1>中央邦< /选项>
<期权价值=2>古吉拉特邦< /选项>
<期权价值=4>&旁遮普LT; /选项>
<期权价值=9>泰米尔纳德邦< /选项>
<期权价值=10>哈里亚纳邦< /选项>
< /选择>
<跨度类=现场验证,有效文本危险数据valmsg换=STATE_ID数据valmsg替换=真正的>< / SPAN>
< / DIV>
< / DIV>
您 @ Html.DropDownList的使用(STATE_ID,NULL,...)
是绑定在 STATE_ID
这是你已经添加到 ViewBag $ C $的
的SelectList
属性C>(并且没有任何验证的属性。
而不是给你的财产结合和的SelectList
不同的名称,这样就可以强烈绑定到你的模型属性。在GET方法
ViewBag.StateList =新的SelectList(db.States,STATE_ID,STATE_NAME);
和视图
@ Html.DropDownListFor(M = GT; m.State_Id,(的SelectList)ViewBag.StateList,选择国家,新{@class =表格控})
正确数据-VAL-要求
和数据-VAL-号
属性现在将增加了对客户端验证。
然后在POST方法,您需要返回视图之前重新填充 ViewBag
属性
[HttpPost]
[ValidateAntiForgeryToken]
公众的ActionResult创建(城市)
{
如果(ModelState.IsValid)
{
....
}
ViewBag.StateList =新的SelectList(db.States,STATE_ID,STATE_NAME); //添加此
返回查看(市);
}
边注:没有必要为 [绑定]
属性,因为您的包括所有属性这是默认的(和你包括 City_Id
,因为你不知道它没有任何意义 - 并且不应该 - 有一个控制它
有一个更好的办法是使用含有的IEnumerable℃的视图模型; SelectListItem> StateList
,这样就可以简单地使用 @ Html.DropDownListFor(M = GT; m.State_Id,Model.StateList,....)
I have created a project using database first approach in which My table
City - has the following columns
City_Id
City_Name
State_Id
State_Id is a foreign key to state table.
Now all validations and everything is working until I put the [Required] annotation over State_Id in my City.cs model file which is this
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace SS.Models
{
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
public partial class City
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public City()
{
this.Areas = new HashSet<Area>();
}
public int City_Id { get; set; }
[Required]
[DisplayName("City Name")]
[StringLength(50,ErrorMessage = "City Name exceeds limit of 50 characters")]
[RegularExpression(@"[A-Z][a-z]+",ErrorMessage ="Input Format Incorrect")]
[Remote("CheckDuplicateInState","Cities",AdditionalFields ="State_Id",ErrorMessage ="There cannot be duplicate city names in same state")]
public string City_Name { get; set; }
[DisplayName("State Name")]
public int State_Id { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Area> Areas { get; set; }
public virtual State State { get; set; }
}
}
When I put [Required] over State_Id and press the button to Submit in the form in Create view nothing happens, even if I select a correct state from the drop down no post-back happens or I just select the default display value of "Select State" then also no error is shown.
My view is as follows
@model SS.Models.City
@{
ViewBag.Title = "Create";
}
<h2>Create</h2>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>City</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.City_Name, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.City_Name, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.City_Name, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.State_Id,htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownList("State_Id", null,"Select State", htmlAttributes: new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.State_Id, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
And my controller (relevant code) is as follows
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using SS.Models;
namespace SS.Controllers.Admin
{
public class CitiesController : Controller
{
private SS db = new SSDatabaseEntities();
// GET: Cities/Create
public ActionResult Create()
{
ViewBag.State_Id = new SelectList(db.States, "State_Id", "State_Name");
return View();
}
// POST: Cities/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "City_Id,City_Name,State_Id")] City city)
{
if (ModelState.IsValid)
{
db.Cities.Add(city);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(city);
}
public JsonResult CheckDuplicateInState(string City_Name,int state_id)
{
State st = db.States.Find(state_id);
if (st.Cities.Any(x => x.City_Name == City_Name))
return Json(false, JsonRequestBehavior.AllowGet);
else
return Json(true, JsonRequestBehavior.AllowGet);
}
}
}
On putting [Required] on State_Id in City.cs the required attribute data-val-required is not generated in the drop down html on viewing page source.
<div class="form-group">
<label class="control-label col-md-2" for="State_Id">State Name</label>
<div class="col-md-10">
<select class="form-control" id="State_Id" name="State_Id"><option value="">Select State</option>
<option value="1">Madhya Pradesh</option>
<option value="2">Gujarat</option>
<option value="4">Punjab</option>
<option value="9">Tamil Nadu</option>
<option value="10">Haryana</option>
</select>
<span class="field-validation-valid text-danger" data-valmsg-for="State_Id" data-valmsg-replace="true"></span>
</div>
</div>
Your usage of @Html.DropDownList("State_Id", null, ...)
is binding to the State_Id
which is the SelectList
property you have added to ViewBag
(and does not have any validation attributes.
Instead give the property your binding to and the SelectList
different names so that you can strongly bind to you model property. In the GET method
ViewBag.StateList = new SelectList(db.States, "State_Id", "State_Name");
and in the view
@Html.DropDownListFor(m => m.State_Id, (SelectList)ViewBag.StateList, "Select State", new { @class = "form-control" })
The correct data-val-required
and data-val-number
attributes will now be added for client side validation.
then in the POST method, you need to repopulate the ViewBag
property before you return the view
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(City city)
{
if (ModelState.IsValid)
{
....
}
ViewBag.StateList = new SelectList(db.States, "State_Id", "State_Name"); // add this
return View(city);
}
Side note: There is no need for the [Bind]
attribute since your including all properties which is the default (and your including City_Id
which does not make sense since you don't - and should not - have a control for it.
A better approach would be to use a view model containing IEnumerable<SelectListItem> StateList
so that you can simply use @Html.DropDownListFor(m => m.State_Id, Model.StateList, ....)
这篇关于所需的属性不外键下拉列表上工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!