2009-02-26 4 views
1

Справочная информация:LINQ аудит и текущий пользователь с веб-приложением

У меня есть веб-приложение, для которого мне нужно сделать аудит базы данных для вставки/удаления/обновления (и, возможно, читает). Я использую LINQ как свой ORM. Используя некоторые идеи, которые я нашел в Интернете, я придумал способ использования атрибутов для украшения моих объектов, имеющих связанные таблицы аудита. Сама таблица аудита должна включать те же колонки с теми же типами, что и исходная таблица, в дополнение к полям для идентификатора и имени текущего пользователя, типу модификации, времени модификации и успешной операции. Аудит происходит во время SubmitChanges - мой контекст данных является абстрактным, и я наследую и переопределяю SubmitChanges в моей конкретной реализации. Контекст абстрактных данных на самом деле происходит из AbstractAuditableDataContext, который расширяет DataContext и добавляет свойство CurrentUser с заполнителями для текущего идентификатора пользователя и имени. По умолчанию это 0 и «система» для экземпляров, в которых нет зарегистрированного пользователя - скажем, во время регистрации или входа в систему, когда могут быть обновлены некоторые поля таблицы пользователя. Приложение написано на C# с использованием ASP.NET MVC.

Проблема:

Какой самый лучший способ для заполнения текущего свойства пользователя моего полученного контекста данных? Должен ли я создать класс утилиты, который вводится в AuditUtility, который проверяет, был ли установлен CurrentUser и, если нет, заполняет его. Для тестирования я бы издевался над этим, но в реальном приложении он, вероятно, использовал бы ленивый -гружать и получать/устанавливать его в сеансе. Или я должен изменить фабрику контекста данных (используемую всеми контроллерами) для выполнения этой функции. Я уже использую макет фабрики во время модульного тестирования, поэтому это не будет связано с созданием новых классов. Или должен быть сделан вывод за пределами фабрики и текущего пользователя, введенного во время создания контекста. Это позволило бы мне сделать «от имени» аудита.

Я понимаю, что это несколько субъективно, но я был бы признателен за любые мысли/впечатления, которые вы могли бы внести.

Спасибо.

ответ

0

В результате я создал класс CurrentUserUtilityBase, который использует метод GetAuditUser, который принимает текущий контекст данных и извлекает объект пользователя, соответствующий текущему имени пользователя в HttpContext.User.Identity. Он использует этот объект для извлечения идентификатора и отображения имени текущего пользователя и создания и возврата объекта AuditUser, содержащего эти свойства.

Мой класс реализации использует фабрику для получения экземпляра моего контекста данных и вызывает метод базового класса в этом контексте данных. Методы фабрики для моего контекста данных используют текущую пользовательскую утилиту для ввода текущего пользователя контекста в контекст после его создания.

0

Какова область действия вашего DataContext (Application, Session, Request, for BusinessObject ..)? Если он отличается, вы можете не захотеть кэшировать текущего пользователя в DataContext вообще (или установить его во время создания). Я бы, вероятно, использовал свойство в DataContext, которое извлекало текущего пользователя из сеанса (так или иначе) всякий раз, когда это необходимо.

+0

Область контекста данных для каждого действия - это довольно недолго. – tvanfosson

1

Если вы используете Windows или Forms auth, вы можете проверить HttpContext, не передавая ничего. Если вы не находитесь в веб-контексте, хватайте пользователя из потока. Может быть:

if(HttpContext.Current != null) 
{ 
    //grab the user from the HttpContext 
} 
else 
{ 
    //grab the user from the Thread 
} 
+0

Но где бы вы поместили этот код?При создании контекста данных или при каждом вызове утилиты? – tvanfosson

+0

Путь наименьшего сопротивления может быть добавлен в вашу реализацию SubmitChanges(). Это устраняет необходимость передавать что-либо, и ваши потребители DataContext остаются приятно не знакомыми с деталями. –

1

System.Threading.Thread.CurrentPrincipal должен дать вам ответ, который вы ищете.