C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[7]: ASP MVC Bind属性について


(過去ログ 140 を表示中)

[トピック内 9 記事 (1 - 9 表示)]  << 0 >>

■82282 / inTopicNo.1)  ASP MVC Bind属性について
  
□投稿者/ yapii (13回)-(2016/12/28(Wed) 05:28:46)

分類:[.NET 全般] 

2016/12/28(Wed) 05:31:27 編集(投稿者)
2016/12/28(Wed) 05:31:13 編集(投稿者)

<pre><pre>ASP.NET MVC 勉強中です。

Bind属性のIncludeプロパティなのですが、参考書にはExcludeではなくIncludeを使った方がよいとありました。

もしモデルのプロパティが追加されてInclude定義を更新し忘れた場合、値がバインドされていないという明確な結果になり問題が特定しやすいが、
Excludeで定義を更新し忘れても、オーバーポスティング攻撃にあうまで気づかないからだそうです。
(この意見には異議ありません)

しかし、入力画面のすべての引数にIncludeを定義するのはめんどくさいし、メンテがしんどいです。

規約で1つのビューモデルに入力値用のモデルと表示用のモデルを突っ込んで
表示する際はまとめたビューモデルを
受け取る際は入力値用のモデルを使用するようにしてはダメでしょうか?
   public class SampleViewModel
    {
        public class InputViewModel
        { 
            [Display(Name = "string値")]
            public string StringValue { get; set; }

            [Display(Name = "int値")]
            public int? IntValue { get; set; }
        }
        public class ReadonlyViewModel
        { 
            [Display(Name = "権限")]
            public string Role { get; set; }
        }
    }

全部受け取るなら、Bind属性指定しなくてもいいんじゃないかと思いましたが
後でプロパティが追加されたたとき「定義を更新し忘れても、オーバーポスティング攻撃にあうまで気づかない」と同じになるかと思いました。
みなさんはどうされているのでしょうか?
本当に一つ一つ定義しているのでしょうか?
めんどくさくないですか?</pre></pre>

引用返信 編集キー/
■82286 / inTopicNo.2)  Re[1]: ASP MVC Bind属性について
□投稿者/ WebSurfer (1106回)-(2016/12/28(Wed) 12:47:23)
No82282 (yapii さん) に返信

> Bind属性のIncludeプロパティなのですが、参考書にはExcludeではなくIncludeを使った方がよいとありました。

それは、質問者さんのコードを例に取ると、入力モデルに InputViewModel を使うが、ユーザー
から受け取るのは StringValue のみというような場合に、ホワイトリスト (include) を使うか、
ブラックリスト (exclude) を使うかという話ですよね。それはもう、ケースバイケース / 適材
適所 / 好みの問題だと思います。

ユーザーに StringValue と IntValue の両方を入力して POST してもらう場合は、どちらかはバイ
ンド不要だから受け取らないということはないはずなので、include も exclude も出番はないので
は。たぶんそういう使い方が普通ではないかと思いますが、そうであれば、

> 全部受け取るなら、Bind属性指定しなくてもいいんじゃないかと思いましたが

はその通り(と言うか、Bind 属性指定は意味がない)と思います。

> 後でプロパティが追加されたたとき

・・・も、それをユーザー入力として受け取るのであれば(普通そうですよね、だらか追加するの
でしょうから)、include も exclude も出番はないはずです。

Bind 属性指定とユーザー入力の検証は別の話だと言うことは理解されてますよね?

モデルバインディング+データアノテーション検証の機能を利用している場合、アクションメソッド
の引数が指すオブジェクトに送信されてきたデータがバインドされると同時にサーバー側で検証され
ますので、コントローラーで ModelState.IsValid が ture であればアクションメソッドの引数が指
すオブジェクトにバインドされたデータは検証結果 OK ということになります。

引用返信 編集キー/
■82287 / inTopicNo.3)  Re[2]: ASP MVC Bind属性について
□投稿者/ yapii (14回)-(2016/12/28(Wed) 13:50:22)
WebSurfer さん いつもありがとうございます。

質問がうまく伝わりませんでした。
すみません。


何も考えずにビューモデルを作成すると、下記のようになると思います。

Roleプロパティは表示項目で編集はしません。
StringValueとIntValueは入力項目です。

public class SampleViewModel
{
    [Display(Name = "string値(入力項目)")]
    public string StringValue { get; set; }

    [Display(Name = "int値(入力項目)")]
    public int? IntValue { get; set; }

    [Display(Name = "権限(表示項目)")]
    public string Role { get; set; }
    
}
これをアクションメソッドで受け取るとき
Bind属性でInclude="StringValue,IntValue"としないといけないのですよね?
でないと表示項目であるRoleがビューモデルにバインドされてしまいます。
このとき悪意あるユーザーが異なるRoleを含むデータをポストされる可能性があり、意図しない結果になると認識しています。

※その後の処理でRoleが分岐の判断に使用されたり、データベースに更新されたりしないようなら
とくにBind属性は不要と思っています。


