2015-10-01 5 views
-1

Я пытаюсь удалить пароль, записанный в параметрах, из моего фильтра действий и заменить его словом «Удалено», чтобы параметры сохранялись в базе данных для ведения журнала. Пароль хранится в ViewModel (в зависимости от действия). Ниже приводится своего рода «псевдокод» относительно того, чего я пытаюсь достичь.Заменить параметр в фильтре действия

Как мне скрыть маскировку/замену пароля для сохранения в базе данных? Основная проблема, с которой я сталкиваюсь, заключается в том, что я не знаю, как получить доступ к параметру пароля и изменить его. Я попытался получить его с помощью actionParams.TryGetValue("model, out value), но проблема в том, что я не знаю тип значения и он изменяется в зависимости от действия. Кроме того, я не могу назвать много методов на actionParams["model"] (например, содержит)

public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 

     var actionParam = filterContext.ActionParameters; 

     // Remove the password from the parameters 
     if (actionParam.ContainsKey("model") && actionParam["model"] != null) 
     {   
      // If actionParam["model"].ToLower().Contains("password") 
      // actionParam["model"]["password"] = "Removed"; 

      // If actionParam["model"].ToLower().Contains("confirm password") 
      // actionParam["model"]["confirm password"] = "Removed"; 
     } 

     string str = Json.Encode(filterContext.ActionParameters).Trim(); 

     string par = string.Empty; 

     if (str.Length > 2) 
     { 
      par = str.Substring(1, str.Length - 2).Replace("\"", string.Empty); 
     } 

     ActionLog log = new ActionLog() 
     { 
      SessionId = filterContext.HttpContext.Session.SessionID, 
      UserName = (request.IsAuthenticated) ? filterContext.HttpContext.User.Identity.Name : "Anonymous", 
      Controller = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName, 
      Action = filterContext.ActionDescriptor.ActionName, 
      ActionParameters = par, 
      IsPost = request.HttpMethod.ToLower() == "post" ? true : false, 
      IPAddress = request.ServerVariables["HTTP_X_FORWARDED_FOR"] ?? request.UserHostAddress, 
      UserAgent = request.UserAgent, 
      ActionDate = filterContext.HttpContext.Timestamp 
     }; 

     //Store the Audit into the Database 
     ActionLogContext context = new ActionLogContext(); 
     context.ActionLogs.Add(log); 
     context.SaveChanges(); 

     // Finishes executing the Action as normal 
     base.OnActionExecuting(filterContext); 

    } 

Пример возможных моделей зрения

public class LoginViewModel 
{ 

    [Required] 
    [Display(Name = "User ID")] 
    [RegularExpression("^[a-zA-Z0-9]+$", ErrorMessage="Letters and Numbers Only")] 
    public string UserName { get; set; } 

    [Required] 
    [DataType(DataType.Password)] 
    [Display(Name = "Password")] 
    public string Password { get; set; } 

} 
public class ResetPasswordViewModel 
{ 
    [Required] 
    [EmailAddress] 
    [Display(Name = "Email")] 
    public string Email { get; set; } 

    [Required] 
    [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)] 
    [DataType(DataType.Password)] 
    [Display(Name = "Password")] 
    public string Password { get; set; } 

    [DataType(DataType.Password)] 
    [Display(Name = "Confirm password")] 
    [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")] 
    public string ConfirmPassword { get; set; } 

    public string Code { get; set; } 
} 

Пример возможных действий параметров

 public async Task<ActionResult> Login(LoginViewModel model, string returnUrl) 
+0

Показать пример модели представления и само действие – haim770

+0

Это будет применяться ко всем действиям, поэтому модель представления и действия будут варьироваться –

+0

Как вы собираетесь выполнить вход, если вы удаляете пароль заранее? – haim770

ответ

1

Один из подходов - использовать интерфейс как абстракцию, чтобы вы не занимались d прямо с ViewModel. Во-первых, создайте некоторые интерфейсы для взаимодействия фильтра действий.

public interface IPassword 
{ 
    string Password { get; set; } 
} 

public interface IConfirmPassword 
{ 
    string ConfirmPassword { get; set; } 
} 

Далее, чтобы ваши классы ViewModel реализовали эти интерфейсы.

public class LoginViewModel : IPassword 
{ 

