2013-09-18 3 views
1

Я планирую создать фильтр на основе ActionFilterAttribute для входа пользователя деятельности:Лог действий пользователя в приложении ASP.NET MVC

public class LogAttribute : ActionFilterAttribute 
{ 
    public ActionType Type { get; set; } 

    public override void OnResultExecuted(ResultExecutedContext filterContext) 
    { 
     // logic for log 
    } 
} 

Я хотел бы использовать этот атрибут на действия в своих контроллерах. Я хотел бы зарегистрировать некоторые значения X,Y,Z, которые пользователь задает в моих представлениях, а также информацию о некоторых действиях. В этом случае я должен, вероятно, отправить эти X, Y, Z моим действиям в качестве параметров, а затем в код атрибута получить эти значения из ResultExecutedContext. Но этот подход немного смутил меня, потому что у меня будут избыточные параметры для каждого из моих действий.

Есть ли хороший подход для обмена значениями из вида в код C#?

ответ

0

Значения должны быть установлены в какой-то момент, как пользователем, так и кодом. Однако вы можете использовать массив Session, чтобы содержать эти значения. Они будут сохранены на время сеанса входа в систему.

Чтобы сохранить в сессии

Session["key"] = "data"; 

, а затем в коде

var val = Session["key"]; // val now has a value of "data"; 
+0

Я думаю, что использование сессий в м vc - плохая идея – Polaris

+0

@Polaris Это новость для меня - http://stackoverflow.com/questions/6744493/still-ok-to-use-session-variables-in-asp-net-mvc-or-is-there -a-better-alternati - Любая конкретная причина, по которой вы считаете, что это плохой вариант? – Kami

0

что я использую это вспомогательный метод, который используют отражение и выводит модель в словарь, таким образом Вы не делаете есть вопрос, чтобы скопировать ценности в другом месте, все отправляется из одного места «ваша модель»

private static Dictionary<string, string> DumpModel(object obt) 
     { 
      Type type = obt.GetType(); 
      if (TypeDefinitionIsList(type)) 
       return null; 

      PropertyInfo[] properties = obt.GetType().GetProperties(); 
      Func<PropertyInfo, string> func = info => 
                { 
                 if (info.PropertyType.GetInterface(typeof (ICatalogue<>).FullName) != null) 
                 { 
                  dynamic propertyValue = info.GetValue(obt, null); 
                  if (propertyValue != null) 
                   return string.Format("{{ Id: {0}, Description: {1} }}", 
                        propertyValue.Id, 
                        propertyValue.Description); 
                  return "null"; 
                 } 
                 object normalValue = info.GetValue(obt, null); 
                 if (normalValue == null) return "null"; 
                 return TypeDefinitionIsList(normalValue.GetType()) ? HelpersMessages.NotSupportedList : normalValue.ToString(); 
                }; 

      return properties.ToDictionary(x => "model-"+x.Name, func); 
     } 

Вы можете использовать его в атрибут фильтра

var request = filterContext.HttpContext.Request; 
object model = filterContext.Controller.ViewData.Model; 

и вы можете использовать что-то вроде

DumpModel(model);  

использовать значения для входа wharever вам нужно, Я надеюсь, что это помогает

0

Я могу добиться этого следующим образом:

Создать таблицу (название - Portal_Logger и D_EMP_MASTER), как показано ниже

Portal_Logger

enter image description here

D_EMP_MASTER

enter image description here

Далее, создан фильтр, который будет отслеживать активность для пользователей/с, как показано ниже

LoggerActionFilter.cs

using System; 
using System.Web.Mvc; 
using System.Net; 
using System.Linq; 
using System.Net.Sockets; 
using MyMvcApplication.Models.Entity; 
using MyMvcApplication.Utilities; 

