ASP.Net MVC动态输入绑定到相同的控制器属性

时间:2018-12-04 14:56:06

标签: asp.net-mvc asp.net-core-mvc model-binding

我有2个控制器字段,分别是“类型”和“数据”。 根据要为“类型”(日期或文本)选择的值,我想动态地将“数据”字段显示为文本输入或自定义时间选择器输入。 由于任何时候都只能渲染一个,因此我需要使用相同的属性名称(Data)进行绑定。 这就是我正在尝试的:

@if (Model.Type == "Date")
{
   // custom timepicker control goes here
   <input asp-for="Data" class="form-control timepicker"/>
}
else
{
   <input asp-for="Data" class="form-control text-input" type="text"/>
}

在页面加载时,仅呈现文本输入,并且根据所选的类型显示/隐藏。不会显示时间选择器输入(根本不会生成html)。

有没有办法在MVC中实现这一目标?

2 个答案:

答案 0 :(得分:1)

不能有两个具有相同名称的<input>元素。如果发布的<form>包含多个具有相同名称的输入,则MVC模型绑定程序将仅绑定来自最后一个输入的一个值。

要实现所需的目标,您有两种选择:

  • 在视图中只有name="Data"的{​​{1}}的一个输入,然后让时间选择器将时间作为字符串写入此输入。然后在控制器中,根据选定的type="text"解析此输入值。

  • 或者具有两个Typename="TextData"输入,并根据选定的name="TimeData"使用JS禁用和隐藏这些输入之一。在控制器中,根据所选的Type从右侧输入中读取值。可以说这是更清洁的解决方案。

在MVC5中,第二个解决方案看起来像这样(我不熟悉MVC-Core):

Type

控制器:

@model MyViewModel
@using (Html.BeginForm("Submit", "MyController", FormMethod.Post)) {
    @Html.EditorFor(m => m.Type)
    @Html.EditorFor(m => m.TextData, new { @class = "text-input"})
    @Html.EditorFor(m => m.TimeData, new { @class = "timepicker"})
}

<script type="text/javascript">
    function toggleInput_() {
         if ($('#@Html.IdFor(m => m.Type)').val() === 'Text') {
             $('#@Html.IdFor(m => m.TextData)').prop('disabled', false).show();
             $('#@Html.IdFor(m => m.TimeData)').prop('disabled', true).hide();
         }
         else {
             $('#@Html.IdFor(m => m.TextData)').prop('disabled', true).hide();
             $('#@Html.IdFor(m => m.TimeData)').prop('disabled', false).show();
         }
    }

    $(document).ready(function() {
        $('#@Html.IdFor(m => m.Type)').on('change', function() {
            toggleInput_(); // toggle when drop down changes
        });

        toggleInput_(); // toggle initially on page load
    });
</script>

答案 1 :(得分:1)

ASP MVC已经使用编辑器模板内置了此功能。通过遵循约定,您可以指定将用于@Html.EditorFor()呈现的任何类型(包括用户定义的复杂类型)的模板。

简而言之,只需将两个局部视图放在~/Views/Shared/EditorTemplates文件夹中,一个局部视图为模型类型DateTime,另一个局部模型为string。当基于@Html.EditorFor(m => m.Property)的类型使用Property时,将呈现正确的局部视图。

注意:string属性的默认编辑器已经是type="text"的输入,因此您不必指定该模板

有关编辑器模板(和显示模板)的教程,请参见以下链接: https://exceptionnotfound.net/asp-net-mvc-demystified-display-and-editor-templates/