Further stylistic tweaks

This commit is contained in:
SteveSandersonMS
2016-05-31 22:29:27 +01:00
parent 5bb92d02dd
commit cb289fd387
10 changed files with 64 additions and 42 deletions

View File

@@ -25,16 +25,14 @@ namespace Microsoft.AspNetCore.AngularServices
try
{
var request = html.ViewContext.HttpContext.Request;
var baseUri =
new Uri(
string.Concat(
request.Scheme,
"://",
request.Host.ToUriComponent(),
request.PathBase.ToUriComponent(),
request.Path.ToUriComponent(),
request.QueryString.ToUriComponent()));
var fullUri = new Uri(baseUri, url);
var baseUriString = string.Concat(
request.Scheme,
"://",
request.Host.ToUriComponent(),
request.PathBase.ToUriComponent(),
request.Path.ToUriComponent(),
request.QueryString.ToUriComponent());
var fullUri = new Uri(new Uri(baseUriString), url);
var response = await new HttpClient().GetAsync(fullUri.ToString());
var responseBody = await response.Content.ReadAsStringAsync();
return new HtmlString(FormatAsScript(url, response.StatusCode, responseBody));
@@ -48,11 +46,13 @@ namespace Microsoft.AspNetCore.AngularServices
}
private static string FormatAsScript(string url, HttpStatusCode responseStatusCode, string responseBody)
=>
"<script>" +
"window.__preCachedResponses = window.__preCachedResponses || {}; " +
$"window.__preCachedResponses[{JsonConvert.SerializeObject(url)}] " +
$"= {JsonConvert.SerializeObject(new { statusCode = responseStatusCode, body = responseBody })};" +
"</script>";
{
var preCachedUrl = JsonConvert.SerializeObject(url);
var preCachedJson = JsonConvert.SerializeObject(new { statusCode = responseStatusCode, body = responseBody });
return "<script>"
+ "window.__preCachedResponses = window.__preCachedResponses || {};"
+ $"window.__preCachedResponses[{preCachedUrl}] = {preCachedJson};"
+ "</script>";
}
}
}

View File

