2013-09-27 2 views
0

Итак, у меня есть приложение MVC4, и я использую систему регистрации и регистрации по умолчанию. На домашней странице я хочу перенаправить или изменить сообщение на основе роли пользователя. Вот что у меня есть в контроллере:Ссылка на объект не установлена ​​в экземпляр объекта. - Ролей не существует при запуске приложения

public ActionResult Index() 
    { 
     if (Roles.GetRolesForUser().Contains("Admin")) 
      ViewBag.Message = "Click on a link to get started."; 
     else if (Roles.GetRolesForUser().Contains("Authorized")) 
      ViewBag.Message = "Click on Organizations or Interfaces to get started."; 
     else if (Roles.GetRolesForUser().Contains("Unauthorized")) 
      ViewBag.Message = "An administrator must activate your account before you can use this tool."; 
     else 
      return RedirectToAction("Login", "Account"); 
     return View(); 
    } 

Обычно, это работает отлично, но если я перезапустить приложение, пока я вошел в систему, и после внесения изменений в код, то я получаю ошибку «Object ссылка не установлена ​​в экземпляр объекта. " И это указывает на роли, которые, по-видимому, еще не существуют.

После слишком большого поиска я нашел somebody with the same problem. Я попробовал предлагаемое решение там и заменил все экземпляры Roles.GetRolesForUser(). Содержит с HttpContext.User.IsInRole, но затем я получил эту ошибку: «Возникла связанная с сетью или конкретная конкретная ошибка при установлении соединения с SQL Сервер не найден или недоступен. Убедитесь, что имя экземпляра верное и что SQL Server настроен для разрешения удаленных подключений. (Поставщик: сетевые интерфейсы SQL, ошибка: 26 - Ошибка определения местоположения сервера/экземпляра) «

После того, как кучу больше искали, я нашел this, в котором указывал here, в котором говорится, что ни одна из моих попыток не будет работать, потому что мне сначала нужно перенаправить. Хотя, по-видимому, он говорит о чем-то другом, но выглядит очень похоже.

Я попытался переименовать Index в Index2, который перенаправлен на Index3, содержащий тот же код, и я получил ту же ошибку. Я попробовал кликабельные ссылки, чтобы получить от Index to Index2 до Index3, ту же ошибку. Я попытался сделать вывод, поместив WebSecurity.Logout(); прямо перед строкой кода, которая вызывает ошибку, и я получаю другую ошибку: «Вы должны вызвать метод« WebSecurity.InitializeDatabaseConnection », прежде чем вы вызовете какой-либо другой метод класса« WebSecurity ». Этот вызов должен быть помещен в _AppStart .cshtml в корневом каталоге вашего сайта. " Но встроенный метод выхода из системы не кажется, что называет, он получил другую вещь происходит:

@using (Html.BeginForm("LogOff", "Account", FormMethod.Post, new { id = "logoutForm" })) { 
     @Html.AntiForgeryToken() 
     <a href="javascript:document.getElementById('logoutForm').submit()">Log off</a> 
    } 

, при нажатии, немедленно вызывает WebSecurity.Logout();

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

Чтобы обойти это, сначала я прокомментировал весь проблемный код, перезапустив его, щелкнув при выходе из системы, затем раскомментировав и перезапустив. Затем я понял, что удаление файла cookie в моем браузере исправляет его. Я все еще не хочу делать это каждый раз. Если я не смогу найти решение, я просто вынужу пользователя нажать ссылку для выхода из системы, которая приведет их на страницу входа.

ответ

1

Ok, наконец-то разобрался.Ответ Ромоку был полезен, но у меня пока нет достаточной репутации, чтобы его проголосовать :(

Блок try/catch работает, но он все еще зависает некоторое время, пока он пытается подключиться, а затем он попадает в блок HttpException с сообщением «Невозможно подключиться к базе данных SQL Server». Затем он перейдет на страницу «Вход», но мне странно, что на странице входа в систему он может определить, кто вошел в систему, и даже лучше, у меня есть схожая код в файле _Layout.cshtml [@if (Roles.GetRolesForUser(). Содержит («Admin»))], чтобы фильтровать параметры меню, и он правильно запускает их на странице входа в систему. Это действительно странно, потому что я уже пробовал перенаправляя на Index2 и Index3 раньше, не повезло. Поэтому я решил, что мне просто нужно перенаправить на другой контроллер, и я добавил контроллер «Тестер», без кубиков.

Оказывается, класс AccountController имеет над ним атрибут [InitializeSimpleMembership], и все, что мне нужно сделать, чтобы заставить исходный код работать как предполагалось, добавить это выше класса HomeController, а также инструкцию «using MyProject.Filters;».

Еще смешнее, что я искал решение для «WebSecurity.InitializeDatabaseConnection» всякий раз, когда я получил соответствующую ошибку раньше, нашел инструкцию в «SimpleMembershipInitializer()» в папке «Фильтры», а затем выполнил поиск решения для «SimpleMembershipInitializer» и не нашел других хитов. Кто знал, что он был скрыт в атрибуте [InitializeSimpleMembership].

1

код может вызывать NullReferenceException, так как вы не проверяете результат Roles.GetRolesForUser.

Try:

string[] roles; 

try 
{ 
    roles = Roles.GetRolesForUser(); 
} 
catch(HttpException) 
{ 
    return RedirectToAction("Login", "Account"); 
} 

if(roles == null) return RedirectToAction("Login", "Account"); 

if(roles.Contains("Admin") 
{ 
    ViewBag.Message = "Click on a link to get started."; 
} 
else if (roles.Contains("Authorized")) 
{ 
    ViewBag.Message = "Click on Organizations or Interfaces to get started."; 
} 
else if (roles.Contains("Unauthorized")) 
{ 
    ViewBag.Message = "An administrator must activate your account before you can use this tool."; 
} 
else 
{ 
    return RedirectToAction("Login", "Account"); 
} 

return View(); 

Если вы используете Roles.IsUserInRole, то код может быть упрощена:

try 
{ 
    if(Roles.IsUserInRole("Admin")) 
    { 
     ViewBag.Message = "Click on a link to get started."; 
    } 
    else if(Roles.IsUserInRole("Authorized")) 
    { 
     ViewBag.Message = "Click on Organizations or Interfaces to get started."; 
    } 
    else if (Roles.IsUserInRole("Unauthorized")) 
    { 
     ViewBag.Message = "An administrator must activate your account before you can use this tool."; 
    } 
    else 
    { 
     return RedirectToAction("Login", "Account"); 
    } 
} 
catch(ArgumentNullException) 
{ 
    // No user is currently logged in 
    return RedirectToAction("Login", "Account"); 
} 
catch(HttpException) 
{ 
    // There is no current logged on user. Role membership cannot be verified. 
    return RedirectToAction("Login", "Account"); 
} 

return View(); 
+0

Это определенно помогло и поставило меня на правильный путь к полному решению. Благодаря! – Zook

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

  • Нет связанных вопросов^_^