ASP.NET MVC - ActionFilterAttribute para validar dados POST
-
05-07-2019 - |
Pergunta
Na verdade eu tenho um aplicativo que está usando um WebService para recuperar algumas informações clientes. Então, eu estava validar as informações de login dentro da minha ActionResult como:
[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");
}
}
Onde Client.Validate () é um método que retorna um booleano com base nas informações fornecidas no nome de usuário e senha POST
Mas eu mudei minha mente e eu gostaria de usar que ActionFilterAttributes agradáveis ??no início do método para que ele só vai ser processado se o Client.validate () retornar verdadeiro, da mesma forma como [autorizar], mas com meu costume webservice, então eu teria algo como:
[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')
}
e, em seguida, no interior do ValidateAsClient eu teria algo como:
public class ValidateAsClient : ActionFilterAttribute
{
public string username { get; set; }
public string password { get; set; }
public Boolean ValidateAsClient()
{
return Client.validate(username,password);
}
}
Então, meu problema é que eu não sei exatamente como fazê-lo funcionar, porque eu não sei como passar a informação enviada para as [ValidateAsClient (username = postedUsername, password = postedPassword)] e também, como eu poderia fazer o trabalho função ValidateAsClient corretamente?
Espero que isso é fácil de entender Agradecemos antecipadamente
Solução
Algo como isso provavelmente:
[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
}
}
E usá-lo como este:
[ValidateAsClient(HttpContext.Request.Form)]
Outras dicas
Você deve substituir o método a seguir.
public override void OnActionExecuting(ActionExecutingContext context)
E a partir do objeto de contexto, o acesso a seus dados de postagem.
Eu não acho que é uma boa idéia usar um ActionFilterAttribute
neste caso. E o que você quer fazer não é definitivamente o mesmo que atributo Authorize
faz.
O atributo Authorize
apenas injeta uma lógica comum em um controlador / ação. Que é:
redirecionar para a página de login, se o usuário não está logado. Else deixar a ação ser executada.
A sua acção ClientLogin
faz exatamente o que é suposto fazer no momento.
Seria uma má concepção para realizar essa lógica até uma ActionFilterAttribute
.
Gostaria de resolver este problema com uma pasta feita sob encomenda em ASP.NET MVC.
Suponha que a sua acção terá a seguinte assinatura.
public ActionResult MyAction(MyParameter param)
{
if(param.isValid)
return View("valid");
else
return View("invalid");
}
classe MyParam:
public class MyParameter
{
public string UserName{get;set;}
public string Password {get;set;}
public bool isValid
{
//check if password and username is valid.
}
}
Um em seguida, a pasta feita sob encomenda
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.
}
}