mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 19:54:57 +08:00
Update MvcModule.cs
This commit is contained in:
@@ -1,20 +1,23 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Specialized;
|
using System.Collections.Specialized;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
using System.IO;
|
||||||
using System.Web;
|
using System.Web;
|
||||||
using System.Web.Caching;
|
using System.Web.Caching;
|
||||||
using System.Web.Instrumentation;
|
using System.Web.Instrumentation;
|
||||||
using System.Web.Mvc;
|
using System.Web.Mvc;
|
||||||
using System.Web.Routing;
|
using System.Web.Routing;
|
||||||
using Autofac;
|
using Autofac;
|
||||||
|
using Orchard.Environment.Configuration;
|
||||||
|
using Orchard.Mvc.Extensions;
|
||||||
using Orchard.Mvc.Routes;
|
using Orchard.Mvc.Routes;
|
||||||
using Orchard.Settings;
|
using Orchard.Settings;
|
||||||
using Orchard.Exceptions;
|
|
||||||
|
|
||||||
namespace Orchard.Mvc {
|
namespace Orchard.Mvc {
|
||||||
public class MvcModule : Module {
|
public class MvcModule : Module {
|
||||||
|
public const string IsBackgroundHttpContextKey = "IsBackgroundHttpContext";
|
||||||
|
|
||||||
protected override void Load(ContainerBuilder moduleBuilder) {
|
protected override void Load(ContainerBuilder moduleBuilder) {
|
||||||
moduleBuilder.RegisterType<ShellRoute>().InstancePerDependency();
|
moduleBuilder.RegisterType<ShellRoute>().InstancePerDependency();
|
||||||
@@ -24,37 +27,25 @@ namespace Orchard.Mvc {
|
|||||||
moduleBuilder.Register(UrlHelperFactory).As<UrlHelper>().InstancePerDependency();
|
moduleBuilder.Register(UrlHelperFactory).As<UrlHelper>().InstancePerDependency();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool IsRequestValid() {
|
|
||||||
if (HttpContext.Current == null)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
try {
|
|
||||||
// The "Request" property throws at application startup on IIS integrated pipeline mode.
|
|
||||||
var req = HttpContext.Current.Request;
|
|
||||||
}
|
|
||||||
catch (Exception ex) {
|
|
||||||
if (ex.IsFatal()) {
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HttpContextBase HttpContextBaseFactory(IComponentContext context) {
|
static HttpContextBase HttpContextBaseFactory(IComponentContext context) {
|
||||||
if (IsRequestValid()) {
|
|
||||||
return new HttpContextWrapper(HttpContext.Current);
|
var httpContext = context.Resolve<IHttpContextAccessor>().Current();
|
||||||
}
|
if (httpContext != null)
|
||||||
|
return httpContext;
|
||||||
|
|
||||||
var siteService = context.Resolve<ISiteService>();
|
var siteService = context.Resolve<ISiteService>();
|
||||||
|
var prefix = context.Resolve<ShellSettings>().RequestUrlPrefix;
|
||||||
|
|
||||||
// Wrapping the code accessing the SiteSettings in a function that will be executed later (in HttpContextPlaceholder),
|
// Wrapping the code accessing the SiteSettings in a function that will be executed later (in HttpContextPlaceholder),
|
||||||
// so that the RequestContext will have been established when the time comes to actually load the site settings,
|
// so that the RequestContext will have been established when the time comes to actually load the site settings,
|
||||||
// which requires activating the Site content item, which in turn requires a UrlHelper, which in turn requires a RequestContext,
|
// which requires activating the Site content item, which in turn requires a UrlHelper, which in turn requires a RequestContext,
|
||||||
// thus preventing a StackOverflowException.
|
// thus preventing a StackOverflowException.
|
||||||
var baseUrl = new Func<string>(() => siteService.GetSiteSettings().BaseUrl);
|
var baseUrl = new Func<string>(() => {
|
||||||
|
var url = siteService.GetSiteSettings().BaseUrl;
|
||||||
|
return !string.IsNullOrWhiteSpace(url) ? !string.IsNullOrWhiteSpace(prefix) ?
|
||||||
|
url.TrimEnd('/') + "/" + prefix : url : "http://localhost"
|
||||||
|
+ System.Web.Hosting.HostingEnvironment.ApplicationVirtualPath;
|
||||||
|
});
|
||||||
var httpContextBase = new HttpContextPlaceholder(baseUrl);
|
var httpContextBase = new HttpContextPlaceholder(baseUrl);
|
||||||
|
|
||||||
return httpContextBase;
|
return httpContextBase;
|
||||||
@@ -63,7 +54,8 @@ namespace Orchard.Mvc {
|
|||||||
static RequestContext RequestContextFactory(IComponentContext context) {
|
static RequestContext RequestContextFactory(IComponentContext context) {
|
||||||
var httpContextAccessor = context.Resolve<IHttpContextAccessor>();
|
var httpContextAccessor = context.Resolve<IHttpContextAccessor>();
|
||||||
var httpContext = httpContextAccessor.Current();
|
var httpContext = httpContextAccessor.Current();
|
||||||
if (httpContext != null) {
|
|
||||||
|
if (!httpContext.IsBackgroundContext()) {
|
||||||
|
|
||||||
var mvcHandler = httpContext.Handler as MvcHandler;
|
var mvcHandler = httpContext.Handler as MvcHandler;
|
||||||
if (mvcHandler != null) {
|
if (mvcHandler != null) {
|
||||||
@@ -76,7 +68,11 @@ namespace Orchard.Mvc {
|
|||||||
return hasRequestContext.RequestContext;
|
return hasRequestContext.RequestContext;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else if (httpContext is HttpContextPlaceholder) {
|
||||||
|
if (((HttpContextPlaceholder)httpContext).IsResolved)
|
||||||
|
return httpContext.Request.RequestContext;
|
||||||
|
}
|
||||||
|
else if (httpContext == null) {
|
||||||
httpContext = HttpContextBaseFactory(context);
|
httpContext = HttpContextBaseFactory(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,7 +86,8 @@ namespace Orchard.Mvc {
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Standin context for background tasks.
|
/// Standin context for background tasks.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class HttpContextPlaceholder : HttpContextBase {
|
public class HttpContextPlaceholder : HttpContextBase, IDisposable {
|
||||||
|
private HttpContext _httpContext;
|
||||||
private readonly Lazy<string> _baseUrl;
|
private readonly Lazy<string> _baseUrl;
|
||||||
private readonly IDictionary _items = new Dictionary<object, object>();
|
private readonly IDictionary _items = new Dictionary<object, object>();
|
||||||
|
|
||||||
@@ -98,8 +95,35 @@ namespace Orchard.Mvc {
|
|||||||
_baseUrl = new Lazy<string>(baseUrl);
|
_baseUrl = new Lazy<string>(baseUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Dispose() {
|
||||||
|
_httpContext = null;
|
||||||
|
if (HttpContext.Current != null)
|
||||||
|
HttpContext.Current = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsResolved {
|
||||||
|
get {
|
||||||
|
return _baseUrl.IsValueCreated;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override HttpRequestBase Request {
|
public override HttpRequestBase Request {
|
||||||
get { return new HttpRequestPlaceholder(new Uri(_baseUrl.Value)); }
|
get {
|
||||||
|
|
||||||
|
if (_httpContext == null) {
|
||||||
|
var httpContext = new HttpContext(new HttpRequest("", _baseUrl.Value, ""), new HttpResponse(new StringWriter()));
|
||||||
|
httpContext.Items[IsBackgroundHttpContextKey] = true;
|
||||||
|
_httpContext = httpContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HttpContext.Current != _httpContext)
|
||||||
|
HttpContext.Current = _httpContext;
|
||||||
|
return new HttpRequestPlaceholder(this, new Uri(_baseUrl.Value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override HttpSessionStateBase Session {
|
||||||
|
get { return new HttpSessionStatePlaceholder(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IHttpHandler Handler { get; set; }
|
public override IHttpHandler Handler { get; set; }
|
||||||
@@ -129,6 +153,14 @@ namespace Orchard.Mvc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class HttpSessionStatePlaceholder : HttpSessionStateBase {
|
||||||
|
public override object this[string name] {
|
||||||
|
get {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class HttpResponsePlaceholder : HttpResponseBase {
|
public class HttpResponsePlaceholder : HttpResponseBase {
|
||||||
public override string ApplyAppPathModifier(string virtualPath) {
|
public override string ApplyAppPathModifier(string virtualPath) {
|
||||||
return virtualPath;
|
return virtualPath;
|
||||||
@@ -145,12 +177,32 @@ namespace Orchard.Mvc {
|
|||||||
/// standin context for background tasks.
|
/// standin context for background tasks.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class HttpRequestPlaceholder : HttpRequestBase {
|
public class HttpRequestPlaceholder : HttpRequestBase {
|
||||||
|
private HttpContextBase _httpContext;
|
||||||
private readonly Uri _uri;
|
private readonly Uri _uri;
|
||||||
|
|
||||||
public HttpRequestPlaceholder(Uri uri) {
|
public HttpRequestPlaceholder(HttpContextBase httpContext, Uri uri) {
|
||||||
|
_httpContext = httpContext;
|
||||||
_uri = uri;
|
_uri = uri;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override RequestContext RequestContext {
|
||||||
|
get {
|
||||||
|
return new RequestContext(_httpContext, new RouteData());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override NameValueCollection QueryString {
|
||||||
|
get {
|
||||||
|
return new NameValueCollection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string RawUrl {
|
||||||
|
get {
|
||||||
|
return _uri.OriginalString;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// anonymous identity provided for background task.
|
/// anonymous identity provided for background task.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -158,17 +210,6 @@ namespace Orchard.Mvc {
|
|||||||
get { return false; }
|
get { return false; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Create an anonymous ID the same way as ASP.NET would.
|
|
||||||
/// Some users of an HttpRequestPlaceHolder object could expect this,
|
|
||||||
/// say CookieCultureSelector from module Orchard.CulturePicker.
|
|
||||||
/// </summary>
|
|
||||||
public override string AnonymousID {
|
|
||||||
get {
|
|
||||||
return Guid.NewGuid().ToString("D", CultureInfo.InvariantCulture);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// empty collection provided for background operation
|
// empty collection provided for background operation
|
||||||
public override NameValueCollection Form {
|
public override NameValueCollection Form {
|
||||||
get {
|
get {
|
||||||
@@ -278,4 +319,4 @@ namespace Orchard.Mvc {
|
|||||||
public override int ScriptTimeout { get; set; }
|
public override int ScriptTimeout { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user