【问题标题】:How can I make my EditorFor disabled?如何使我的 EditorFor 禁用?
【发布时间】:2015-06-27 02:48:55
【问题描述】:

我有一个 MVC Razor Create 视图,我的模型包含一个或多个需要系统自动填充的字段,例如“时间戳”和“用户名”。因为这些字段是必需的,所以它们需要在表单中。

下面是当您允许 Visual Studio 从控制器构建视图时默认代码的示例。

        <div class="form-group">
        @Html.LabelFor(model => model.RoseUserName, 
            htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.RoseUserName, 
                  new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.RoseUserName, "", 
                  new { @class = "text-danger" })
        </div>
    </div>

这是渲染时代码的样子。它很实用,但第一个和第三个字段在不应该的时候是完全可编辑的。所以问题是我们如何让 EditorFor 字段在提交表单时将正确的数据输入模型但用户无法更改?

进一步说明 虽然您可能出于某些原因希望将这些字段从视图中隐藏起来,但您也有一些正当的原因希望用户看到这些字段,例如在公司内部网中,用户希望看到该信息。虽然 SQL Server 可以使用 getdate() 默认值自动生成日期戳,但在 Windows 身份验证下捕获用户的身份需要从 MVC 端完成。用户的识别是模型的一部分。

【问题讨论】:

    标签: razor asp.net-mvc-5


    【解决方案1】:

    一个重要的数据库特性是具有计算属性的能力。如果您将代码优先类映射到包含计算属性的表,您不希望 Entity Framework 尝试更新这些列。但您确实希望 EF 在插入或更新数据后从数据库中返回这些值。您可以使用 DatabaseGenerated 注释来标记类中的这些属性以及 Computed 枚举。其他枚举是 None 和 Identity。

    [DatabaseGenerated(DatabaseGenerationOption.Computed)] 
         public DateTime DateCreated { get; set; }
    

    现在只需让您的数据库在创建记录时生成时间戳。您也可以像这样将 DataAnnotation 设置为只读

    [DatabaseGenerated(DatabaseGenerationOption.Computed)] 
    [Editable(false)]
    public DateTime DateCreated { get; set; }
    

    希望这会有所帮助 更新

    // Private
    private DateTime _createdOn = DateTime.Now;
    // Public property
    [Display(Name = "Created On")]
    [DataType(DataType.DateTime)]
    [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:MM/dd/yyyy}")]
    public DateTime CreatedOn
    {
                get
                {
                    return (_createdOn == DateTime.MinValue) ? DateTime.Now : _createdOn;
                }
                set { _createdOn = value; }
    }
    

    或者在视图中。

    @Html.HiddenFor(model => model.CommentTime, new { @Value=System.DateTime.Now })
    

    或者在控制器中。

    public ActionResult Index()
        {
            return View(new MyViewModel
            {
                Birth = DateTime.Now
            });
        }
    

    如果在控制器和/或模型中完成,您可以像这样使用 readonly 的 html 属性。

    您可以使用自定义编辑器模板:

    public class MyViewModel
    {
        [UIHint("MyHiddenDate")]
        public DateTime Date { get; set; }
    }
    

    然后定义~/Views/Shared/EditorTemplates/MyHiddenDate.cshtml:

    @model DateTime
    @Html.Hidden("", Model.ToString("dd/MM/yyyy"))
    

    最后在你看来使用 EditorFor 助手:

    @model MyViewModel
    @Html.EditorFor(x => x.Date)
    

    这将为视图模型的 Date 属性呈现自定义编辑器模板,并因此使用所需格式呈现具有值的隐藏字段。

    更新

    EditorFor html 帮助器没有采用 HTML 属性的重载。在这种情况下,您需要使用更具体的内容,例如 TextBoxFor:

    <div class="editor-field">
        @Html.TextBoxFor(model => model.DateCreated , new 
            { disabled = "disabled", @readonly = "readonly" })
    </div>
    

    您仍然可以使用 EditorFor,但您需要在自定义 EditorTemplate 中有一个 TextBoxFor:

    public class MyModel
    {
        [UIHint("DateCreated ")]
        public string DateCreated { ;get; set; }
    }
    

    然后,在您的 Views/Shared/EditorTemplates 文件夹中,创建一个文件 DateCreated .cshtml。在该文件中,输入以下内容:

    @model string
    @Html.TextBoxFor(m => m, new {  @readonly = "readonly" })
    

    【讨论】:

    • 很高兴知道。我是 MVC 的新手,仍在学习。无论如何,我首先做了数据库。数据库已经存在。虽然 SQL Server 可以将 getdate() 作为默认日期时间值,但用户身份是 windows 用户身份,不适合让 SQL Server 尝试找出。
    • 发帖前我试过displayfor,但是当我点击提交按钮时,模型不接受它,这就是我回到editorfor的原因。我可以在不同的情况下使用隐藏选项,但是对于这种情况,我希望用户查看这些值,以便他们可以查看其中一个值是否不正确。基本上,我希望这些值可以看到但不可编辑,并且具有与可编辑控件相同的格式。我试过[Editable(false)],但是对控件没有影响。
    • 在控制器中设置日期。或模型。并且根本不显示该字段。
    • 在这种情况下,我需要显示日期和用户的 windows 身份。
    • 那么你必须在模型或控制器中设置日期并使用 HTML 属性 TextBox 是这里的关键 "@Html.TextBox("DateCreated ",new { @readonly="readonly" })" ,或尝试将模型设置为此“public DateTime Date {get; private set;}”
    【解决方案2】:
            <div class="form-group">
                    @Html.LabelFor(model => model.RoseUserName, 
                        htmlAttributes: new { @class = "control-label col-md-2" })
                    <div class="col-md-10">
                        @Html.EditorFor(model => model.RoseUserName, 
                              new { htmlAttributes = new { @class = "form-control", disabled = "disabled", @readonly = "readonly"} })
                        @Html.ValidationMessageFor(model => model.RoseUserName, "", 
                              new { @class = "text-danger" })
                    </div>
    
        ///add  disabled = "disabled", @readonly = "readonly along with@class = "form-control"
    ********@Html.EditorFor(model => model.RoseUserName, 
                              new { htmlAttributes = new { @class = "form-control", disabled = "disabled", @readonly = "readonly"} })
    

    【讨论】:

      【解决方案3】:

      当我发布这个答案时,它是基于我目前能够找到的。我了解到这是一个“当心你所希望的”的案例。提供的其他答案正确地指出,遵循下面显示的方法不是一种好的做法,并且至少有一个错误的前提,如对话线程中所述。

      这仅用于解释不该做什么。我接受的答案显示了我采用的方法。

      答案非常简单和优雅。 Tt 只需要一个额外的短语:@readonly="readonly"

      在更好的上下文中,原始示例是:

              <div class="form-group">
              @Html.LabelFor(model => model.RoseUserName, 
                  htmlAttributes: new { @class = "control-label col-md-2" })
              <div class="col-md-10">
                  @Html.EditorFor(model => model.RoseUserName, 
                        new { htmlAttributes = new { @class = "form-control" } })
                  @Html.ValidationMessageFor(model => model.RoseUserName, "", 
                        new { @class = "text-danger" })
              </div>
      

      你所做的只是将@readonly="readonly"添加到EditorFor html属性中,像这样:

      @Html.EditorFor(model => model.RoseUserName, 
           new { htmlAttributes = new { @class = "form-control", @readonly="readonly" } })
      

      问题解决了。

      【讨论】:

      • 这不是一个好的解决方案 - 因为 (1) 您只是将额外的信息发送到视图,然后再次原封不动地发回(降低性能)(2) 恶意用户可以轻松地覆盖这些值你也不会更聪明。应该如何完成 - 创建一个仅包含您需要的属性的视图模型。如果您想显示UserNameDateStamp,那么只需使用@Html.DisplayFor(),否则从视图模型中省略它们。发布时,从存储库中获取数据模型并根据视图模型属性更新其属性,然后保存数据模型
      • 你提出了一些好观点。我还没有学会如何创建存储库,所以我会研究一下。你描述了一些对我有用的东西。唯一剩下的问题是我无法使渲染的DisplayFor 看起来与EditorFor 相同。但这是一个不同的线程。无论如何,我还有更多的研究要做。谢谢。
      • 这只是使用 css 设置样式的问题。将@Html.DisplayFor() 放在(比如说)&lt;div class="readonly"&gt; 中,然后使用 css 设置边框、填充等(检查虚拟禁用文本框的 css 以查看所有要设置的值)
      • 谢谢@StephenMuecke。我终于看到了我是多么需要范式转变。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多