Добавление значений профиля для автоматически сгенерированного пользователя - PullRequest
1 голос
/ 30 августа 2011

Я создаю веб-сайт ASP.NET MVC 3.0 и выполняю несколько разных инициализаций базы данных в зависимости от того, предназначен ли сайт для разработки, тестирования или производства. Я застрял на инициализации тестирования, так как я пытаюсь создать тестового пользователя. Я могу заставить пользователя просто создавать, но когда я пытаюсь добавить некоторые значения профиля, я получаю: System.Web.HttpException: Запрос не доступен в этом контексте. Есть ли способ добавить значения профиля в ситуации, когда запрос не будет доступен?

Следующий код - это то, что выполняется:

    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

        RegisterGlobalFilters(GlobalFilters.Filters);
        RegisterRoutes(RouteTable.Routes);

        if (ApplicationServices.GetInitialCatalog() != "tasktracker")
        {
            Database.SetInitializer(new TaskTrackerDropCreateDatabaseIfModelChanges());
        }
        else
        {
            Database.SetInitializer(new TaskTrackerCreateDatabaseIfNotExists());
        }

        using (var db = new TaskTrackerContext())
        {
            db.Database.Initialize(false);
        }
    }

public class TaskTrackerDropCreateDatabaseIfModelChanges : DropCreateDatabaseIfModelChanges<TaskTrackerContext>
{
    protected override void Seed(TaskTrackerContext context)
    {
        // Set up the membership, roles, and profile systems.
        ApplicationServices.InstallServices(SqlFeatures.Membership | SqlFeatures.Profile | SqlFeatures.RoleManager);

        // Create the default accounts and roles.
        if (ApplicationServices.GetInitialCatalog() == "tasktracker_testing")
        {
            if (Membership.GetUser("testuser", false) == null)
            {
                Membership.CreateUser("testuser", "password", "testuser@test.com");
                MembershipUser user = Membership.GetUser("testuser", false);
                user.IsApproved = true;

                var profile = ProfileBase.Create("testuser");
                profile.SetPropertyValue("FirstName", "test");
                profile.SetPropertyValue("LastName", "user");
                profile.SetPropertyValue("TimeZone", "US Mountain Standard Time");
                profile.Save();
            }
        }
    }
}

Ответы [ 3 ]

0 голосов
/ 04 июля 2012

Вы пытались сделать вызов "Initialize ()":

profile.Initialize(username, true) 

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

Используя Reflector, я увидел, что ProfileBase of Initialize (см. Ниже) создает такой вид контекста из настроек:

public void Initialize(string username, bool isAuthenticated)
{
    if (username != null)
    {
        this._UserName = username.Trim();
    }
    else
    {
        this._UserName = username;
    }
    SettingsContext context = new SettingsContext();
    context.Add("UserName", this._UserName);
    context.Add("IsAuthenticated", isAuthenticated);
    this._IsAuthenticated = isAuthenticated;
    base.Initialize(context, s_Properties, ProfileManager.Providers);
}

Кажется, что здесь работает, SettingsContext (), похоже, учитывает мои пользовательские свойства, объявленные в web.config.

С уважением,

0 голосов
/ 04 июля 2012

Я возвращаюсь снова, потому что решение, которое я добавил с помощью функции «Initialize ()», фактически не запускается после другого теста. Так что на самом деле я нашел способ, который работает правильно.

Проблема «запрос недоступен в этом контексте» в application_start в вашем случае может быть из-за режима приложения «Интегрированный», который является новым из II7 вместо классического режима.

Чтобы увидеть хорошее объяснение, вы можете зайти в блог Майка Володарского Интегрированный режим IIS7: в этом контексте исключение запроса недоступно в Application_Start .

Я копирую / вставляю выдержку, которая может указывать на основную причину:

"* Эта ошибка связана с изменением конструкции в интегрированном конвейере IIS7, из-за которого контекст запроса становится недоступным в событии Application_Start. При использовании классического режима (единственный режим при работе в предыдущих версиях IIS) использовался контекст запроса быть доступным, даже если событие Application_Start всегда предназначалось как глобальное и не зависящее от запроса событие в жизни приложения. Несмотря на это, поскольку приложения ASP.NET всегда запускались при первом обращении к приложению, раньше это было возможно чтобы добраться до контекста запроса через статическое поле HttpContext.Current. * "

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

Хороший пример кода приведен в его блоге:

    void Application_BeginRequest(Object source, EventArgs e)

{

    HttpApplication app = (HttpApplication)source;

    HttpContext context = app.Context;



    // Attempt to peform first request initialization

    FirstRequestInitialization.Initialize(context);

}




class FirstRequestInitialization

{

    private static bool s_InitializedAlready = false;
    private static Object s_lock = new Object();

    // Initialize only on the first request
    public static void Initialize(HttpContext context)
    {
        if (s_InitializedAlready)
        {
            return;
        }

        lock (s_lock)
        {
            if (s_InitializedAlready)
            {
                return;
            }

            // Perform first-request initialization here 
            //
            // You can use your create profile code  here....


            //---

            s_InitializedAlready = true;
        }
    }
}
0 голосов
/ 31 августа 2011

Интересный вопрос. Вы смотрели на использование новых универсальных провайдеров? Не знаю, если вы столкнетесь с той же проблемой httpcontext, но, возможно, стоит посмотреть:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...