我正在创建一个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();
}
}
}
}
答案 0 :(得分:0)
有趣的问题。您是否考虑过使用新的通用提供商? Dunno如果你遇到相同的httpcontext问题但可能值得一看:http://www.hanselman.com/blog/IntroducingSystemWebProvidersASPNETUniversalProvidersForSessionMembershipRolesAndUserProfileOnSQLCompactAndSQLAzure.aspx
答案 1 :(得分:0)
您是否尝试过调用“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中声明的自定义属性。
此致
答案 2 :(得分:0)
我再次回来,因为我在“Initialize()”函数中添加的解决方案实际上并没有在其他测试之后运行。所以事实上我找到了一种正确运行的方式。
在您的情况下,application_start中的“请求在此上下文中不可用”的问题可能是由于应用程序模式“Integrated”,这是II7中的新功能而不是经典模式。
要了解一个很好的解释,请访问Mike Volodarsky的博客IIS7 Integrated mode: Request is not available in this context exception in 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;
}
}
}