@@ -1,11 +1,9 @@
using System;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.PlatformAbstractions;
using Microsoft.AspNetCore.Hosting;
namespace Microsoft.AspNetCore.NodeServices
{
using System;
public static class Configuration
{
private static readonly string[] DefaultWatchFileExtensions = {".js", ".jsx", ".ts", ".tsx", ".json", ".html"};
@@ -20,15 +18,18 @@ namespace Microsoft.AspNetCore.NodeServices
=> AddNodeServices(serviceCollection, DefaultOptions);
public static void AddNodeServices(this IServiceCollection serviceCollection, NodeServicesOptions options)
=> serviceCollection.AddSingleton(typeof(INodeServices), serviceProvider =>
{
serviceCollection.AddSingleton(typeof(INodeServices), serviceProvider =>
{
var hostEnv = serviceProvider.GetRequiredService<IHostingEnvironment>();
if (string.IsNullOrEmpty(options.ProjectPath))
{
options.ProjectPath = hostEnv.ContentRootPath;
}
return CreateNodeServices(options);
});
}
public static INodeServices CreateNodeServices(NodeServicesOptions options)
{

View File

@@ -64,12 +64,14 @@ namespace Microsoft.AspNetCore.NodeServices
{
return JsonConvert.DeserializeObject<T>(responseString);
}
if (typeof(T) != typeof(string))
{
throw new ArgumentException(
"Node module responded with non-JSON string. This cannot be converted to the requested generic type: " +
typeof(T).FullName);
}
return (T)(object)responseString;
}
}

View File

@@ -15,6 +15,7 @@ namespace Microsoft.AspNetCore.NodeServices
private readonly object _childProcessLauncherLock;
private readonly string _commandLineArguments;
private readonly StringAsTempFile _entryPointScript;
private Process _nodeProcess;
private TaskCompletionSource<bool> _nodeProcessIsReadySource;
private readonly string _projectPath;
private bool _disposed;
@@ -27,18 +28,28 @@ namespace Microsoft.AspNetCore.NodeServices
_commandLineArguments = commandLineArguments ?? string.Empty;
}
protected Process NodeProcess { get; private set; }
protected Process NodeProcess
{
get
{
// This is only exposed to support the unreliable InputOutputStreamNodeInstance, which is just to verify that
// other hosting/transport mechanisms are possible. This shouldn't really be exposed, and will be removed.
return this._nodeProcess;
}
}
public Task<T> Invoke<T>(string moduleName, params object[] args)
=> InvokeExport<T>(moduleName, null, args);
public Task<T> InvokeExport<T>(string moduleName, string exportedFunctionName, params object[] args)
=> Invoke<T>(new NodeInvocationInfo
{
return Invoke<T>(new NodeInvocationInfo
{
ModuleName = moduleName,
ExportedFunctionName = exportedFunctionName,
Args = args
});
}
public void Dispose()
{
@@ -52,7 +63,7 @@ namespace Microsoft.AspNetCore.NodeServices
{
lock (_childProcessLauncherLock)
{
if (NodeProcess == null || NodeProcess.HasExited)
if (_nodeProcess == null || _nodeProcess.HasExited)
{
var startInfo = new ProcessStartInfo("node")
{
@@ -79,7 +90,7 @@ namespace Microsoft.AspNetCore.NodeServices
#endif
OnBeforeLaunchProcess();
NodeProcess = Process.Start(startInfo);
_nodeProcess = Process.Start(startInfo);
ConnectToInputOutputStreams();
}
}
@@ -98,7 +109,7 @@ namespace Microsoft.AspNetCore.NodeServices
var initializationIsCompleted = false; // TODO: Make this thread-safe? (Interlocked.Exchange etc.)
_nodeProcessIsReadySource = new TaskCompletionSource<bool>();
NodeProcess.OutputDataReceived += (sender, evt) =>
_nodeProcess.OutputDataReceived += (sender, evt) =>
{
if (evt.Data == "[Microsoft.AspNetCore.NodeServices:Listening]" && !initializationIsCompleted)
{
@@ -111,7 +122,7 @@ namespace Microsoft.AspNetCore.NodeServices
}
};
NodeProcess.ErrorDataReceived += (sender, evt) =>
_nodeProcess.ErrorDataReceived += (sender, evt) =>
{
if (evt.Data != null)
{
@@ -124,8 +135,8 @@ namespace Microsoft.AspNetCore.NodeServices
}
};
NodeProcess.BeginOutputReadLine();
NodeProcess.BeginErrorReadLine();
_nodeProcess.BeginOutputReadLine();
_nodeProcess.BeginErrorReadLine();
}
protected virtual void OnBeforeLaunchProcess()
@@ -151,9 +162,9 @@ namespace Microsoft.AspNetCore.NodeServices
_entryPointScript.Dispose();
}
if (NodeProcess != null && !NodeProcess.HasExited)
if (_nodeProcess != null && !_nodeProcess.HasExited)
{
NodeProcess.Kill();
_nodeProcess.Kill();
// TODO: Is there a more graceful way to end it? Or does this still let it perform any cleanup?
}

View File

@@ -4,7 +4,7 @@ namespace Microsoft.AspNetCore.SpaServices.Prerendering
{
public JavaScriptModuleExport(string moduleName)
{
this.ModuleName = moduleName;
ModuleName = moduleName;
}
public string ModuleName { get; private set; }

View File

@@ -17,18 +17,20 @@ namespace Microsoft.AspNetCore.SpaServices.Prerendering
});
}
public static async Task<RenderToStringResult> RenderToString(
public static Task<RenderToStringResult> RenderToString(
string applicationBasePath,
INodeServices nodeServices,
JavaScriptModuleExport bootModule,
string requestAbsoluteUrl,
string requestPathAndQuery)
=> await nodeServices.InvokeExport<RenderToStringResult>(
{
return nodeServices.InvokeExport<RenderToStringResult>(
NodeScript.Value.FileName,
"renderToString",
applicationBasePath,
bootModule,
requestAbsoluteUrl,
requestPathAndQuery);
}
}
}

View File

@@ -24,9 +24,14 @@ namespace Microsoft.AspNetCore.SpaServices
string routeKey,
RouteValueDictionary values,
RouteDirection routeDirection)
=> !HasDotInLastSegment(values[_clientRouteTokenName] as string ?? string.Empty);
{
return !HasDotInLastSegment(values[_clientRouteTokenName] as string ?? string.Empty);
}
private bool HasDotInLastSegment(string uri)
=> uri.IndexOf('.', uri.LastIndexOf('/') + 1) >= 0;
{
var lastSegmentStartPos = uri.LastIndexOf('/');
return uri.IndexOf('.', lastSegmentStartPos + 1) >= 0;
}
}
}

View File

@@ -17,13 +17,15 @@ namespace Microsoft.AspNetCore.Builder
object defaults,
object constraints = null,
object dataTokens = null)
=> MapSpaFallbackRoute(
{
MapSpaFallbackRoute(
routeBuilder,
name,
/* templatePrefix */ null,
defaults,
constraints,
dataTokens);
}
public static void MapSpaFallbackRoute(
this IRouteBuilder routeBuilder,
@@ -34,7 +36,6 @@ namespace Microsoft.AspNetCore.Builder
object dataTokens = null)
{
var template = CreateRouteTemplate(templatePrefix);
var constraintsDict = ObjectToDictionary(constraints);
constraintsDict.Add(ClientRouteTokenName, new SpaRouteConstraint(ClientRouteTokenName));

View File

@@ -67,10 +67,10 @@ namespace Microsoft.AspNetCore.SpaServices.Webpack
requestMessage.Method = new HttpMethod(context.Request.Method);
using (
var responseMessage =
await
_httpClient.SendAsync(requestMessage, HttpCompletionOption.ResponseHeadersRead,
context.RequestAborted))
var responseMessage = await _httpClient.SendAsync(
requestMessage,
HttpCompletionOption.ResponseHeadersRead,
context.RequestAborted))
{
if (responseMessage.StatusCode == HttpStatusCode.NotFound)
{

View File

@@ -91,4 +91,4 @@ namespace Microsoft.AspNetCore.Builder
}
}
#pragma warning restore CS0649
}
}