0

MVC3 と EF4 を使用して Web アプリケーションを作成しています。以下のようなアクション ヘッダーを使用して、ユーザーが送信したフォームの値を取得しています。

<HttpPost()>
Public Function Edit(ByVal prod as Product) As ActionResult

以下のコードを使用してレコードを更新します。

db.Attach(prod)
db.ObjectStateManager.ChangeObjectState(prod, EntityState.Modified)
db.SaveChanges()

データベースで更新する prod オブジェクトで送信された値を取得します。問題は、ProductCost など、Product の特定のフィールドを変更することを許可されていないユーザーがいるということです。HTML でそのようなフィールドのテキスト ボックスを無効にしました。ただし、これはクライアント側であるため、ユーザーは Firebug などのツールを使用して簡単に有効化し、値を変更できます。

私が思いついた唯一の解決策は、データベースから既存のレコードを取得し、その ProductCost 値を prod.ProductCost にコピーすることでした。しかし、これを達成するためにクエリを発行するのは好きではありません。これを達成するためのより良い方法はありますか?

編集:特定のフィールドを更新するための以下のリンクが見つかりました。Entity Frameworkを使用して1つのフィールドのみを更新する方法は?

以下のコードを使用して、特定のフィールドを変更できます。

context.ObjectStateManager.GetObjectStateEntry(user).SetModifiedProperty("FieldName");

問題は、ユーザーが変更できるすべてのフィールドに対して上記のステートメントを記述する必要があるかどうかです。はいの場合、製品モデルに 10 個のフィールド (1 つの主キー) があり、ユーザーが主キーを除くすべてのフィールドを変更できると仮定すると、9 つのステートメントを記述する必要がありますか?? 一度に複数のプロパティを指定できる方法はありますか。または、変更されていないプロパティを指定するより良いもの。(注:フィールド名の配列に対してループを実行して、9つのステートメントを書くことを避けることができることを知っています。別の方法を求めており、上記をリファクタリングしていません)

4

1 に答える 1

2

クライアントのデータを信用しないでください。入力を検証し、適切なアクションを実行するためのサーバー コードを常に用意してください。

Respiratory メソッドの個別のオーバーロードを作成し、さまざまな方法で製品を更新してから、現在のユーザーのアクセス タイプを確認します。彼が管理者の場合は、すべてを更新するオーバーロードを呼び出します。マネージャーの場合は、 name、imageUrl、price を更新するメソッド。彼が従業員の場合は、name と ImageURL のみを更新するメソッドを呼び出します。

[HttpPost]
public ActionResult Edit(Product prod)
{
  if(ModelState.IsValid) 
  {
    string userType=GetCurrentUserTypeFromSomeWhere();
    if(userType=="admin")
    {
       repo.UpdateProduct(prod);
    }
    else if(userType=="manager")
    {
       repo.UpdateProduct(prod.ID, prod.Name, prod.ImageUrl, prod.Price);
    } 
    else if(userType=="employee")
    {
       repo.UpdateProduct(prod.ID, prod.Name, prod.ImageUrl);
    } 
    return RedirectToAction("Updated",new {id=prod.ID});
  }

}
于 2012-09-18T20:18:05.417 に答える