none
Использование InitializeSimpleMembershipAttribute в ASP.NET MVC4 RRS feed

  • Вопрос

  • Доброе время суток.

    Хочу выяснить для себя как лучше всего поступить, если используется DataBase-First.

    При создании ASP.NET MVC4 приложения создается атрибут InitializeSimpleMembershipAttribute, который навешивается на AccountController. Естественно в таком виде оставлять нельзя, так как другие контроллеры тоже хотят иметь доступ к БД, и добавлять для каждого контроллера отдельно (или создать базовый) - не видел чтоб такое практиковалось, тем более это создаст дополнительные заботы. 

    Одни источники рекомендуют сменить тип атрибута на AutorizeAttribute (что мне в принципе не подходит), другие - перенести SimpleMembershipInitializer в Global.asax (что я у себя и сделал), третие - в  _ViewStart.cshtml.

    А как решается эта задача в больших серьезных приложениях?

    Спасибо. 

    1 ноября 2013 г. 7:37

Ответы

  • "А как решается эта задача в больших серьезных приложениях?" - а мы подобное вообще не используем :). Используем собственные поставщики. Вот так и решается эта проблема. А если по делу то посмотрите сюда. Его основная задача инициализация и обеспечение связи с БД при первом запуске. Так как он реализовывается в виде синглтона (одиночки), то основная часть логикики выполняется единожды, в независимости от того, где он находится. Делайте так, как вам удобно.


    Сделаем содержимое сообщества лучше, вместе!

    • Предложено в качестве ответа YatajgaModerator 4 ноября 2013 г. 10:50
    • Помечено в качестве ответа Yaroshvitaliy 4 ноября 2013 г. 13:05
    1 ноября 2013 г. 8:25
    Модератор

Все ответы

  • "А как решается эта задача в больших серьезных приложениях?" - а мы подобное вообще не используем :). Используем собственные поставщики. Вот так и решается эта проблема. А если по делу то посмотрите сюда. Его основная задача инициализация и обеспечение связи с БД при первом запуске. Так как он реализовывается в виде синглтона (одиночки), то основная часть логикики выполняется единожды, в независимости от того, где он находится. Делайте так, как вам удобно.


    Сделаем содержимое сообщества лучше, вместе!

    • Предложено в качестве ответа YatajgaModerator 4 ноября 2013 г. 10:50
    • Помечено в качестве ответа Yaroshvitaliy 4 ноября 2013 г. 13:05
    1 ноября 2013 г. 8:25
    Модератор
  • Спасибо за ответ. Это навело меня на мысль, что выносить SimpleMembershipInitializer в Global.asax чревато тем, что приложение может оказать полностью нерабочим при отсутствии коннекшена к БД, даже если она на той странице и не нужна.
    1 ноября 2013 г. 8:45
  • Не знаю какой код у вас. Но вот если используется отложенная инициализация, то и это не проблема.

    Сделаем содержимое сообщества лучше, вместе!

    1 ноября 2013 г. 8:51
    Модератор
  • Не знаю какой код у вас. Но вот если используется отложенная инициализация, то и это не проблема.

    Сделаем содержимое сообщества лучше, вместе!

    А вот и код. Меня смущает throw new InvalidOperationException в Global.asax. Правильнее было бы как-то донести до пользователя что нету коннекшена на тех страницах, где он используется. Я так понимаю, это уже в контроллерах нужно отлавливать эксепшн и выдавать соответствующую информацию? Не хочу изобретать велосипед.

        public class MvcApplication : System.Web.HttpApplication
        {
            private static SimpleMembershipInitializer _initializer;
            private static object _initializerLock = new object();
            private static bool _isInitialized;
    
            protected void Application_Start()
            {
                AreaRegistration.RegisterAllAreas();
    
                WebApiConfig.Register(GlobalConfiguration.Configuration);
                FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
                RouteConfig.RegisterRoutes(RouteTable.Routes);
                BundleConfig.RegisterBundles(BundleTable.Bundles);
                AuthConfig.RegisterAuth();
    
                DependecyInjectionConfig.RegisterDependencies();
    
                LazyInitializer.EnsureInitialized(ref _initializer, ref _isInitialized, ref _initializerLock);
    
                LogService.GetLogger().Info("Application started");
            }
    
            private class SimpleMembershipInitializer
            {
                public SimpleMembershipInitializer()
                {
                    Database.SetInitializer<UsersContext>(null);
    
                    try
                    {
                        using (var context = new UsersContext())
                        {
                            if (!context.Database.Exists())
                            {
                                // Create the SimpleMembership database without Entity Framework migration schema
                                ((IObjectContextAdapter)context).ObjectContext.CreateDatabase();
                            }
                        }
    
                        WebSecurity.InitializeDatabaseConnection("DefaultConnection", "Users", "UserId", "UserName", autoCreateTables: true);
    
                        if (!Roles.RoleExists("Administrator"))
                        {
                            Roles.CreateRole("Administrator");
                        }
    
                        if (!Roles.RoleExists("Manager"))
                        {
                            Roles.CreateRole("Manager");
                        }
    
                        if (!Roles.RoleExists("Banned"))
                        {
                            Roles.CreateRole("Banned");
                        }
    
                        if (!WebSecurity.UserExists("Administrator"))
                        {
                            WebSecurity.CreateUserAndAccount("Administrator", "Administrator", new {Email = "", Balance = 0});
                            Roles.AddUserToRole("Administrator", "Administrator");
                        }
                    }
                    catch (Exception ex)
                    {
                       LogService.GetLogger().ErrorException(ex.Message, ex);
                       throw new InvalidOperationException("The ASP.NET Simple Membership database could not be initialized. For more information, please see http://go.microsoft.com/fwlink/?LinkId=256588", ex);
                    }
                }
            }
    
        }
    

    Спасибо за советы.

    1 ноября 2013 г. 9:52
  • "Правильнее было бы как-то донести до пользователя что нету коннекшена на тех страницах, где он используется. Я так понимаю, это уже в контроллерах нужно отлавливать эксепшн и выдавать соответствующую информацию?" - можете в контроллере. А ещё лучше в глобальном обработчике ошибок (файл Global.asax), поскольку ошибка носит глобальный характер, связана с приложением в целом, а не конкретно с конкретным контроллером.

    Сделаем содержимое сообщества лучше, вместе!

    1 ноября 2013 г. 9:59
    Модератор