Ajax.BeginForm with Dropdown + Server Side Validation

本文关键字:Server Side Validation Dropdown BeginForm with Ajax | 更新日期: 2023-09-27 18:30:17

我正在尝试构建一个Ajax.BeginForm(有一个下拉列表),它使用服务器端验证来检查模型的注释。我无法使下拉列表正常工作。最初,我使用viewbag填充了下拉列表:

视图:

@Html.DropDownList("CheckIn_Location", ViewBag.CageLocationList as IEnumerable<SelectListItem>, "(Select one)", new { @class = "form-control" })

控制器:

    public void GetCageLocations()
    {        
        IEnumerable<SelectListItem> selectList =
        from c in db.Locations
        select new SelectListItem
        {
            Text = c.LocationName,
            Value = c.Id.ToString()
        };
        ViewBag.CageLocationList = selectList;
    }

但这似乎对服务器端验证并不友好,所以我尝试重新设计我的模型/视图/控制器:

这是我的模型:

public class CheckInViewModel
{
    public int CheckIn_Id { get; set; }
    [Required(ErrorMessage = "Location Required.")]
    public IEnumerable<SelectListItem> CheckIn_Location { get; set; }
    [Required(ErrorMessage = "Quantity Required.")]
    [Range(1, 100, ErrorMessage = "Quantity must be between 1 and 100000")]
    public int CheckIn_Quantity { get; set; }
    public string CheckIn_Comment { get; set; }
}

这是我的控制器:

    [HttpPost]
    public ActionResult CheckIn(CheckInViewModel model)
    {
        if (ModelState.IsValid)
        {
            var New_Transaction = new Transaction
            {
                Id = model.CheckIn_Id,
                Quantity = model.CheckIn_Quantity,
                LocationId = Convert.ToInt32(model.CheckIn_Location),
                TransactionDate = DateTime.Now,
                TransactionComments = model.CheckIn_Comment.Replace("'r'n", " ")
            };
            unitOfWork.TransactionRepository.Insert(New_Transaction);
            unitOfWork.Save();
            return PartialView("CheckIn", model);
        }
        return PartialView("CheckIn", model);
    }

这是我的名为CheckIn.cshtml的部分视图

@model ViewModels.CheckInViewModel
<!-- Modal -->
<div class="modal fade" id="CheckInModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
                <h1 class="modal-title" id="CheckInModalLabel">Check In</h1>
            </div>
            <div class="modal-body">
            @using (Ajax.BeginForm("CheckIn", "Cage", null, new AjaxOptions { HttpMethod = "POST", OnSuccess = "success", OnFailure  = "failure"}, new { @id = "CheckInForm", @class = "form-horizontal" }))
            {
                @Html.ValidationSummary(true)
                @Html.HiddenFor(model => model.CheckIn_Id, new { @class = "form-control" })
                <div class="form-group">
                    <label for="CheckIn_Location" class="col-sm-4 control-label">Location</label>
                    <div class="col-sm-8">
                        @Html.DropDownListFor(x => x.CheckIn_Location, Model.CheckIn_Location, "Select One")
                        @Html.ValidationMessageFor(model => model.CheckIn_Location)
                    </div>
                </div>
                <div class="form-group">
                    <label for="CheckIn_Quantity" class="col-sm-4 control-label">Quantity</label>
                    <div class="col-sm-8">
                        @Html.TextBoxFor(model => model.CheckIn_Quantity, new { @class = "form-control" })
                        @Html.ValidationMessageFor(model => model.CheckIn_Quantity)
                    </div>
                </div>
                <div class="form-group">
                    <label for="CheckIn_Comment" class="col-sm-4 control-label">Comment</label>
                    <div class="col-sm-8">
                        @Html.TextAreaFor(model => model.CheckIn_Comment, new { @class = "form-control" })
                    </div>
                </div>
            }
        </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
                <button type="button" class="btn btn-primary" onclick="SubmitCheckInForm()">Check In</button>
            </div>
        </div>
    </div>
</div>

下面是触发提交的 JS 函数:

    function SubmitCheckInForm() {
            $('#CheckInForm').submit();
        }

有人可以告诉我如何:

  1. 使用模型作为绑定代理(而不是我之前所做的视图包)填充下拉列表(值/文本)
  2. 将所选选项返回到控制器,并将其插入到事务表的位置元素(即 INT)中
  3. 正确地连接这一切,以便服务器端注释工作并在表单中出现错误时返回消息。

提前感谢!

Ajax.BeginForm with Dropdown + Server Side Validation

如果我理解正确,有不止一种方法可以做到这一点。例如,模型中可以有两个属性来管理 Dropdown 控件。

1- CheckIn_Location_Selected。存储用户选择的值

2- CheckIn_Location_List。以填充下拉列表。

这可能是您的模型。

public class CheckInViewModel
{
    [Required(ErrorMessage = "Location Required.")]
    public int CheckIn_Location_Selected { get; set; } 
    public IEnumerable<SelectListItem> CheckIn_Location_List { get; set; }
    //Rest of the properties...
}

所以现在在你的GET操作中,你可以有这样的东西:

    [HttpGet]
    public ActionResult CheckIn()
    {
        var model = new CheckInViewModel
        {
            CheckIn_Location_List = repository.GetCageLocations().Select(
                location => new SelectListItem
                {
                    Value = location.Id.ToString(),
                    Text = location.LocationName
                })
        };
        return View(model);
    }

在您看来:

@Html.DropDownListFor(x => x.CheckIn_Location_Selected, Model.CheckIn_Location_List, "Select One")

我们需要稍微改变一下您的 POST 操作。

[HttpPost]
    public ActionResult CheckIn(CheckInViewModel model)
    {
        if (!ModelState.IsValid)
        {
            // This is necessary because we are sending the model back to the view.
            // You could cache this info and do not take it from the DB again.
            model.CheckIn_Location_List = repository.GetCageLocations().Select(
                location => new SelectListItem
                {
                    Value = location.Id.ToString(),
                    Text = location.LocationName
                });
            return PartialView("CheckIn", model);
        }
        var New_Transaction = new Transaction
        {
            Id = model.CheckIn_Id,
            Quantity = model.CheckIn_Quantity,
            LocationId = Convert.ToInt32(model.CheckIn_Location_Selected),
            TransactionDate = DateTime.Now,
            TransactionComments = model.CheckIn_Comment.Replace("'r'n", " ")
        };
        unitOfWork.TransactionRepository.Insert(New_Transaction);
        unitOfWork.Save();
        return PartialView("CheckIn", model);
    }