ホームページ  >  記事  >  バックエンド開発  >  ASP.NET MVCのバックグラウンドパラメータ検証のいくつかの方法

ASP.NET MVCのバックグラウンドパラメータ検証のいくつかの方法

高洛峰
高洛峰オリジナル
2016-12-24 13:27:071494ブラウズ

前書き

フロントエンドであってもバックエンドであっても、システム データの正確性を保証するためにユーザー入力を検証する必要があるのは一般的な問題です。 Web の場合、当然のことながらフロントエンドで検証したいと思う人もいるかもしれませんが、これは非常に間違ったアプローチです。フロントエンドのコードはユーザーに対して透過的であり、少しのテクノロジーを持っている人はこれを回避できます。確認してデータを直接バックステージに送信します。フロントエンド Web ページによって送信されるインターフェイスであっても、外部に提供されるインターフェイスであっても、パラメーターの検証はあらゆる場所で見られ、必須です。つまり、ユーザー入力はすべて信頼できません。

パラメータを検証する方法はたくさんありますが、一般的な検証方法をいくつか挙げるために mvc を例に挙げます。

[HttpPost]
public ActionResult Register(RegisterInfo info)

1. if-if

if(string.IsNullOrEmpty(info.UserName))
 
{
 
  return FailJson("用户名不能为空");
 
}
 
if(string.IsNullOrEmpty(info.Password))
 
{
 
  return FailJson("用户密码不能为空")
 
}

を使用して判断します。

パラメータを 1 つずつ検証します。この方法は最も粗雑ですが、当時 WebForm で実際に使用されていました。パラメータが少ないメソッドの場合は問題ありませんが、さらに多くのパラメータがある場合、さらに n 個の if-if を記述する必要があり、さらに重要なのは、この部分の判定を別のメソッドで再利用することはできません。

2. DataAnnotation を通じて

mvc は、アクション モデルを検証するための DataAnnotation を提供します。最終的に、DataAnnotation は RangeAttribute や RequiredAttribute などの一連の特性です。 ValidationAttribute の仮想メソッド IsValid は、マークされたオブジェクトが現在のルールに準拠しているかどうかを判断するために使用されます。 asp.net mvc はモデル バインディングを実行するときに、リフレクションを通じてマークされた ValidationAttribute を取得し、IsValid を呼び出して現在のパラメーターがルールに準拠しているかどうかを判断します。これが、検証が失敗した場合にエラー情報も収集される理由です。 ModelState.IsValid を使用してモデル検証が成功したかどうかを判断し、ModelState を使用して検証失敗の理由を取得します。例えば上記の例:

public class RegisterInfo
 
{
 
  [Required(ErrorMessage="用户名不能为空")]
 
  public string UserName{get;set;}
 
 [Required(ErrorMessage="密码不能为空")]
 
  public string Password { get; set; }
 
}

実はこの処理もmvcの実装原理を参考にすればwebform上でも実装可能です。このメソッドの利点は、実装が非常にエレガントで柔軟であることです。Model パラメーターを共有する複数のアクションがある場合、重要なのは、コードが非常に簡潔に見えることです。

ただし、この方法には欠点もあります。通常、プロジェクトには数十のインターフェイスなど、多くのインターフェイスがあり、インターフェイスごとにクラス パッケージング パラメーターを定義するのは少し贅沢です。実際、このクラスに名前を付けるのも非常に面倒です。

3. DataAnnotation はパラメータにもマークできます

検証機能の AttributeUsage を見ると、属性やフィールドだけでなくパラメータにもマークできることがわかります。つまり、次のように書くこともできます:

public ActionResult Register([Required(ErrorMessage="用户名不能为空")]string userName, [Required(ErrorMessage="密码不能为空")]string password)

このように書くこともOKですが、明らかに、このようにメソッドパラメータを記述すると、特に複数のパラメータがある場合、メソッドパラメータが見苦しくなります。複数の検証ルールがある場合。

4. ValidateAttribute をカスタマイズする

フィルターを使用して、mvc のアクションの実行前に認証や認可の処理などの処理を実行できることがわかりました。同様に、パラメータの検証にも使用できます。 FilterAttribute は、アクションの実行前と後にいくつかの操作を実行できるようにする一般的なフィルターです。ここで行う必要があるのは、アクションの前にパラメーターを検証することです。検証が失敗した場合、アクションは実行されなくなります。

次のように BaseValidateAttribute 基本クラスを定義します。

public class BaseValidateAttribute : FilterAttribute
 
{
 
