ASP.NET MVC-POSTデータを検証するActionFilterAttribute
-
05-07-2019 - |
質問
実際には、WebServiceを使用して一部のクライアント情報を取得するアプリケーションがあります。 だから私は私のようなActionResult内のログイン情報を検証していました:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult ClientLogin(FormCollection collection)
{
if(Client.validate(collection["username"], collection["password"]))
{
Session["username"] = collection["username"];
Session["password"] = collection["password"];
return View("valid");
}
else
{
Session["username"] = "";
Session["password"] = "";
return View("invalid");
}
}
Client.Validate()は、POSTユーザー名とパスワードで提供される情報に基づいてブール値を返すメソッドです
しかし、気が変わったので、メソッドの最初にその素晴らしいActionFilterAttributesを使用して、Client.validate()がtrueを返す場合にレンダリングされるようにします。[Authorize]と同じですが、カスタムWebサービスなので、次のようになります。
[AcceptVerbs(HttpVerbs.Post)]
[ValidateAsClient(username=postedUsername,password=postedPassword)]
//Pass Posted username and password to ValidateAsClient Class
//If returns true render the view
public ActionResult ClientLogin()
{
return View('valid')
}
そしてValidateAsClient内に次のようなものがあります:
public class ValidateAsClient : ActionFilterAttribute
{
public string username { get; set; }
public string password { get; set; }
public Boolean ValidateAsClient()
{
return Client.validate(username,password);
}
}
つまり、私の問題は、POSTED情報を [ValidateAsClient(username = postedUsername、password = postedPassword)]に渡す方法がわからないためです。 / b>また、ValidateAsClient関数を適切に機能させるにはどうすればよいですか
これが理解しやすいことを願っています よろしくお願いします
解決
おそらく次のようなもの:
[AttributeUsage(AttributeTargets.All)]
public sealed class ValidateAsClientAttribute : ActionFilterAttribute
{
private readonly NameValueCollection formData;
public NameValueCollection FormData{ get { return formData; } }
public ValidateAsClientAttribute (NameValueCollection formData)
{
this.formData = formData;
}
public override void OnActionExecuting
(ActionExecutingContext filterContext)
{
string username = formData["username"];
if (string.IsNullOrEmpty(username))
{
filterContext.Controller.ViewData.ModelState.AddModelError("username");
}
// you get the idea
}
}
次のように使用します:
[ValidateAsClient(HttpContext.Request.Form)]
他のヒント
次のメソッドをオーバーライドする必要があります。
public override void OnActionExecuting(ActionExecutingContext context)
そしてコンテキストオブジェクトから、投稿データにアクセスします。
この場合、 ActionFilterAttribute
を使用することはお勧めできません。そして、あなたがやりたいことは、 Authorize
属性とは間違いなく同じです。
Authorize
属性は、一般的なロジックをコントローラー/アクションに挿入するだけです。どちらですか:
ユーザーがログインしていない場合は、ログインページにリダイレクトします。それ以外の場合は、アクションを実行します。
ClientLogin
アクションは、現時点で想定されていることを実行します。
そのロジックを ActionFilterAttribute
に引き継ぐのは悪い設計です。
ASP.NET MVCのカスタムバインダーでこの問題を解決します。
アクションに次の署名があるとします。
public ActionResult MyAction(MyParameter param)
{
if(param.isValid)
return View("valid");
else
return View("invalid");
}
MyParamクラス:
public class MyParameter
{
public string UserName{get;set;}
public string Password {get;set;}
public bool isValid
{
//check if password and username is valid.
}
}
カスタムバインダー
public class CustomBinder:IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var p = new MyParam();
// extract necessary data from the bindingcontext like
p.UserName = bindingContext.ValueProvider["username"] != null
? bindingContext.ValueProvider["username"].AttemptedValue
: "";
//initialize other attributes.
}
}