PDA

View Full Version : اعمال AOP برای لاگ فعالیت های کاربران



7asemoon
سه شنبه 02 شهریور 1395, 11:41 صبح
من میخام با استفاده از فیلترهای سفارشی mvc فعالیت های کاربر رو لاگ کنم به این صورت که بر روی هر اکشنی که میخام به این صورت اعمال کنم


[Activity(Description = "ورود به حساب کاربری",LogType = AuditLogType.Login)]
{}public virtual async Task<ActionResult> Login(LoginViewModel model, string returnUrl)

و فیلتر رو هم به این صورت قرار دادم


/// <summary>
/// به منظور اعمال
/// AOP
/// برای لاگ فعالیت های کاربران
/// </summary>
[AttributeUsage(AttributeTargets.Method)]
public class ActivityAttribute : ActionFilterAttribute
{
#region Properties
public Type LoggableType { get; set; }
public string Property { get; set; }
public string Description { get; set; }
public AuditLogType LogType { get; set; }
public IActivityLogService ActivityLogService { get; set; }
#endregion

#region OnActionExecuting
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (LogType == AuditLogType.JustDescription)
{
var propertyValue = string.Empty;
if (Property.HasValue())
{
var parameters = filterContext.ActionDescriptor.GetParameters();
var parameterToAudit = parameters.SingleOrDefault(p => p.ParameterType == LoggableType);
if (parameterToAudit != null)
{
var argumentToAudit = filterContext.ActionParameters[parameterToAudit.ParameterName];
var propertyInfo = parameterToAudit.ParameterType.GetProperties()
.First(p => Property == p.Name);

var pi = argumentToAudit.GetType().GetProperty(propertyInfo .Name);
propertyValue = pi.GetValue(argumentToAudit, null).ToString();
}
}

ActivityLogService.Create(Description, propertyValue);

}

base.OnActionExecuting(filterContext);
}

#endregion

#region OnActionExecuted
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
if (LogType == AuditLogType.Login)
{
ActivityLogService.Create(Description, LogType);
}
if (LogType != AuditLogType.Serialize) return;
if (filterContext.Controller.ViewData.ModelState.IsVa lid)
{
ActivityLogService.Create(Description, LogType);
}

base.OnActionExecuted(filterContext);
}
#endregion

}

اما از متد create ایراد میگیره
142133

7asemoon
سه شنبه 02 شهریور 1395, 11:43 صبح
اینترفیس مربوط به IActivityLogService


public interface IActivityLogService
{
void Create(ActivityLog log);
IList<LastActivityViewModel> GetLastActivities();
}

و کلاس مربوطه


public class ActivityLogService : IActivityLogService
{
#region Fields
private readonly IMappingEngine _mappingEngine;
private readonly IUnitOfWork _unitOfWork;
private readonly IApplicationUserManager _userManager;
private readonly IDbSet<ActivityLog> _logs;
#endregion

#region Ctor
public ActivityLogService(IUnitOfWork unitOfWork, IApplicationUserManager userManager, IMappingEngine mappingEngine)
{
_userManager = userManager;
_unitOfWork = unitOfWork;
_logs = _unitOfWork.Set<ActivityLog>();
_mappingEngine = mappingEngine;
}
#endregion

#region Create
public void Create(ActivityLog log)
{
_logs.Add(log);
}
#endregion

public IList<LastActivityViewModel> GetLastActivities()
{
throw new NotImplementedException();
}

}

hakim22
سه شنبه 02 شهریور 1395, 15:36 عصر
شما در اینترفیس متد رو به این صورت تعریف کردید :

void Create(ActivityLog log);




که یک پارامتر ورودی میگیره. در حالی که موقع استفاده دو مقدار به متد میدید :


ActivityLogService.Create(Description, LogType);



شما باید یک کلاس از ActivityLog بسازید و پارامترهاشو درون اون پر کنید و سپس به متد create پاس بدید.