ASP.Net MVC 中 ViewModel 的验证 DropDownList 值
Validation DropDownList value from ViewModel in ASP.Net MVC
我试着搜索帖子,也没有任何结果,可能是我用词不对。
我需要 MVC
中的解决方案来验证 DropDownList
值,使用 Model class
和 Html.DropDownListFor Helper
方法以及 MySql 从数据库中填充。
在视图中我添加了新的 DDL
并且这是从数据库中正确填充的
@Html.DropDownListFor(m => m.Fruits, Model.Fruits, "[ === Please select === ]", new { @Class = "textarea" })
@Html.ValidationMessageFor(m => m.Fruits, "", new { @class = "text-danger" })
<div class="form-group">
<div class="col-md-offset-5 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
但是当点击
<input type="submit" value="Create" class="btn btn-default" />
当 DDL
没有选择任何值时,表单有效并且不会停止发送。
没有 DDL
验证工作正常。
请帮帮我。
下面是我的代码
型号
namespace InsGE.Models
{
public class PersonModel
{
[Required]
[Display(Name = "Fruits")]
public List<SelectListItem> Fruits { get; set; }
public string Namex { get; set; }
public string Codex { get; set; }
[Required]
[Display(Name = "CL")]
public string CL { get; set; }
[Required]
[Display(Name = "Ticket")]
public string Ticket { get; set; }
}
}
控制器
namespace InGE.Controllers
{
public class HomeController : Controller
{
private static List<SelectListItem> PopulateFruits()
{
string sql;
List<SelectListItem> items = new List<SelectListItem>();
string constr = ConfigurationManager.ConnectionStrings["cn"].ConnectionString;
using (MySqlConnection con = new MySqlConnection(constr))
{
sql = @String.Format("SELECT * FROM `dotable`; ");
using (MySqlCommand cmd = new MySqlCommand(sql))
{
cmd.Connection = con;
con.Open();
using (MySqlDataReader sdr = cmd.ExecuteReader())
{
while (sdr.Read())
{
items.Add(new SelectListItem
{
Text = sdr["sName"].ToString(),
Value = sdr["sCode"].ToString()
});
}
}
con.Close();
}
}
return items;
}
[HttpPost]
public ActionResult Index(PersonModel person)
{
string sCl = person.CL;
string sTicket = person.Ticket;
string sName = person.Namex;
string sCode = person.Codex;
return View();
}
[HttpGet]
public ActionResult Index()
{
PersonModel fruit = new PersonModel();
fruit.Fruits = PopulateFruits();
return View(fruit);
}
public ActionResult About()
{
ViewBag.Message = "Your application description page.";
return View();
}
public ActionResult Contact()
{
ViewBag.Message = "Your contact page.";
return View();
}
更新
控制器
public class HomeController : Controller
{
public class Fruit
{
public string Code { get; }
public string Name { get; }
public Fruit(string code, string name)
{
Code = code;
Name = name;
}
}
public class FruitsRepository
{
private static List<Fruit> GetAll()
{
string sql;
var fruits = new List<Fruit>();
string constr = ConfigurationManager.ConnectionStrings["cn"].ConnectionString;
using (MySqlConnection con = new MySqlConnection(constr))
{
sql = @String.Format("SELECT * FROM `dotable`; ");
using (MySqlCommand cmd = new MySqlCommand(sql))
{
cmd.Connection = con;
con.Open();
using (MySqlDataReader sdr = cmd.ExecuteReader())
{
while (sdr.Read())
{
var fruit = new Fruit(sdr["sCode"].ToString(), sdr["sName"].ToString());
fruits.Add(fruit);
}
}
con.Close();
}
}
return fruits;
}
}
[HttpGet]
public ActionResult Index() <<<<<< Error “not all code paths return a value”
{
var personModel = new PersonModel();
var fruitsRepo = new FruitsRepository();
var fruits = fruitsRepo.GetAll(); <<<<<< Error “is inaccessible due to its protection level”
var fruitsSelecteListItems = fruits.Select(fruit => new SelectListItem
{
Text = fruit.Name;
Value = fruit.Code; <<<<<< Error “The name 'Value' does not exist in the current context”
});
return View(personModel); <<<<<<Error “The type or namespace name could not be found”
}
型号
public class PersonModel
{
[Required]
[Display(Name = "Fruits")]
public string SelectedFruitCode { get; set; }
public List<SelectListItem> Fruits { get; set; }
public string Namex { get; set; }
public string Codex { get; set; }
[Required]
[Display(Name = "CL")]
public string CL { get; set; }
[Required]
[Display(Name = "Ticket")]
public string Ticket { get; set; }
}
完整视图
@using (Html.BeginForm("Index", "Home", FormMethod.Post))
{
@Html.AntiForgeryToken()
<div>
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<table>
<tr>
<td class="textarea">CL</td>
<td>
@Html.TextBoxFor(m => m.CL, new { @Class = "textarea", placeholder = "CL" })
@Html.ValidationMessageFor(m => m.CL, "", new { @class = "text-danger" })
</td>
<td class="textarea"></td>
<tr>
<td class="textarea">Ticket</td>
<td>
@Html.TextBoxFor(m => m.Ticket, new { @Class = "textarea", placeholder = "Ticket" })
@Html.ValidationMessageFor(m => m.Ticket, "", new { @class = "text-danger" })
</td>
<td class="textarea"></td>
<td class="textarea">Fruits</td>
<td>
@Html.DropDownListFor(m => m.SelectedFruitCode, Model.Fruits, "[ === Please select === ]", new { @Class = "textarea" })
@Html.ValidationMessageFor(m => m.SelectedFruitCode, "", new { @class = "text-danger" })
</td>
</tr>
</table>
<br />
<hr class="new3">
<div class="form-group">
<div class="col-md-offset-5 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/jqueryui")
@Styles.Render("~/Content/cssjqryUi")
<script type="text/javascript">
$(document).ready(function () {
$('input[type=datetime]').datepicker({
dateFormat: "dd/mm/yy",
changeMonth: true,
changeYear: true,
yearRange: "-2:+0"
});
});
</script>
}
完整控制器
public class HomeController : Controller
{
[HttpPost]
public ActionResult Index(PersonModel person)
{
if (ModelState.IsValid)
{
string cl = person.CL;
string ticket = person.Ticket;
}
return View();
}
public class Fruit
{
public string Code { get; }
public string Name { get; }
public Fruit(string code, string name)
{
Code = code;
Name = name;
}
}
public class FruitsRepository
{
public List<Fruit> GetAll()
{
string sql;
var fruits = new List<Fruit>();
string constr = ConfigurationManager.ConnectionStrings["cnx"].ConnectionString;
using (MySqlConnection con = new MySqlConnection(constr))
{
sql = @String.Format("SELECT * FROM `dotable`; ")
using (MySqlCommand cmd = new MySqlCommand(sql))
{
cmd.Connection = con;
con.Open();
using (MySqlDataReader sdr = cmd.ExecuteReader())
{
while (sdr.Read())
{
var fruit = new Fruit(sdr["sCode"].ToString(), sdr["sName"].ToString());
fruits.Add(fruit);
}
}
con.Close();
}
}
return fruits;
}
}
[HttpGet]
public ActionResult Index()
{
var personModel = new PersonModel();
var fruitsRepo = new FruitsRepository();
var fruits = fruitsRepo.GetAll();
var fruitsSelecteListItems = fruits.Select(fruit => new SelectListItem
{
Text = fruit.Name,
Value = fruit.Code
}).ToList();
personModel.Fruits = fruitsSelecteListItems;
return View(personModel);
}
public ActionResult About()
{
ViewBag.Message = "Your application description page.";
return View();
}
public ActionResult Contact()
{
ViewBag.Message = "Your contact page.";
return View();
}
}
你需要一些改变。让我们从数据库相关代码开始。不要将数据库相关的东西(MySqlConnection
、MySqlCommand
等)与表示层的东西(SelectListItem
、List<SelectListItem>
等)混合在一起,并在控制器内部进行,你应该
- 创建一个单独的 class 用于访问数据库和获取数据。
- 将被调用的方法应该 return 代表水果的某种 domain/entity 对象的列表。
所以,让我们先定义我们的 class, Fruit
:
public class Fruit
{
public string Code { get; }
public string Name { get; }
public Fruit(string code, string name)
{
Code = code;
Name = name;
}
}
然后让我们创建一个class,负责访问数据库和获取水果:
public class FruitsRepository
{
public List<Fruits> GetAll()
{
string sql;
var fruits = new List<Fruit>();
string constr = ConfigurationManager.ConnectionStrings["cn"].ConnectionString;
using (MySqlConnection con = new MySqlConnection(constr))
{
sql = @String.Format("SELECT * FROM `dotable`; ");
using (MySqlCommand cmd = new MySqlCommand(sql))
{
cmd.Connection = con;
con.Open();
using (MySqlDataReader sdr = cmd.ExecuteReader())
{
while (sdr.Read())
{
var fruit = new Fruit(sdr["sCode"].ToString(), sdr["sName"].ToString());
fruits.Add(fruit);
}
}
con.Close();
}
}
return fruits;
}
}
通常,这个 class 应该实现一个接口,以便我们将控制器与执行数据库操作的实际 class 分离,但我们现在不讨论这个。
然后在你的控制器上:
- 我们应该使用上面的class来获取水果。
- 我们应该创建一个 SelectListItem 对象列表,您可以将该列表提供给模型。
- 我们应该更改模型,使其包含有关所选水果的信息(查看下方)。
- 我们应该改变看法。
模型变化
public class PersonModel
{
[Required]
[Display(Name = "Fruits")]
public string SelectedFruitCode { get; set; }
public List<SelectListItem> Fruits { get; set; }
public string Namex { get; set; }
public string Codex { get; set; }
[Required]
[Display(Name = "CL")]
public string CL { get; set; }
[Required]
[Display(Name = "Ticket")]
public string Ticket { get; set; }
}
视图中的变化
@Html.DropDownListFor(model => model.SelectedFruitCode, Model.Fruits, "[ === Please select === ]", new { @Class = "textarea" })
@Html.ValidationMessageFor(model => model.SelectedFruitCode, "", new { @class = "text-danger" })
控制器的变化
[HttpGet]
public ActionResult Index()
{
var personModel = new PersonModel();
// THIS IS **BAD CODE**...Normaly, you should create an interface that describes
// what is expected from the class that communicates with the DB for operations
// related with the Fruit and then inject the dependency in the HomeController
// Constructor.
var fruitsRepo = new FruitsRepository();
var fruits = fruitsRepo.GetAll();
var fruitsSelecteListItems = fruits.Select(fruit => new SelectListItem
{
Text = fruit.Name,
Value = fruit.Code
}).ToList();
personModel.Fruits = fruitsSelecteListItems;
return View(personModel);
}
请仔细检查上面代码中的注释^^。作为评论中提到的起点,您可以看到 this.
更新
我们还必须更改 post 操作:
[HttpPost]
public ActionResult Index(PersonModel person)
{
// Removed the Model.IsValid check since it's redundant in your case
// Usually we use it and when it is valid we perform a task, like update
// the corresponding object in the DB or doing something else. Otherwise,
// we return a view with errors to the client.
var fruitsRepo = new FruitsRepository();
var fruits = fruitsRepo.GetAll();
var fruitsSelecteListItems = fruits.Select(fruit => new SelectListItem
{
Text = fruit.Name,
Value = fruit.Code,
Selected = String.Equals(fruit.Code,
person.SelectedFruitCode,
StringComparison.InvariantCultureIgnoreCase)
}).ToList();
person.Fruits = fruitsSelecteListItems;
return View(person);
}
我试着搜索帖子,也没有任何结果,可能是我用词不对。
我需要 MVC
中的解决方案来验证 DropDownList
值,使用 Model class
和 Html.DropDownListFor Helper
方法以及 MySql 从数据库中填充。
在视图中我添加了新的 DDL
并且这是从数据库中正确填充的
@Html.DropDownListFor(m => m.Fruits, Model.Fruits, "[ === Please select === ]", new { @Class = "textarea" })
@Html.ValidationMessageFor(m => m.Fruits, "", new { @class = "text-danger" })
<div class="form-group">
<div class="col-md-offset-5 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
但是当点击
<input type="submit" value="Create" class="btn btn-default" />
当 DDL
没有选择任何值时,表单有效并且不会停止发送。
没有 DDL
验证工作正常。
请帮帮我。
下面是我的代码
型号
namespace InsGE.Models
{
public class PersonModel
{
[Required]
[Display(Name = "Fruits")]
public List<SelectListItem> Fruits { get; set; }
public string Namex { get; set; }
public string Codex { get; set; }
[Required]
[Display(Name = "CL")]
public string CL { get; set; }
[Required]
[Display(Name = "Ticket")]
public string Ticket { get; set; }
}
}
控制器
namespace InGE.Controllers
{
public class HomeController : Controller
{
private static List<SelectListItem> PopulateFruits()
{
string sql;
List<SelectListItem> items = new List<SelectListItem>();
string constr = ConfigurationManager.ConnectionStrings["cn"].ConnectionString;
using (MySqlConnection con = new MySqlConnection(constr))
{
sql = @String.Format("SELECT * FROM `dotable`; ");
using (MySqlCommand cmd = new MySqlCommand(sql))
{
cmd.Connection = con;
con.Open();
using (MySqlDataReader sdr = cmd.ExecuteReader())
{
while (sdr.Read())
{
items.Add(new SelectListItem
{
Text = sdr["sName"].ToString(),
Value = sdr["sCode"].ToString()
});
}
}
con.Close();
}
}
return items;
}
[HttpPost]
public ActionResult Index(PersonModel person)
{
string sCl = person.CL;
string sTicket = person.Ticket;
string sName = person.Namex;
string sCode = person.Codex;
return View();
}
[HttpGet]
public ActionResult Index()
{
PersonModel fruit = new PersonModel();
fruit.Fruits = PopulateFruits();
return View(fruit);
}
public ActionResult About()
{
ViewBag.Message = "Your application description page.";
return View();
}
public ActionResult Contact()
{
ViewBag.Message = "Your contact page.";
return View();
}
更新
控制器
public class HomeController : Controller
{
public class Fruit
{
public string Code { get; }
public string Name { get; }
public Fruit(string code, string name)
{
Code = code;
Name = name;
}
}
public class FruitsRepository
{
private static List<Fruit> GetAll()
{
string sql;
var fruits = new List<Fruit>();
string constr = ConfigurationManager.ConnectionStrings["cn"].ConnectionString;
using (MySqlConnection con = new MySqlConnection(constr))
{
sql = @String.Format("SELECT * FROM `dotable`; ");
using (MySqlCommand cmd = new MySqlCommand(sql))
{
cmd.Connection = con;
con.Open();
using (MySqlDataReader sdr = cmd.ExecuteReader())
{
while (sdr.Read())
{
var fruit = new Fruit(sdr["sCode"].ToString(), sdr["sName"].ToString());
fruits.Add(fruit);
}
}
con.Close();
}
}
return fruits;
}
}
[HttpGet]
public ActionResult Index() <<<<<< Error “not all code paths return a value”
{
var personModel = new PersonModel();
var fruitsRepo = new FruitsRepository();
var fruits = fruitsRepo.GetAll(); <<<<<< Error “is inaccessible due to its protection level”
var fruitsSelecteListItems = fruits.Select(fruit => new SelectListItem
{
Text = fruit.Name;
Value = fruit.Code; <<<<<< Error “The name 'Value' does not exist in the current context”
});
return View(personModel); <<<<<<Error “The type or namespace name could not be found”
}
型号
public class PersonModel
{
[Required]
[Display(Name = "Fruits")]
public string SelectedFruitCode { get; set; }
public List<SelectListItem> Fruits { get; set; }
public string Namex { get; set; }
public string Codex { get; set; }
[Required]
[Display(Name = "CL")]
public string CL { get; set; }
[Required]
[Display(Name = "Ticket")]
public string Ticket { get; set; }
}
完整视图
@using (Html.BeginForm("Index", "Home", FormMethod.Post))
{
@Html.AntiForgeryToken()
<div>
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<table>
<tr>
<td class="textarea">CL</td>
<td>
@Html.TextBoxFor(m => m.CL, new { @Class = "textarea", placeholder = "CL" })
@Html.ValidationMessageFor(m => m.CL, "", new { @class = "text-danger" })
</td>
<td class="textarea"></td>
<tr>
<td class="textarea">Ticket</td>
<td>
@Html.TextBoxFor(m => m.Ticket, new { @Class = "textarea", placeholder = "Ticket" })
@Html.ValidationMessageFor(m => m.Ticket, "", new { @class = "text-danger" })
</td>
<td class="textarea"></td>
<td class="textarea">Fruits</td>
<td>
@Html.DropDownListFor(m => m.SelectedFruitCode, Model.Fruits, "[ === Please select === ]", new { @Class = "textarea" })
@Html.ValidationMessageFor(m => m.SelectedFruitCode, "", new { @class = "text-danger" })
</td>
</tr>
</table>
<br />
<hr class="new3">
<div class="form-group">
<div class="col-md-offset-5 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/jqueryui")
@Styles.Render("~/Content/cssjqryUi")
<script type="text/javascript">
$(document).ready(function () {
$('input[type=datetime]').datepicker({
dateFormat: "dd/mm/yy",
changeMonth: true,
changeYear: true,
yearRange: "-2:+0"
});
});
</script>
}
完整控制器
public class HomeController : Controller
{
[HttpPost]
public ActionResult Index(PersonModel person)
{
if (ModelState.IsValid)
{
string cl = person.CL;
string ticket = person.Ticket;
}
return View();
}
public class Fruit
{
public string Code { get; }
public string Name { get; }
public Fruit(string code, string name)
{
Code = code;
Name = name;
}
}
public class FruitsRepository
{
public List<Fruit> GetAll()
{
string sql;
var fruits = new List<Fruit>();
string constr = ConfigurationManager.ConnectionStrings["cnx"].ConnectionString;
using (MySqlConnection con = new MySqlConnection(constr))
{
sql = @String.Format("SELECT * FROM `dotable`; ")
using (MySqlCommand cmd = new MySqlCommand(sql))
{
cmd.Connection = con;
con.Open();
using (MySqlDataReader sdr = cmd.ExecuteReader())
{
while (sdr.Read())
{
var fruit = new Fruit(sdr["sCode"].ToString(), sdr["sName"].ToString());
fruits.Add(fruit);
}
}
con.Close();
}
}
return fruits;
}
}
[HttpGet]
public ActionResult Index()
{
var personModel = new PersonModel();
var fruitsRepo = new FruitsRepository();
var fruits = fruitsRepo.GetAll();
var fruitsSelecteListItems = fruits.Select(fruit => new SelectListItem
{
Text = fruit.Name,
Value = fruit.Code
}).ToList();
personModel.Fruits = fruitsSelecteListItems;
return View(personModel);
}
public ActionResult About()
{
ViewBag.Message = "Your application description page.";
return View();
}
public ActionResult Contact()
{
ViewBag.Message = "Your contact page.";
return View();
}
}
你需要一些改变。让我们从数据库相关代码开始。不要将数据库相关的东西(MySqlConnection
、MySqlCommand
等)与表示层的东西(SelectListItem
、List<SelectListItem>
等)混合在一起,并在控制器内部进行,你应该
- 创建一个单独的 class 用于访问数据库和获取数据。
- 将被调用的方法应该 return 代表水果的某种 domain/entity 对象的列表。
所以,让我们先定义我们的 class, Fruit
:
public class Fruit
{
public string Code { get; }
public string Name { get; }
public Fruit(string code, string name)
{
Code = code;
Name = name;
}
}
然后让我们创建一个class,负责访问数据库和获取水果:
public class FruitsRepository
{
public List<Fruits> GetAll()
{
string sql;
var fruits = new List<Fruit>();
string constr = ConfigurationManager.ConnectionStrings["cn"].ConnectionString;
using (MySqlConnection con = new MySqlConnection(constr))
{
sql = @String.Format("SELECT * FROM `dotable`; ");
using (MySqlCommand cmd = new MySqlCommand(sql))
{
cmd.Connection = con;
con.Open();
using (MySqlDataReader sdr = cmd.ExecuteReader())
{
while (sdr.Read())
{
var fruit = new Fruit(sdr["sCode"].ToString(), sdr["sName"].ToString());
fruits.Add(fruit);
}
}
con.Close();
}
}
return fruits;
}
}
通常,这个 class 应该实现一个接口,以便我们将控制器与执行数据库操作的实际 class 分离,但我们现在不讨论这个。
然后在你的控制器上:
- 我们应该使用上面的class来获取水果。
- 我们应该创建一个 SelectListItem 对象列表,您可以将该列表提供给模型。
- 我们应该更改模型,使其包含有关所选水果的信息(查看下方)。
- 我们应该改变看法。
模型变化
public class PersonModel
{
[Required]
[Display(Name = "Fruits")]
public string SelectedFruitCode { get; set; }
public List<SelectListItem> Fruits { get; set; }
public string Namex { get; set; }
public string Codex { get; set; }
[Required]
[Display(Name = "CL")]
public string CL { get; set; }
[Required]
[Display(Name = "Ticket")]
public string Ticket { get; set; }
}
视图中的变化
@Html.DropDownListFor(model => model.SelectedFruitCode, Model.Fruits, "[ === Please select === ]", new { @Class = "textarea" })
@Html.ValidationMessageFor(model => model.SelectedFruitCode, "", new { @class = "text-danger" })
控制器的变化
[HttpGet]
public ActionResult Index()
{
var personModel = new PersonModel();
// THIS IS **BAD CODE**...Normaly, you should create an interface that describes
// what is expected from the class that communicates with the DB for operations
// related with the Fruit and then inject the dependency in the HomeController
// Constructor.
var fruitsRepo = new FruitsRepository();
var fruits = fruitsRepo.GetAll();
var fruitsSelecteListItems = fruits.Select(fruit => new SelectListItem
{
Text = fruit.Name,
Value = fruit.Code
}).ToList();
personModel.Fruits = fruitsSelecteListItems;
return View(personModel);
}
请仔细检查上面代码中的注释^^。作为评论中提到的起点,您可以看到 this.
更新
我们还必须更改 post 操作:
[HttpPost]
public ActionResult Index(PersonModel person)
{
// Removed the Model.IsValid check since it's redundant in your case
// Usually we use it and when it is valid we perform a task, like update
// the corresponding object in the DB or doing something else. Otherwise,
// we return a view with errors to the client.
var fruitsRepo = new FruitsRepository();
var fruits = fruitsRepo.GetAll();
var fruitsSelecteListItems = fruits.Select(fruit => new SelectListItem
{
Text = fruit.Name,
Value = fruit.Code,
Selected = String.Equals(fruit.Code,
person.SelectedFruitCode,
StringComparison.InvariantCultureIgnoreCase)
}).ToList();
person.Fruits = fruitsSelecteListItems;
return View(person);
}