繁体   English   中英

ASP.Net MVC 中来自 ViewModel 的验证 DropDownList 值

[英]Validation DropDownList value from ViewModel in ASP.Net MVC

我试图搜索帖子,也没有任何结果,也许我没有使用正确的词。

我需要MVC的解决方案来验证DropDownList值,使用Model classHtml.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();
    }
}

你需要一些改变。 让我们从与数据库相关的代码开始。 而不是将数据库相关的东西( MySqlConnectionMySqlCommand等)与表示层的东西( SelectListItemList<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);
 }

请仔细检查上面代码中的注释^^。 作为评论中提到的起点,您可以看到这个

更新

我们还必须更改 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);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM