Заголовки являются исключением только для чтения при записи в HttpResponse - PullRequest
0 голосов
/ 31 октября 2018

У меня есть контроллер, который выглядит так

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, я не уверен, как поступить.

1 Ответ

0 голосов
/ 31 октября 2018

Почему бы вам просто не написать свои заголовки, прежде чем писать ответ? и даже лучше: вместо того, чтобы вручную устанавливать ответ, почему бы вам не объявить возвращение как нечто более абстрактное и позволить фреймворку разобраться с этим?

В любом случае, здесь фрагмент кода о том, как добавить пользовательские заголовки:

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;
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...