16

開発者が ASP.NET MVC プロジェクトの ViewModel オブジェクトで属性を使用するBindと、アプリケーションに悪影響を与える可能性があるのはなぜですか?

[Bind(Include = "Id,Name")]
[MetadataType(typeof (MyViewModelValidation))]
public class MyViewModel
{
    public string CustomerProductUserName { get; set; }

    [Display(Name = "Name")]
    public string Name { get; set; }

}

public class MyViewModelValidation
{
    [HiddenInput(DisplayValue = false)]
    public int Id { get; set; }

    [Required]
    public string Name{ get; set; }
}
4

4 に答える 4

20

まずMetadataType、ViewModel のクラスを作成する必要はありません。ViewModel でデータ注釈属性を直接使用できます。MetadataTypeクラスは、EF またはその他の ORM によって自動的に生成されたモデルに使用されるため、自動生成されたコードに触れることなくデータ注釈属性を使用できます。

このBind属性を使用する必要はありません。Bind 属性のプロパティを使用する場合をInclude除きExclude、Model のプロパティをバインディングに含めたりバインディングから除外したりする必要はありません。

たとえば、質問のコードでは、ビューからモデルを送信するときにIdとプロパティのみがバインドされます。Nameのビューに入力がある場合でもCustomerProductUserName、フォームを送信すると、プロパティは常に null になります。これは、自動生成された ID フィールドをバインディングに含めたくない場合などに役立ちます。

検証はモデル バインディングの一部として実行されるため、バインディングから除外されたプロパティも検証から除外されます。また、Bindセキュリティ上の理由から属性を使用することもできます。たとえば、モデル内のプロパティだけがコントローラーにポストされていることを確認したい場合などです。

于 2013-08-16T15:32:14.347 に答える
15

bind 属性を使用する目的は、リクエストの投稿中に攻撃者がプロパティ値を割り当てないようにすること、またはバインドするプロパティを制御することです。

呼び出されたクラスとMember、メンバーを保存する create メソッドがあるとします。MemberTypeしかし、ユーザーにプロパティの値を送信してほしくありません。

Class Member  
{  
    public int MemberId { get; set; }  
    public string FirstName { get; set; }  
    public string LastName { get; set; }  
    public string MemberType { get; set; }  
}  

[HttpPost]  
Public ActionResult Create(Member member)  
{  
    Save(member);  
}

ここでは、デフォルト値である正規メンバー タイプのみを提供しているとします。Propertyの入力を許可しないことで、ユーザーが MemberType プロパティの値を送信できないようにできると考えるかもしれませんMemberType。しかし、ユーザーがメンバー オブジェクトを投稿すると、攻撃者はリクエストを傍受し、リクエストで MemberType 値を送信し 、メンバーをプレミアムMemberId=1&FirstName=Chandra&LastName=Malla&MemberType=Premiumメンバーとして保存する可能性があります。これを防ぐために、クラスを属性で装飾できます。 MemberBind

[Bind(Include="MemberId,FirstName,LastName")]  
Class Member  
{
    ...

また

[Bind(Exclude="MemberType")]  
Class Member  
{  
    ...

オブジェクトが投稿された場​​合、 MemberTypeMemberプロパティの値は投稿されません。

ViewModel を使用している場合は、ViewModel で MemberType プロパティを省略できるため、必ずしも bind 属性を使用する必要はありません。

Class Member  
{  
    public int MemberId { get; set; }  
    public string FirstName { get; set; }  
    public string LastName { get; set; }  
    public string MemberType { get; set; } 
}  

Class MemberViewModel  
{       
    public int MemberId { get; set; }   
    public string FirstName { get; set; }  
    public string LastName { get; set; }  
}  

[HttpPost]  
Public ActionResult Create(MemberViewModel memberviewmodel)  
{  
    Save(memberviewmodel);  
}

モデルや ViewModel を適切に設計せず、バインド属性を使用して不要なプロパティの投稿を回避しないと、悪影響が生じる可能性があります。

于 2014-11-12T04:40:32.363 に答える