开发者

Adding profile values for auto-generated user

I'm creating a ASP.NET MVC 3.0 website, and have a couple of different database initializations based on whether the site is i开发者_如何学Pythonntended for development, testing, or production. I'm stuck on the testing initialization, as I'm trying to get a test user created. I can get the user to create just fine, however when I try to add some profile values, I get: System.Web.HttpException: Request is not available in this context. Is there a way to add Profile values in a situation where the request isn't going to be available?

Following code is what is being run:

    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();
            }
        }
    }
}


Interesting question. Have you looked at using the new Universal Providers? Dunno if you will run into the same httpcontext issue but may be worth a look: http://www.hanselman.com/blog/IntroducingSystemWebProvidersASPNETUniversalProvidersForSessionMembershipRolesAndUserProfileOnSQLCompactAndSQLAzure.aspx


Did you try to do a call of "Initialize()" :

profile.Initialize(username, true) 

after your create action to see if the context should be Initialized.

By using Reflector i saw the ProfileBase of Initialize (see below) creates this kind of context from the settings:

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);
}

It seems working here, the SettingsContext() seems taking account of my custom properties declared in the web.config.

Regards,


I come back again because the solution I added with the "Initialize()" function in fact not run really after an other test. So in fact I found a way which runs correctly.

The problem of "request is not available in this context" in application_start in your case could be due to the application mode "Integrated" which is new from II7 instead of the Classic mode.

To see a good explain you ca go on the Mike Volodarsky's blog IIS7 Integrated mode: Request is not available in this context exception in Application_Start .

I copy/paste an extract which could indicate the main reason:

" *This error is due to a design change in the IIS7 Integrated pipeline that makes the request context unavailable in Application_Start event. When using the Classic mode (the only mode when running on previous versions of IIS), the request context used to be available, even though the Application_Start event has always been intended as a global and request-agnostic event in the application lifetime. Despite this, because ASP.NET applications were always started by the first request to the app, it used to be possible to get to the request context through the static HttpContext.Current field.* "

To solve this you can use a workaround that moves your first-request initialization from Application_Start to BeginRequest and performs the request-specific initialization on the first request.

A good example of code is done in his blog :

    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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