Установка Content-Type пустого ответа в ASP.NET MVC - PullRequest
5 голосов
/ 27 декабря 2010

Для поддержки унаследованного приложения, которое находится в поле, мне нужно, чтобы мое приложение ASP.NET MVC возвращало пустой ответ, который также имеет Content-Type. Один из IIS, ASP.NET или ASP.NET MVC удаляет мой Content-Type, когда я возвращаю нулевой ответ. Есть ли способ обойти это?

(Хотя не требуется пустой ответ с набором Content-Type, очевидно, было бы идеальным решением, клиенты уже существуют, и многие из них не могут быть обновлены.)

РЕДАКТИРОВАТЬ : Поскольку был запрос на код: я передаю запрос от нового веб-приложения на то, на которое полагаются более старые клиенты. Для этого у меня есть подкласс ActionResult, называемый LegacyResult, который вы можете просто вернуть для тех методов, которые должны обрабатываться старым программным обеспечением. Это соответствующая часть его кода:

    public override void ExecuteResult(ControllerContext context)
    {
        using (var legacyResponse = GetLegacyResponse(context))
        {
            var clientResponse = context.HttpContext.Response;
            clientResponse.Buffer = false;
            clientResponse.ContentType = legacyResponse.ContentType; /* Yes, I checked that legacyResponse.ContentType is never string.IsNullOrEmpty */
            if (legacyResponse.ContentLength >= 0) clientResponse.AddHeader("Content-Length", legacyResponse.ContentLength.ToString());

            var legacyInput = legacyResponse.GetResponseStream();
            using (var clientOutput = clientResponse.OutputStream)
            {
                var rgb = new byte[32768];
                int cb;
                while ((cb = legacyInput.Read(rgb, 0, rgb.Length)) > 0)
                {
                    clientOutput.Write(rgb, 0, cb);
                }
                clientOutput.Flush();
            }
        }
    }

Если legacyInput имеет данные, тогда Content-Type устанавливается соответствующим образом. В противном случае это не так. Я действительно могу использовать старый бэкэнд для отправки пустого v. Непустого ответа на точно такой же запрос и наблюдать разницу в Fiddler.

РЕДАКТИРОВАТЬ 2 : Возмущение с помощью Reflector показывает, что, если заголовки не были записаны во время вызова HttpResponse.Flush, то Flush записывает сами заголовки. Проблема в том, что он записывает только крошечное подмножество заголовков. Один из пропавших без вести - Content-Type. Похоже, что если я смогу принудительно вывести заголовки в поток, я смогу избежать этой проблемы.

1 Ответ

8 голосов
/ 28 декабря 2010

Вы должны обмануть ответ, написав заголовки, ложно сообщив, что контент есть, затем подавив его :

/// [inside the writing block]
var didWrite = false;
while ((cb = legacyInput.Read(rgb, 0, rgb.Length)) > 0)
{
  didWrite = true;
  clientOutput.Write(rgb, 0, cb);
}
if (!didWrite)
{
  // The stream needs a non-zero content length to write the correct headers, but...
  clientResponse.AddHeader("Content-Length", "1");
  // ...this actually writes a "Content-Length: 0" header with the other headers.
  clientResponse.SuppressContent = true;
}
...