ASP NET 核心服务特定 html 页面
ASP NET Core Serving specific html page
我有这个中间件:
public class SpecificPageMiddleware
{
private readonly RequestDelegate next;
public SpecificPageMiddleware(RequestDelegate next)
{
this.next = next;
}
public async Task Invoke(HttpContext context)
{
if (this.IsSubDomainRequest(context.Request.Host.Value))
{
if (this.IsIndexRequest(context.Request.Path.Value))
{
await this.ReturnIndexPage(context);
return;
}
}
await this.next.Invoke(context);
}
private bool IsSubDomainRequest(string host)
{
return host.StartsWith("subdomain")
|| host.Contains("subdomain");
}
private bool IsIndexRequest(string query)
{
return query == "/" || query == "/response.html";
}
private static async Task ReturnIndexPage(HttpContext context)
{
var file = new FileInfo(@"wwwroot\response.html");
byte[] buffer;
if (file.Exists)
{
context.Response.StatusCode = (int)HttpStatusCode.OK;
context.Response.ContentType = "text/html";
buffer = File.ReadAllBytes(file.FullName);
}
else
{
context.Response.StatusCode = (int)HttpStatusCode.NotFound;
context.Response.ContentType = "text/plain";
buffer = Encoding.UTF8.GetBytes("Unable to find the requested file");
}
using (var stream = context.Response.Body)
{
await stream.WriteAsync(buffer, 0, buffer.Length);
await stream.FlushAsync();
}
context.Response.ContentLength = buffer.Length;
}
}
很简单,当我得到这样的东西时: subdomain.mydomain.com
我想显示一个特定的 html 页面,否则继续正常的中间件管道到 www.mydomain.com
.
当这个中间件被命中时,它在浏览器中以 404 结束。如果我不设置内容类型,那么它最终为 200,所有 html 都写为文本,而不是呈现为 html。我在这里错过了什么?
我不想使用 app.UseDefaultFiles()
或 app.UseStaticFiles()
。
回答。
你犯的一个错误是:
await this.ReturnIndexPage(context); // wrong!
await SpecificPageMiddleware.ReturnIndexPage(context); // right (1)
await ReturnIndexPage(context); // right (2)
this
表示实例。您无法从实例访问 static
方法。相反,您必须使用类型名称 (1) 或不使用类型名称 (2) 对其进行限定,这样就可以了。
在我的机器上工作
为了更好的衡量,this is up on GitHub too as a demo.
SimpleMiddleware.cs
using Microsoft.AspNet.Builder;
using System.Threading.Tasks;
using Microsoft.AspNet.Http;
using System.IO;
using System.Text;
using System.Net;
namespace App04SimpleMiddleware
{
public class SimpleMiddleware
{
private readonly RequestDelegate _next;
public SimpleMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
if (context.Request.QueryString.ToString().Contains("simple"))
{
await ReturnIndexPage(context); // right!
return;
}
await _next.Invoke(context);
}
private static async Task ReturnIndexPage(HttpContext context)
{
var file = new FileInfo(@"wwwroot\response.html");
byte[] buffer;
if (file.Exists)
{
context.Response.StatusCode = (int)HttpStatusCode.OK;
context.Response.ContentType = "text/html";
buffer = File.ReadAllBytes(file.FullName);
}
else
{
context.Response.StatusCode = (int)HttpStatusCode.NotFound;
context.Response.ContentType = "text/plain";
buffer = Encoding.UTF8
.GetBytes("Unable to find the requested file");
}
context.Response.ContentLength = buffer.Length;
using (var stream = context.Response.Body)
{
await stream.WriteAsync(buffer, 0, buffer.Length);
await stream.FlushAsync();
}
}
}
}
Startup.cs
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Http;
namespace App04SimpleMiddleware
{
public class Startup
{
public void Configure(IApplicationBuilder app)
{
app.UseMiddleware<SimpleMiddleware>();
app.Run(async (context) =>
{
await context.Response.WriteAsync("Hello world!");
});
}
}
}
结果
我有这个中间件:
public class SpecificPageMiddleware
{
private readonly RequestDelegate next;
public SpecificPageMiddleware(RequestDelegate next)
{
this.next = next;
}
public async Task Invoke(HttpContext context)
{
if (this.IsSubDomainRequest(context.Request.Host.Value))
{
if (this.IsIndexRequest(context.Request.Path.Value))
{
await this.ReturnIndexPage(context);
return;
}
}
await this.next.Invoke(context);
}
private bool IsSubDomainRequest(string host)
{
return host.StartsWith("subdomain")
|| host.Contains("subdomain");
}
private bool IsIndexRequest(string query)
{
return query == "/" || query == "/response.html";
}
private static async Task ReturnIndexPage(HttpContext context)
{
var file = new FileInfo(@"wwwroot\response.html");
byte[] buffer;
if (file.Exists)
{
context.Response.StatusCode = (int)HttpStatusCode.OK;
context.Response.ContentType = "text/html";
buffer = File.ReadAllBytes(file.FullName);
}
else
{
context.Response.StatusCode = (int)HttpStatusCode.NotFound;
context.Response.ContentType = "text/plain";
buffer = Encoding.UTF8.GetBytes("Unable to find the requested file");
}
using (var stream = context.Response.Body)
{
await stream.WriteAsync(buffer, 0, buffer.Length);
await stream.FlushAsync();
}
context.Response.ContentLength = buffer.Length;
}
}
很简单,当我得到这样的东西时: subdomain.mydomain.com
我想显示一个特定的 html 页面,否则继续正常的中间件管道到 www.mydomain.com
.
当这个中间件被命中时,它在浏览器中以 404 结束。如果我不设置内容类型,那么它最终为 200,所有 html 都写为文本,而不是呈现为 html。我在这里错过了什么?
我不想使用 app.UseDefaultFiles()
或 app.UseStaticFiles()
。
回答。
你犯的一个错误是:
await this.ReturnIndexPage(context); // wrong!
await SpecificPageMiddleware.ReturnIndexPage(context); // right (1)
await ReturnIndexPage(context); // right (2)
this
表示实例。您无法从实例访问 static
方法。相反,您必须使用类型名称 (1) 或不使用类型名称 (2) 对其进行限定,这样就可以了。
在我的机器上工作
为了更好的衡量,this is up on GitHub too as a demo.
SimpleMiddleware.cs
using Microsoft.AspNet.Builder;
using System.Threading.Tasks;
using Microsoft.AspNet.Http;
using System.IO;
using System.Text;
using System.Net;
namespace App04SimpleMiddleware
{
public class SimpleMiddleware
{
private readonly RequestDelegate _next;
public SimpleMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
if (context.Request.QueryString.ToString().Contains("simple"))
{
await ReturnIndexPage(context); // right!
return;
}
await _next.Invoke(context);
}
private static async Task ReturnIndexPage(HttpContext context)
{
var file = new FileInfo(@"wwwroot\response.html");
byte[] buffer;
if (file.Exists)
{
context.Response.StatusCode = (int)HttpStatusCode.OK;
context.Response.ContentType = "text/html";
buffer = File.ReadAllBytes(file.FullName);
}
else
{
context.Response.StatusCode = (int)HttpStatusCode.NotFound;
context.Response.ContentType = "text/plain";
buffer = Encoding.UTF8
.GetBytes("Unable to find the requested file");
}
context.Response.ContentLength = buffer.Length;
using (var stream = context.Response.Body)
{
await stream.WriteAsync(buffer, 0, buffer.Length);
await stream.FlushAsync();
}
}
}
}
Startup.cs
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Http;
namespace App04SimpleMiddleware
{
public class Startup
{
public void Configure(IApplicationBuilder app)
{
app.UseMiddleware<SimpleMiddleware>();
app.Run(async (context) =>
{
await context.Response.WriteAsync("Hello world!");
});
}
}
}
结果