namespace MyMvcApplication.Filters 
{ 
    /// <summary> 
    /// 
    /// </summary> 
    public class LoggerActionFilter : ActionFilterAttribute 
    { 
     private static TimeZoneInfo INDIAN_ZONE = TimeZoneInfo.FindSystemTimeZoneById("India Standard Time"); 
     IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName()); 
     public override void OnActionExecuting(ActionExecutingContext filterContext) 
     { 
      // Stores the Request in an Accessible object 
      var request = filterContext.HttpContext.Request; 
      var visitCount = Convert.ToInt64(filterContext.HttpContext.Session["LoggerActivityTracking"].ToString()); 
      // Generate an audit 
      Portal_Logger aLogger = new Portal_Logger() 
      { 
       // Your Logger Identifier  
       LoggerId = Guid.NewGuid(), 
       //Logged On User Id 
       LogedUserId = Convert.ToInt32(filterContext.HttpContext.Session["LogedUserID"]), 
       // The IP Address of the Request 
       IPAddress = Convert.ToString(ipHostInfo.AddressList.FirstOrDefault(address => address.AddressFamily == AddressFamily.InterNetwork)), 
       //Get the Web Page name(from the URL that was accessed) 
       AreaAccessed = UserActivityUtility.GetWebPageName(request.RawUrl == "/"? "/Home/UserLandingPage" : request.RawUrl), 
       // Creates our Timestamp 
       Timestamp = TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, INDIAN_ZONE), 
       VisitorSessionId = visitCount 
      }; 

      // Stores the Logger in the Database 
      using (IOTAssetEntities context = new IOTAssetEntities()) 
      { 
       if (aLogger.LogedUserId != null) 
       { 
        aLogger.LogedUserEmpId = context.D_EMP_MASTER 
         .Where(x => x.User_Id == aLogger.LogedUserId) 
         .Select(x => x.Emp_Id).FirstOrDefault(); 
        aLogger.LogedUserEmpName = context.D_EMP_MASTER 
         .Where(x => x.User_Id == aLogger.LogedUserId) 
         .Select(x => x.Emp_Name).FirstOrDefault(); 
        aLogger.AccessedType = aLogger.AreaAccessed.Contains("Report") ? "Report" : "Page"; 
       } 
       context.Portal_Logger.Add(aLogger); 
       context.SaveChanges(); 
      } 
      // Finishes executing the Logger as normal 
      base.OnActionExecuting(filterContext); 
     } 

    } 
} 

Примечание: Session["LoggerActivityTracking"] и Session["LogedUserID"] данные я инициализацию в отдельном контроллере (AuthenticationController) Действие (ValidateUser), которая выполняется при входе пользователя в приложение.

Ниже я использую класс Utility, который получит точное название веб-страницы из RawUrl (например: /Home/MyController или /Home/MyController1?id=1&name=chandan)

Ниже моя утилита класса

UserActivityUtility.cs

using System;  
namespace MyMvcApplication.Utilities 
{ 
    public static class UserActivityUtility 
    { 
     /// <summary> 
     /// 
     /// </summary> 
     /// <param name="pageName"></param> 
     /// <returns></returns> 
     public static string GetWebPageName(string pageName) 
     { 
      string formattedPageName = string.Empty; 
      //For All user web pages 
      if (pageName.Contains("UserLandingPage")) 
      { 
       formattedPageName = "Home - App Management"; 
      }    
      //For Report Web Pages 
      else if (pageName.Contains("AppUtilization")) 
      { 
       formattedPageName = "Applocation Utilization Report"; 
      }   
      else if (pageName.Contains("AlertReport")) 
      { 
       formattedPageName = "Alert Report"; 
      }    
      else if (pageName.Contains("DetailedReport")) 
      { 
       formattedPageName = "Detailed Report"; 
      }    
      //For Admin Web Pages    
      else if (pageName.Contains("CreateUser")) 
      { 
       formattedPageName = "Admin - Create User"; 
      }   
      else if (pageName.Contains("UpdateUserDetails")) 
      { 
       formattedPageName = "Admin - Update User Details"; 
      } 
      else if (pageName.Contains("EditUser")) 
      { 
       formattedPageName = "Admin - Edit User"; 
      }   
      else 
      { 
       formattedPageName = pageName; 
      } 
      return formattedPageName; 
     } 
    } 
} 

И, наконец, применить этот атрибут к контроллеру Action/s (какие действия вы хотите отслеживать), как показано ниже

