c# - 来自 ASP.Net MVC 中 ViewModel 的验证 DropDownList 值
问题描述
我试图搜索帖子,也没有任何结果,也许我没有使用正确的词。
我需要一个解决方案MVC
来验证值,使用方法和MySqlDropDownList
从数据库填充。Model class
Html.DropDownListFor Helper
在我添加了新的视图中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>
)混合并在控制器中这样做,你应该
- 创建一个单独的类来访问数据库和获取数据。
- 将被调用的方法应该返回一个表示水果的某种域/实体对象的列表。
所以,让我们首先定义我们的类Fruit
:
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<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;
}
}
通常,这个类应该实现一个接口,以便我们将控制器与执行数据库操作的实际类分离,但我们现在不讨论这个。
然后在你的控制器上:
- 我们应该使用上面的类来获取水果。
- 我们应该创建一个 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);
}
推荐阅读
- amazon-web-services - 如何限制仅从 NLB 访问 EC2
- asp.net - MVC 中的 CRUD 表单并将数据发布到 Web Service soap (VB)
- html - 同一行中的不同数据
- java - GAE 错误:API 请求 datastore_v3.Get() 发生错误
- python - 在 Python 中优化列表的运行时
- python - 如何在数据框中的两列中交替值?
- r - 使用源函数加载函数
- bash - 比较两个版本的 zip 文件并找出该 zip 中哪个文件已被修改
- reactjs - 在开发模式下为具有不同静态前缀的反应应用程序提供服务
- hyperlink - AxAcroPDF 不会打开超链接