Pregunta

En realidad tengo una aplicación que usa un servicio web para recuperar información de algunos clientes. Así que estaba validando la información de inicio de sesión dentro de mi 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");
    }
}

Donde Client.Validate () es un método que devuelve un valor lógico basado en la información proporcionada en el nombre de usuario y la contraseña de la POST

Pero cambié de opinión y me gustaría usar ese bonito ActionFilterAttributes al principio del método, por lo que solo se procesará si Client.validate () devuelve true, de la misma forma que [Authorize] pero con mi costumbre servicio web, por lo que tendría 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')
}

y luego dentro del ValidateAsClient tendría algo como:

public class ValidateAsClient : ActionFilterAttribute
{
    public string username { get; set; }
    public string password { get; set; }

    public Boolean ValidateAsClient()
    {
        return Client.validate(username,password);
    }
}

Mi problema es que no sé exactamente cómo hacerlo funcionar, porque no sé cómo pasar la información PUBLICADA a [ValidateAsClient (username = postedUsername, password = postedPassword)] y también, ¿cómo podría hacer que la función ValidateAsClient funcione correctamente?

Espero que esto sea fácil de entender Gracias de antemano

¿Fue útil?

Solución

Algo como esto probablemente:

[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
    }
}

Y úsalo así:

[ValidateAsClient(HttpContext.Request.Form)]

Otros consejos

Debes anular el siguiente método.

public override void OnActionExecuting(ActionExecutingContext context)

Y desde el objeto de contexto, accede a tus datos de publicación.

No creo que sea una buena idea usar un ActionFilterAttribute en este caso. Y lo que quiere hacer definitivamente no es lo mismo que el atributo Autorizar .

El atributo Authorize simplemente inyecta una lógica común en un controlador / acción. Que es:

  

Redirigir a la página de inicio de sesión, si el usuario no ha iniciado sesión. De lo contrario, deje que la acción se ejecute.

Su acción ClientLogin hace exactamente lo que se supone que debe hacer en este momento.
Sería un mal diseño llevar esa lógica a un ActionFilterAttribute .

Resolvería este problema con un archivador personalizado en ASP.NET MVC.

Supongamos que su acción tendrá la siguiente firma.

public ActionResult MyAction(MyParameter param)
{
  if(param.isValid)
    return View("valid");
  else
    return View("invalid");
}

Clase MyParam:

    public class MyParameter
    {
      public string UserName{get;set;}
      public string Password {get;set;}

      public bool isValid
      {
        //check if password and username is valid.
      }

}

Una carpeta entonces personalizada

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.
        }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top