我有一个看起来像这样的控制器
IHttpWrite httpWrite;
[HttpPost]
public async Task<HttpResponse> Post(Request req)
{
return await httpWrite.Write(req, Response);
}
称为的
public async Task<HttpResponse> Write(object data, HttpResponse httpResponse)
{
var json = JsonConvert.SerializeObject(data);
httpResponse.OnStarting(() =>
{
httpResponse.Clear();
httpResponse.ContentType = "application/json";
return Task.CompletedTask;
});
await httpResponse.WriteAsync(json);
return httpResponse;
}
但是调用它会得到这个异常
System.InvalidOperationException: Headers are read-only, response has already started.
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpHeaders.ThrowHeadersReadOnlyException()
我知道一旦将数据写入响应中就无法设置标头,但最终我要在HttpResponse中设置标头,然后再向其中写入任何内容。
从我完成的调试中,仅在控制器返回HttpResponse之后才引发标头的异常。这向我表明,尝试在我的代码之外的某些内容上更改标头。
我正在使用Visual Studio设置的大多数样板代码。这是默认程序
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
哪个调用的是默认情况下的启动
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseMvc();
}
我认为解决方案要么在于更改配置中的某些内容,以使我在返回HttpResponse之后不自动设置响应标头,要么有可能返回其他对象,从而不必手动设置标头。在写HttpResponse之后无法得知试图设置标头的原因,我不确定如何继续。
答案 0 :(得分:0)
为什么不只在写响应之前写标题?甚至更好:为什么不手动设置响应,为什么不将返回声明为更抽象的东西,然后让框架处理呢?
无论如何,这是一段有关如何添加自定义标头的代码:
using System;
using System.Linq;
using System.Net;
using Microsoft.AspNetCore.Mvc;
namespace WebApplication.Controllers
{
[Route("api")]
public class ValuesController : Controller
{
[HttpGet]
[Route("values/{top}")]
public IActionResult Get(int top)
{
// Generate dummy values
var list = Enumerable.Range(0, DateTime.Now.Second)
.Select(i => $"Value {i}")
.ToList();
list.Reverse();
var result = new ObjectResult(list.Take(top))
{
StatusCode = (int)HttpStatusCode.OK
};
Request.HttpContext.Response.Headers.Add("X-Total-Count", list.Count.ToString());
return result;
}
}
}