9

レンダリングされたビューでビュー フィールドが読み取り専用になるように、属性を使用してビュー モデル プロパティを読み取り専用としてマークしたいと考えています。System.ComponentModel.DataAnnotations.EditableAttribute を適用すると、必要な属性が正確に表示されますが、機能しないようです。つまり、テキスト ボックス フィールドはまだ編集可能です。私は周りを見回しましたが、答えが見つからず、関連する質問がいくつかあります。以下に適用される editable 属性は、ビューがレンダリングされるときに機能しません。

[Display(Name = "Last Name")]
[Editable(false, AllowInitialValue = true)]
public string LastName { get; set; }

このようなビュー ヘルパー関数を使用して読み取り専用の動作を実現できますが、私の好みはモデル プロパティの属性を使用することです。

@functions {
    object getHtmlAttributes()
    {
    if (@ViewBag.Mode == "Edit")
    {
      return new {style = "width:100px;background:#ff6;", @readonly = "readonly"};
    }

    return new { style = "width:100px;" };  
}
} 

@Html.TextBoxFor(model => model.FirstName, getHtmlAttributes())

カスタム検証属性を含む他の属性は完全に正常に機能します。データ注釈の編集可能な属性がこのコンテキストで機能するか、上記のように機能するか、それとも他に何かする必要があるか教えていただけますか? ありがとう。

4

5 に答える 5

5

EditableAttribute ドキュメントには次のように記載されています。

データ フィールドに EditableAttribute 属性が存在することは、ユーザーがフィールドの値を変更できるかどうかを示します。

このクラスは、フィールドが編集可能であることを強制も保証もしません。基になるデータ ストアでは、この属性の存在に関係なく、フィールドの変更が許可される場合があります。

残念ながら、これは、この属性を使用しても MVC での検証に影響がないことを意味します。これは間違っているように感じますが、MVC フレームワークに実装するには何が必要かを考えれば理にかなっています。たとえば、典型的な「編集」ビューでは、ユーザーはモデルが (通常は DB レコードから) 取り込まれ、ユーザーにレンダリングされるビューに与えられる最初の GET 要求を実行します。次に、ユーザーはいくつかの編集を行い、フォームを送信します。フォームを送信すると、Model の新しいインスタンスが POST パラメータから構築されます。インスタンスの 1 つ (GET 要求からの最初のインスタンス) が既に破棄されているため、両方のオブジェクト インスタンスでフィールドが同じ値であることをバリデーターが確認することは非常に困難です。

アトリビュートに機能がない場合、わざわざそれを使用する必要があるでしょうか?

私の推測では、彼らは開発者が意図を示すためにコード内でそれを使用することを期待しています。より実際には、独自のカスタム コードを記述して、この属性の存在を確認することもできます...

AttributeCollection attributes = TypeDescriptor.GetAttributes(MyProperty);
if (attributes[typeof(EditableAttribute)].AllowEdit)
{
   // editable
}
else
{
   // read-only
}

また、これらの DataAnnotation 属性は MVC アプリケーション用だけでなく、さまざまな種類のアプリケーションに使用できることにも注意してください。MVC はこの属性に対して特別なことを何もしませんが、他のフレームワークはこの属性の機能/検証を実装しています

于 2012-11-28T18:05:36.253 に答える
2

この問題を自分で半解決しました。

[HiddenInput(DisplayValue = true)]

フィールドは表示されますが、編集できません。

于 2012-07-07T03:00:17.993 に答える
1

モデルで Readonly の代わりに Editable を使用してもまったく同じように機能することがわかりました。

[ReadOnly(true)] //or
[Editable(false)]
public string Name { get; set; }

この構文は、ビュー自体のプロパティ属性を調べるときに機能します。属性が編集可能(true)の場合にも機能します

@if (ViewData.ModelMetadata.Properties.Where(p => p.PropertyName == "Name").First().IsReadOnly)
{ 
    @Html.TextBoxFor(model => model.Name, new { style = "width:190px; background-color: #ffffd6", @readonly =  "readonly" })
} 
else
{
    @Html.TextBoxFor(model => model.Name, new { style = "width:190px; " })
}

ここでエディタ テンプレートを使用して、単純な文字列テンプレートを作成します。

@model String
@{
IDictionary<string, object> htmlAttributes = new Dictionary<string, object>();
if (ViewData.ModelMetadata.IsReadOnly) //this will be looking at the actual property not the complete model
{
htmlAttributes.Add("style", "width:100px; background-color:#ffffd6");
htmlAttributes.Add("readonly", "readonly");
@Html.TextBox("", Model, htmlAttributes)
}
于 2012-11-29T20:11:02.487 に答える
1

別の作成シナリオがありますか? 初期値を許可している特定の理由はありますか? ドキュメントに次のように記載されているため、質問します。

通常、両方のプロパティに同じ値を含める必要があるため、クラス コンストラクターで AllowInitialValue プロパティを AllowEdit の値に設定します。

false に設定し、明示的に宣言しないとうまくいくと思いますAllowInitialValue

于 2012-04-13T15:08:13.497 に答える
0

あなたがまだこれを理解しているかどうかはわかりませんが、私たちは

System.ComponentModel.ReadOnlyAttribute

利用方法

[ReadOnly(true)]
于 2012-11-06T21:49:07.630 に答える