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:
@@ -38,6 +38,7 @@ namespace Orchard.Mvc {
|
|||||||
// 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>(() => siteService.GetSiteSettings().BaseUrl);
|
||||||
var httpContextBase = new HttpContextPlaceholder(baseUrl);
|
var httpContextBase = new HttpContextPlaceholder(baseUrl);
|
||||||
|
|
||||||
@@ -45,8 +46,8 @@ namespace Orchard.Mvc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static RequestContext RequestContextFactory(IComponentContext context) {
|
static RequestContext RequestContextFactory(IComponentContext context) {
|
||||||
var httpContextAccessor = context.Resolve<IHttpContextAccessor>();
|
|
||||||
var httpContext = httpContextAccessor.Current();
|
var httpContext = HttpContextBaseFactory(context);
|
||||||
|
|
||||||
if (!httpContext.IsBackgroundContext()) {
|
if (!httpContext.IsBackgroundContext()) {
|
||||||
|
|
||||||
@@ -62,11 +63,7 @@ namespace Orchard.Mvc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (httpContext is HttpContextPlaceholder) {
|
else if (httpContext is HttpContextPlaceholder) {
|
||||||
if (((HttpContextPlaceholder)httpContext).IsResolved)
|
return ((HttpContextPlaceholder)httpContext).RequestContext;
|
||||||
return httpContext.Request.RequestContext;
|
|
||||||
}
|
|
||||||
else if (httpContext == null) {
|
|
||||||
httpContext = HttpContextBaseFactory(context);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return new RequestContext(httpContext, new RouteData());
|
return new RequestContext(httpContext, new RouteData());
|
||||||
@@ -81,6 +78,7 @@ namespace Orchard.Mvc {
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class HttpContextPlaceholder : HttpContextBase, IDisposable {
|
public class HttpContextPlaceholder : HttpContextBase, IDisposable {
|
||||||
private HttpContext _httpContext;
|
private HttpContext _httpContext;
|
||||||
|
private HttpRequestPlaceholder _request;
|
||||||
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>();
|
||||||
|
|
||||||
@@ -94,15 +92,17 @@ namespace Orchard.Mvc {
|
|||||||
HttpContext.Current = null;
|
HttpContext.Current = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsResolved {
|
|
||||||
get {
|
|
||||||
return _baseUrl.IsValueCreated;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override HttpRequestBase Request {
|
public override HttpRequestBase Request {
|
||||||
get {
|
|
||||||
|
|
||||||
|
// Note: To fully resolve the baseUrl, some factories are needed (HttpContextBase, RequestContext...),
|
||||||
|
// so, doing this in such a factory creates a circular dependency (see HttpContextBase factory comments).
|
||||||
|
|
||||||
|
// When rendering a view in a background task, an Html Helper can access HttpContext.Current directly,
|
||||||
|
// so, here we create a fake HttpContext based on the baseUrl, and use it to update HttpContext.Current.
|
||||||
|
// We cannot do this before in a factory (see note above), anyway, by doing this on each Request access,
|
||||||
|
// we have a better chance to maintain the HttpContext.Current state even with some asynchronous code.
|
||||||
|
|
||||||
|
get {
|
||||||
if (_httpContext == null) {
|
if (_httpContext == null) {
|
||||||
var httpContext = new HttpContext(new HttpRequest("", _baseUrl.Value, ""), new HttpResponse(new StringWriter()));
|
var httpContext = new HttpContext(new HttpRequest("", _baseUrl.Value, ""), new HttpResponse(new StringWriter()));
|
||||||
httpContext.Items[IsBackgroundHttpContextKey] = true;
|
httpContext.Items[IsBackgroundHttpContextKey] = true;
|
||||||
@@ -111,7 +111,24 @@ namespace Orchard.Mvc {
|
|||||||
|
|
||||||
if (HttpContext.Current != _httpContext)
|
if (HttpContext.Current != _httpContext)
|
||||||
HttpContext.Current = _httpContext;
|
HttpContext.Current = _httpContext;
|
||||||
return new HttpRequestPlaceholder(this, new Uri(_baseUrl.Value));
|
|
||||||
|
if (_request == null) {
|
||||||
|
_request = new HttpRequestPlaceholder(this, _baseUrl);
|
||||||
|
}
|
||||||
|
return _request;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal RequestContext RequestContext {
|
||||||
|
|
||||||
|
// Uses the Request object but without creating an HttpContext which would need to resolve the baseUrl,
|
||||||
|
// so, can be used by the RequestContext factory without creating a circular dependency (see note above).
|
||||||
|
|
||||||
|
get {
|
||||||
|
if (_request == null) {
|
||||||
|
_request = new HttpRequestPlaceholder(this, _baseUrl);
|
||||||
|
}
|
||||||
|
return _request.RequestContext;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,28 +188,34 @@ namespace Orchard.Mvc {
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class HttpRequestPlaceholder : HttpRequestBase {
|
public class HttpRequestPlaceholder : HttpRequestBase {
|
||||||
private HttpContextBase _httpContext;
|
private HttpContextBase _httpContext;
|
||||||
private readonly Uri _uri;
|
private RequestContext _requestContext;
|
||||||
|
private readonly Lazy<string> _baseUrl;
|
||||||
|
private readonly NameValueCollection _queryString = new NameValueCollection();
|
||||||
|
private Uri _uri;
|
||||||
|
|
||||||
public HttpRequestPlaceholder(HttpContextBase httpContext, Uri uri) {
|
public HttpRequestPlaceholder(HttpContextBase httpContext, Lazy<string> baseUrl) {
|
||||||
_httpContext = httpContext;
|
_httpContext = httpContext;
|
||||||
_uri = uri;
|
_baseUrl = baseUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override RequestContext RequestContext {
|
public override RequestContext RequestContext {
|
||||||
get {
|
get {
|
||||||
return new RequestContext(_httpContext, new RouteData());
|
if (_requestContext == null) {
|
||||||
|
_requestContext = new RequestContext(_httpContext, new RouteData());
|
||||||
|
}
|
||||||
|
return _requestContext;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override NameValueCollection QueryString {
|
public override NameValueCollection QueryString {
|
||||||
get {
|
get {
|
||||||
return new NameValueCollection();
|
return _queryString;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string RawUrl {
|
public override string RawUrl {
|
||||||
get {
|
get {
|
||||||
return _uri.OriginalString;
|
return Url.OriginalString;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -223,13 +246,16 @@ namespace Orchard.Mvc {
|
|||||||
|
|
||||||
public override Uri Url {
|
public override Uri Url {
|
||||||
get {
|
get {
|
||||||
|
if (_uri == null) {
|
||||||
|
_uri = new Uri(_baseUrl.Value);
|
||||||
|
}
|
||||||
return _uri;
|
return _uri;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override NameValueCollection Headers {
|
public override NameValueCollection Headers {
|
||||||
get {
|
get {
|
||||||
return new NameValueCollection { { "Host", _uri.Authority } };
|
return new NameValueCollection { { "Host", Url.Authority } };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -253,15 +279,15 @@ namespace Orchard.Mvc {
|
|||||||
|
|
||||||
public override string ApplicationPath {
|
public override string ApplicationPath {
|
||||||
get {
|
get {
|
||||||
return _uri.LocalPath;
|
return Url.LocalPath;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override NameValueCollection ServerVariables {
|
public override NameValueCollection ServerVariables {
|
||||||
get {
|
get {
|
||||||
return new NameValueCollection {
|
return new NameValueCollection {
|
||||||
{ "SERVER_PORT", _uri.Port.ToString(CultureInfo.InvariantCulture) },
|
{ "SERVER_PORT", Url.Port.ToString(CultureInfo.InvariantCulture) },
|
||||||
{ "HTTP_HOST", _uri.Authority.ToString(CultureInfo.InvariantCulture) },
|
{ "HTTP_HOST", Url.Authority.ToString(CultureInfo.InvariantCulture) },
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user