[AuthenticationFilter(Order = 1)] 
public class HomeController : Controller 
{ 
    [LoggerActionFilter(Order = 2)] 
    public ActionResult UserLandingPage() 
    { 
     return View(); 
    } 
} 

[AuthenticationFilter(Order = 1)] 
public class AdminController : Controller 
{ 
    [LoggerActionFilter(Order = 2)] 
    public ActionResult CreateUser() 
    { 
     return View(); 
    } 
} 

[AuthenticationFilter(Order = 1)] 
public class ReportController : Controller 
{ 
    [LoggerActionFilter(Order = 2)] 
    public ActionResult AppUtilization() 
    { 
     return View(); 
    } 
} 

И ниже является "MS SQL StoredProcedure", чтобы получить подробную информацию пользователя для входа и страниц мудрого доступа итоговых

Входа пользователя Детали

SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 

CREATE Procedure [dbo].[sp_Portal_GetUserLoginDetails_Logger] 
(
@FromDate DATE, 
@ToDate DATE 
) 
AS 
BEGIN 
     --EXEC sp_Portal_GetUserLoginDetails_Logger '2017-06-16','2017-06-16' 
     SET NOCOUNT ON 

     SELECT u.LogedUserID,u.UserName,u.IPAddress,u.AreaAccessed,u.[Timestamp],u.LastLoggedInDay 
     FROM 
     (
       SELECT DISTINCT l.LogedUserID,e.Emp_Name as 'UserName',l.IPAddress,l.AreaAccessed,l.[Timestamp],l.LastLoggedInDay 
       FROM 
       (
         SELECT * 
         FROM 
         (
          SELECT Row_Number() Over (PARTITION BY LogedUserID ORDER BY [Timestamp] DESC) As RowNum, LogedUserID, 

            IPAddress,AreaAccessed,TIMESTAMP, DATEDIFF(D,TIMESTAMP,CURRENT_TIMESTAMP) AS 'LastLoggedInDay' 
          FROM Portal_Logger 
          WHERE CAST([Timestamp] AS DATE) BETWEEN @FromDate AND @ToDate 
         ) t2 
        WHERE RowNum = 1 
       ) l 
       JOIN D_EMP_MASTER e on l.LogedUserID = e.User_Id     
     ) u  
     ORDER BY u.[Timestamp] DESC  
END 

Page Wise Access итоговых

SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
CREATE PROCEDURE [dbo].[sp_Portal_GetUserAccessedSummary_Logger] 
(
@FromDate DATE, 
@ToDate DATE 
) 
AS 
BEGIN  
     --EXEC sp_Portal_GetUserAccessedSummary_Logger '2017-06-16','2017-06-16' 

     SET NOCOUNT ON  
      SELECT A.AreaAccessed, 
        COUNT(A.Timestamp) AS NoofTimeAccessed, 
        CONVERT(TIME(0), DATEADD(SECOND,SUM(SessionSeconds), 0)) AS TotalTimeSpent, 
        CONVERT(TIME(0), DATEADD(SECOND,AVG(SessionSeconds), 0)) AS AvgTimeSpent, 
        COUNT(DISTINCT LogedUserID) AS NoofUserAccessed 

      FROM 
      (
       SELECT 
         A.AreaAccessed,A.Timestamp, 
         ISNULL(DATEDIFF(S,A.Timestamp,ISNULL(LEAD(A.Timestamp,1)OVER(PARTITION BY A.VisitorSessionId ORDER BY A.Timestamp),A.Timestamp)),0) AS SessionSeconds, 
         A.LogedUserID 

       FROM Portal_Logger A(NOLOCK) 
       JOIN D_EMP_MASTER B(NOLOCK) ON A.LogedUserID=B.User_Id 
       WHERE A.VisitorSessionId IS NOT NULL 
       AND  CAST(A.Timestamp AS DATE) BETWEEN @FromDate AND @ToDate 

      )A 
      GROUP BY A.AreaAccessed 
      ORDER BY NoofTimeAccessed DESC  
     SET NOCOUNT OFF 
END 
Смежные вопросы