しかし、Includeにプロパティ名を書き連ねるのがめんどくさいので、
一つのビューモデルに、Input用のモデルと、表示項目用のモデルを含めてしまって
public class SampleViewModel
{
    public class InputViewModel
    { 
        [Display(Name = "string値(入力項目)")]
        public string StringValue { get; set; }

        [Display(Name = "int値(入力項目)")]
        public int? IntValue { get; set; }
    }
    public class ReadonlyViewModel
    { 
        [Display(Name = "権限(表示項目)")]
        public string Role { get; set; }
    }
}

ビューを表示する際は全体のビューモデルを渡して
public ActionResult Show()
{
	SampleViewModel mdl = CreateModel();
	return View(mdl);
}
受け取る際は入力モデルを引数にとれば楽なのかな
public ActionResult Update(SampleViewModel.InputViewModel inpmdl)
{

}

と思いました。

ですがこんなことは普通しなくて、もっといい方法があるかと思い質問しました。


引用返信 編集キー/
■82288 / inTopicNo.4)  Re[3]: ASP MVC Bind属性について
□投稿者/ WebSurfer (1107回)-(2016/12/28(Wed) 15:39:23)
No82287 (yapii さん) に返信

> しかし、Includeにプロパティ名を書き連ねるのがめんどくさいので、
> 一つのビューモデルに、Input用のモデルと、表示項目用のモデルを含めてしまって

モデルの構造を変えたりアクションメソッドの引数を区別したりする方がよほど面倒
で分かりにくく、普通のやり方ではないので保守でも問題を起こしそうな気がするの
ですが。

> ですがこんなことは普通しなくて、もっといい方法があるかと思い質問しました。

なので、自分的には「もっといい方法」は include, exclude を使うという普通に
取る手段だと思います。
引用返信 編集キー/
■82289 / inTopicNo.5)  Re[3]: ASP MVC Bind属性について
□投稿者/ WebSurfer (1108回)-(2016/12/28(Wed) 15:52:11)
No82287 (yapii さん) に返信

先の私のレスでは、データは DB から Entity Framework を利用して以下のようなクラス
のコレクションとして取得して来るということが頭にあったので、モデル構造を変える方
がよほど面倒と思ったのですが、そういう話ではないのでしょうか?

> public class SampleViewModel
> {
> [Display(Name = "string値(入力項目)")]
> public string StringValue { get; set; }
>
> [Display(Name = "int値(入力項目)")]
> public int? IntValue { get; set; }
>
> [Display(Name = "権限(表示項目)")]
> public string Role { get; set; }
>
> }


引用返信 編集キー/
■82290 / inTopicNo.6)  Re[4]: ASP MVC Bind属性について
□投稿者/ yapii (15回)-(2016/12/28(Wed) 16:37:32)
そうですね。
DBから取ってくるときの面倒さを忘れていました。
すいません。

最後に確認したいのですが
1、全部バインドするならBind属性は書かない
(後でプロパティが追加されることは考えなくてよい)

2、モデルに表示だけのプロパティがあったとしても、その値を更新したり、制御に使用しないのであれば
(表示時に見せるだけ)Bind属性は書かなくもよい

以上の認識でよろしいでしょうか?
引用返信 編集キー/
■82291 / inTopicNo.7)  Re[5]: ASP MVC Bind属性について
□投稿者/ WebSurfer (1109回)-(2016/12/28(Wed) 17:53:33)
No82290 (yapii さん) に返信

自分ならどうするかというレベルの話ですが、質問者さんの SampleViewModel 例で具体
的に言うと:

(1) StringValue, IntValue, Role の 3 項目全てをユーザーが送信してきて、それを全て
  受け取って処置する場合は include も exclude も付与しない。

(2) StringValue, IntValue の 2 項目のみをユーザーが送信してきて、その 2 項目のみ
  を受け取って処置す場合は、[Bind(include="StringValue, IntValue")] を付与する。

・・・というようにすると思います。
引用返信 編集キー/
■82293 / inTopicNo.8)  Re[6]: ASP MVC Bind属性について
□投稿者/ yapii (16回)-(2016/12/30(Fri) 10:47:48)
ありがとうございました。

(2)の場合はBind属性を使用するのですね。

またよろしくお願いいたします。
解決済み
引用返信 編集キー/
■82294 / inTopicNo.9)  Re[7]: ASP MVC Bind属性について
□投稿者/ WebSurfer (1110回)-(2016/12/30(Fri) 13:45:03)
No82293 (yapii さん) に返信

マイクロソフト公式解説書「プログラミング ASP.NET MVC」を読んでたら以下の
ような解説を見つけたので紹介しておきます。

"Include 属性と Exclude 属性を同じパラメーターに指定するほうがバインドす
るプロパティをより効果的に定義できる場合は、そうしてもかまいません。たと
えば、両方の属性で同じプロパティを指定した場合は、Exclude 属性が優先され
ます。"

具体的にどういうケースが「より効果的」になるのか思い当たりませんが、そう
いうこともできるということでご参考まで。
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -