无法将MVC模型属性绑定到输入元素

本文关键字:绑定 输入 元素 属性 模型 MVC | 更新日期: 2023-09-27 18:10:00

我在将模型绑定到由自定义助手方法创建的输入框时遇到了麻烦。我用一个名为"Html.AutoCompleteBoxAjax"的辅助方法包装了一个jquery ajax驱动的自动完成框。这个助手基本上只是创建一个具有javascript自动完成功能的元素。

模型中的属性是一个名为"formatName"的字符串。我已经验证了,在为视图生成的html中,输入元素的名称和id都是"formatName",并且没有其他具有这些标识的元素。我还检查了模型是否有默认构造函数,并且"formatName"属性是可公开访问的。最后,我已经验证了当Channel模型被传递到视图中时,Channel。formatName的值正确。尽管如此,我还是无法将值绑定到元素,并且输入框仍然是空白的。从另一个方向,从视图到控制器和通道,也没有绑定。formatName仍然为空。

我错过了什么?是因为我使用了自定义助手方法吗?

模型:

namespace WebApp.Models
{
    public class ChannelModel
    {
        XYZ.DataAccess.ODS.DB db = Config.DB();
        public string id { get; set; }
        // Parent Project
        [Display(Name = "Project")]
        public string projectID { get; set; }
        // Format Name
        [Required(ErrorMessage = "Format is required.")]
        [RegularExpression(Constants.username_regex, ErrorMessage = Constants.username_regexErrorMsg)]
        [Display(Name = "Format")]
        public string formatName { get; set; }
        // Channel Name
        [Required(ErrorMessage="Channel name is required.")]
        [StringLength(100, ErrorMessage = Constants.minLengthErrorMsg, MinimumLength = Constants.username_minLength)]
        [RegularExpression(Constants.username_regex, ErrorMessage = Constants.username_regexErrorMsg)]
        [Display(Name = "Channel name")]
        public string name { get; set; }
        // Sequence
        [Display(Name = "Sequence")]
        public string sequenceID { get; set; }
        public ChannelModel()
        {
            id = Guid.NewGuid().ToString();
        }
        public ChannelModel(XYZ.DataAccess.ODS.Channel channel_db)
        {
            id = channel_db.id;
            projectID = channel_db.project_id;
            name = channel_db.name;
            formatName = channel_db.format_name;
            sequenceID = channel_db.sequence_id;
        }
        public XYZ.DataAccess.ODS.Channel buildDBObject()
        {
            XYZ.DataAccess.ODS.Channel channel = new XYZ.DataAccess.ODS.Channel();
            channel.id = id;
            channel.project_id = projectID;
            channel.name = name;
            channel.format_name = formatName;
            channel.sequence_id = sequenceID;
            return channel;
        }
    }

}
<<p> 视图/strong>
@model WebApp.Models.ChannelModel
@using HelperMethods.Infrastructure
@{
    ViewBag.Title = "Edit";
    var sequences = ViewData["sequences"] as List<SelectListItem>;
}
<h2>Edit</h2>
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
@section header {
}
@using (Html.BeginForm())
{
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>Channel</legend>
        @Html.HiddenFor(model => model.id)
        @Html.HiddenFor(model => model.projectID)
        @Html.HiddenFor(model => model.name)
        <div class="editor-field">
            @Html.LabelFor(model => model.name):
            @Html.DisplayFor(model => model.name)
        </div>
        <div class="editor-label">
            @Html.Label("Format")
        </div>
        <div class="editor-field">
            @Html.AutoCompleteBoxAjax("formatName", Url.Action("GetFormatsBeginningWith"))
            @Html.ValidationMessageFor(model => model.formatName)
        </div>
        <!-- SEQUENCE -->
        <div class="editor-label">
            @Html.Label("Sequence")
        </div>
        <div class="editor-field">
            @Html.SlaveDropdownList("sequenceID", "groupID", Url.Action("GetSequencesInGroup"), WebApp.Util.makeSelectList(sequences, Model.sequenceID))
        </div>

        <p>
            <input type="submit" value="Save" />
        </p>
    </fieldset>
}
<div>
    @Html.ActionLink("Back to List", "Index")
</div>
控制器

namespace WebApp.Controllers
{
    public class ChannelController : Infrastructure.NoCacheController
    {
        XYZ.DataAccess.ODS.DB db = Config.DB();
        -- stuff --
        [HttpGet]
        public ActionResult GetFormatsBeginningWith(string term)
        {
            var formats = db.getFormatsBeginningWith(term);
            List<CustomHelpers.AutocompleteItem> items = new List<CustomHelpers.AutocompleteItem>();
            foreach (var format in formats)
                items.Add(new CustomHelpers.AutocompleteItem { value = format.name, label = format.name });
            var j = Json(items, JsonRequestBehavior.AllowGet);
            return j;
        }

        public ActionResult Edit(string id)
        {
            ChannelModel channelModel = new ChannelModel(db.getChannel(id));
            string groupID = db.getProject(channelModel.projectID).group_id;
            var sequences = db.getSequencesInGroup(groupID);
            ViewData["sequences"] = makeSelectListItems(sequences);
            return View(channelModel);
        }
        //
        // POST: /Channel/Edit/5
        [HttpPost]
        public ActionResult Edit(ChannelModel model)
        {
            if (ModelState.IsValid)
            {
                db.updateChannel(model.buildDBObject());
                return RedirectToAction("Index");
            }
            string groupID = db.getProject(model.projectID).group_id; 
            var sequences = db.getSequencesInGroup(groupID);
            ViewData["sequences"] = makeSelectListItems(sequences);
            return View(model);
        }
        -- more stuff --
    }
}

AutoCompleteBox的辅助方法

    public static MvcHtmlString AutoCompleteBoxAjax(this HtmlHelper html, string id, string actionUrl)
    {
        TagBuilder input = new TagBuilder("input");
        input.Attributes.Add("id", id);
        input.Attributes.Add("name", id);
        input.Attributes.Add("type", "text");
        input.AddCssClass("autocomplete_ajax");
        input.Attributes.Add("value", "");
        input.Attributes.Add("action", actionUrl);
        var variables = new Dictionary<string, string>() {
            {"AUTOCOMPLETE_ID", id}
        };
        var script = populateScriptTemplate("TEMPLATE_autocomplete_ajax.js", variables);
        StringBuilder s = new StringBuilder();
        s.AppendLine(input.ToString(TagRenderMode.SelfClosing));
        s.AppendLine(script);
        return new MvcHtmlString(s.ToString());
    }
自动补全
$('#AUTOCOMPLETE_ID').autocomplete({
    source: $('#AUTOCOMPLETE_ID').attr('action')
    });

视图html的相关部分

<div class="editor-field">
    <input action="/Channel/GetFormatsBeginningWith" class="autocomplete_ajax" id="formatName" name="formatName" type="text" value="" />
    <span class="field-validation-valid" data-valmsg-for="formatName" data-valmsg-replace="true"></span>
</div>

无法将MVC模型属性绑定到输入元素

答案很简单,有@Jakub的输入。helper本身必须填充这个值;HTML帮助程序没有自动绑定。一旦我解决了这个问题,自动绑定的帖子回到控制器工作如预期。