  protected virtual void HandleError(ActionExecutingContext context)
 
  {
 
    for (int i = ValidateHandlerProviders.Handlers.Count; i > 0; i--)
 
    {
 
      ValidateHandlerProviders.Handlers[i - 1].Handle(context);
 
      if (context.Result != null)
 
      {
 
        break;
 
      }
 
    }
 
  }
 
}

HandleError は、検証が失敗した場合の結果を処理するために使用されます。ここで、ValidateHandlerProviders は、外部に登録できる結果を処理するための IValidateHandler について言及しています。 IValidateHandler は次のように定義されます。

public interface IValidateHandler
 
{
 
  void Handle(ActionExecutingContext context);
 
}

ValidateHandlerProviders は次のように定義され、デフォルトのプロセッサーがあります。

public class ValidateHandlerProviders
 
{
 
  public static List<IValidateHandler> Handlers { get; private set; }
 
  
 
  static ValidateHandlerProviders()
 
  {
 
    Handlers = new List<IValidateHandler>()
 
    {
 
      new DefaultValidateHandler()
 
    };
 
  }
 
  
 
  public static void Register(IValidateHandler handler)
 
  {
 
    Handlers.Add(handler);
 
  }
 
}  

この目的は、多くの特定の ValidateAttributes がある可能性があるため、このモジュールを分離し、最終処理を外部の決定に任せることができます。たとえば、プロジェクト Device:

public class StanderValidateHandler : IValidateHandler
 
{
 
  public void Handle(ActionExecutingContext filterContext)
 
  {
 
    filterContext.Result = new StanderJsonResult()
 
    {
 
      Result = FastStatnderResult.Fail("参数验证失败", 555)
 
    };
 
  }
 
}
で処理を定義できます。

次に、アプリケーションの起動時に登録します: ValidateHandlerProviders.Handlers.Add(new StanderValidateHandler());

ValidateRegexAttribute:

public class ValidateNullAttribute : BaseValidateAttribute, IActionFilter
 
{
 
  public bool ValidateEmpty { get; set; }
 
  
 
  public string Parameter { get; set; }
 
  
 
  public ValidateNullAttribute(string parameter, bool validateEmpty = false)
 
  {
 
    ValidateEmpty = validateEmpty;
 
    Parameter = parameter;
 
  }
 
  
 
  public void OnActionExecuting(ActionExecutingContext filterContext)
 
  {
 
    string[] validates = Parameter.Split(&#39;,&#39;);
 
    foreach (var p in validates)
 
    {
 
      string value = filterContext.HttpContext.Request[p];
 
      if(ValidateEmpty)
 
      {
 
        if (string.IsNullOrEmpty(value))
 
        {
 
          base.HandleError(filterContext);
 
        }
 
      }
 
      else
 
      {
 
        if (value == null)
 
        {
 
          base.HandleError(filterContext);
 
        }
 
      }
 
    }
 
  }
 
  
 
  public void OnActionExecuted(ActionExecutedContext filterContext)
 
  {
 
  
 
  }
 
}

同じ方法でさらに多くの検証を実装できます。

このようにして、上記の記述方法は次のようになります:

public class ValidateRegexAttribute : BaseValidateAttribute, IActionFilter
 
{
 
  private Regex _regex;
 
  
 
  public string Pattern { get; set; }
 
  
 
  public string Parameter { get; set; }
 
  
 
  public ValidateRegexAttribute(string parameter, string pattern)
 
  {
 
    _regex = new Regex(pattern);
 
    Parameter = parameter;
 
  }
 
  
 
  public void OnActionExecuting(ActionExecutingContext filterContext)
 
  {
 
    string[] validates = Parameter.Split(&#39;,&#39;);
 
    foreach (var p in validates)
 
    {
 
      string value = filterContext.HttpContext.Request[p];
 
      if (!_regex.IsMatch(value))
 
      {
 
        base.HandleError(filterContext);
 
      }
 
    }
 
  }
 
  public void OnActionExecuted(ActionExecutedContext filterContext)
 
  {
 
  }
 
}

全体的には問題ないようで、上記の DataAnnotation を評価して使用できます。ここで、エラーの説明など、より有用な情報を拡張できます。など待ってください。

まとめ

もちろん、各方法には欠点があります。この選択は特定の状況によって異なります。一般に、パラメータが多すぎる場合は、それらをオブジェクトでラップすることをお勧めします。

ASP.NET MVC バックグラウンド パラメーター検証のいくつかの方法に関するその他の関連記事については、PHP 中国語 Web サイトに注目してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。