    [Required] 
    [Display(Name = "User ID")] 
    [RegularExpression("^[a-zA-Z0-9]+$", ErrorMessage = "Letters and Numbers Only")] 
    public string UserName { get; set; } 

    [Required] 
    [DataType(DataType.Password)] 
    [Display(Name = "Password")] 
    public string Password { get; set; } 

} 
public class ResetPasswordViewModel : IPassword, IConfirmPassword 
{ 
    [Required] 
    [EmailAddress] 
    [Display(Name = "Email")] 
    public string Email { get; set; } 

    [Required] 
    [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)] 
    [DataType(DataType.Password)] 
    [Display(Name = "Password")] 
    public string Password { get; set; } 

    [DataType(DataType.Password)] 
    [Display(Name = "Confirm password")] 
    [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")] 
    public string ConfirmPassword { get; set; } 

    public string Code { get; set; } 
} 

Тогда это вопрос обновления кода фильтра. Фильтр не должен знать ничего больше о вашей модели, кроме того, что он реализует IPassword или IConfirmPassword, которые он может проверить с помощью броска.

Конечно, для правильной работы вам необходимо восстановить исходные значения перед выполнением метода действия (или, альтернативно, выполнить регистрацию после запуска действия), чтобы метод действия имел правильные значения.

public override void OnActionExecuting(ActionExecutingContext filterContext) 
{ 
    var actionParam = filterContext.ActionParameters; 
    IPassword password = null; 
    IConfirmPassword confirmPassword = null; 

    string originalPassword; 
    string originalConfirmPassword; 

    // Remove the password from the parameters 
    if (actionParam.ContainsKey("model") && actionParam["model"] != null) 
    { 
     // If the model doesn't implement the interface, the result 
     // here will be null. 
     password = actionParam["model"] as IPassword; 
     confirmPassword = actionParam["model"] as IConfirmPassword; 
    } 

    if (password != null) 
    { 
     // Store the original value so it can be restored later 
     originalPassword = password.Password; 
     password.Password = "Removed"; 
    } 

    if (confirmPassword != null) 
    { 
     // Store the original value so it can be restored later 
     originalConfirmPassword = confirmPassword.ConfirmPassword; 
     confirmPassword.ConfirmPassword = "Removed"; 
    } 

    string str = Json.Encode(filterContext.ActionParameters).Trim(); 

    string par = string.Empty; 

    if (str.Length > 2) 
    { 
     par = str.Substring(1, str.Length - 2).Replace("\"", string.Empty); 
    } 

    ActionLog log = new ActionLog() 
    { 
     SessionId = filterContext.HttpContext.Session.SessionID, 
     UserName = (request.IsAuthenticated) ? filterContext.HttpContext.User.Identity.Name : "Anonymous", 
     Controller = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName, 
     Action = filterContext.ActionDescriptor.ActionName, 
     ActionParameters = par, 
     IsPost = request.HttpMethod.ToLower() == "post" ? true : false, 
     IPAddress = request.ServerVariables["HTTP_X_FORWARDED_FOR"] ?? request.UserHostAddress, 
     UserAgent = request.UserAgent, 
     ActionDate = filterContext.HttpContext.Timestamp 
    }; 

    //Store the Audit into the Database 
    ActionLogContext context = new ActionLogContext(); 
    context.ActionLogs.Add(log); 
    context.SaveChanges(); 

    // Restore the original values 
    if (password != null) 
    { 
     password.Password = originalPassword; 
    } 

    if (confirmPassword != null) 
    { 
     confirmPassword.ConfirmPassword = originalConfirmPassword; 
    } 

    // Finishes executing the Action as normal 
    base.OnActionExecuting(filterContext); 

} 
+0

Спасибо, что это работает красиво! Просто быстрый вопрос, вы были правы в том, что нужно восстановить исходный пароль, но как изменилось изменение пароля на «Удалено» в моей локальной переменной «actionParam», также изменяет пароль в 'filterContext.ActionParamaters'? –

+1

Поскольку классы являются ссылочными типами. Это означает, что когда вы назначаете один и тот же класс более чем одной переменной, они всегда указывают на то же место в памяти.Чтобы скопировать класс, вам придется сделать глубокий клон, что является дорогостоящей операцией, поэтому это, безусловно, лучший подход. – NightOwl888

Смежные вопросы