2015-05-27 3 views
1

Я обнаружил, что у меня много повторяющихся кодов во всех моих действиях и хочу знать, как лучше всего это избежать. Скажем, например, что каждый зарегистрированный пользователь принадлежит школе, и мне нужно получить доступ к этому учебнику почти в каждом действии.MVC 5 глобальная переменная на пользователя

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

public ActionResult Index() 
{ 
var schoolId = userService.GetSchoolId(User.Identity.GetUserId()); 
var textBooksForSchool = textBookService.GetBooks(schoolId); 
... 
} 

public ActionResult Delete() 
{ 
var schoolId = userService.GetSchoolId(User.Identity.GetUserId());//all over the place 
var textBooksForSchool = textBookService.DeleteBooks(schoolId); 
... 
} 

Я знаю, что я могу добавить SchoolId к претензиям но синтаксис для возвращения его в каждый метод является довольно громоздким (насколько я понимаю, это позволяет избежать дб удар каждый раз, когда претензия доступ?):

в GenerateIdentityAsync:

var claims = new Collection<Claim> 
     {   
     new Claim("SchoolId", User.SchoolId.ToString()) 
     }; 

     userIdentity.AddClaims(claims);   

в действии:

var SchoolId = Convert.ToInt32((User as ClaimsPrincipal).Claims.First(x => x.Type == "SchoolId").Value); 

Есть ли какой-то лучшей практики здесь? Возможно сохранение заявки в глобальной переменной при входе в систему?

+1

Вы можете переместить многословный код метода расширения. – SLaks

ответ

1

Это, как я делаю ...

Базового контроллера

public class BaseController : Controller 
{ 
    public AppUser CurrentUser 
    { 
     get 
     { 
      return new AppUser(this.User as ClaimsPrincipal); 
     } 
    } 
} 

Иска Основной

public class AppUser : ClaimsPrincipal 
{ 
    public AppUser(ClaimsPrincipal principal) 
     : base(principal) 
    { 
    } 

    public string Name 
    { 
     get 
     { 
      return this.FindFirst(ClaimTypes.Name).Value; 
     } 
    } 

    public string Email 
    { 
     get 
     { 
      return this.FindFirst(ClaimTypes.Email).Value; 
     } 
    } 
} 

В другом контроллере вы можете получить доступ к типу претензии только, делая

CurrentUser.Email 
1

Как создать собственный базовый контроллер, который все ваши контроллеры наследуют от этого, имеет SchoolId как свойство, а затем создает ActionFilter, который бросает каждый контроллер в качестве этого базового контроллера и устанавливает это значение для каждого запроса? Затем он будет доступен для всех ваших действий, но вам нужно будет только один раз написать код.

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

0

Мне очень нравится метод расширения подхода:

public static int SchoolId(this IPrincipal principal) 
     { 
      return Convert.ToInt32((principal as ClaimsPrincipal).Claims.First(x => x.Type == "SchoolId").Value); 
     } 

Действие:

var textBooksForSchool = textBookService.GetBooks(User.SchoolId()); 
Смежные вопросы