Kann der Content-Type-Header nicht für HttpResponseMessage-Header festgelegt werden?

75

Ich verwende ASP.NET WebApi, um eine RESTful-API zu erstellen. Ich erstelle eine PUT-Methode in einem meiner Controller, und der Code sieht folgendermaßen aus:

public HttpResponseMessage Put(int idAssessment, int idCaseStudy, string value) {
    var response = Request.CreateResponse();
    if (!response.Headers.Contains("Content-Type")) {
        response.Headers.Add("Content-Type", "text/plain");
    }

    response.StatusCode = HttpStatusCode.OK;
    return response;
}

Wenn ich mit dem Browser über AJAX an diesen Ort schiebe, gibt es diese Ausnahme:

Missbrauchter Headername. Stellen Sie sicher, dass Anforderungsheader mit HttpRequestMessage, Antwortheader mit HttpResponseMessage und Inhaltsheader mit HttpContent-Objekten verwendet werden.

Aber ist ein nicht Content-Typeganz gültiger Header für eine Antwort nicht? Warum bekomme ich diese Ausnahme?

Jez
quelle

Antworten:

115

Schauen Sie sich die Eigenschaft HttpContentHeaders.ContentType an :

response.Content.Headers.ContentType = new MediaTypeHeaderValue("text/plain");

if (response.Content == null)
{
    response.Content = new StringContent("");
    // The media type for the StringContent created defaults to text/plain.
}
dtb
quelle
1
Was ist, wenn die Antwort keinen Inhalt hat (also .Contentnull ist)? Ich möchte den Content-Type-Header setzen, obwohl kein Inhalt vorhanden ist. Andernfalls beschwert sich Firefox mit dem Fehler "Kein Element gefunden".
Jez
Sie können auch versuchen, Einstellungen vorzunehmen, response.StatusCode = HttpStatusCode.NoContentanstatt das Headerfeld Inhaltstyp hinzuzufügen.
dtb
1
Cool, der Dummy hat response.Content = new StringContent("");funktioniert. Ich frage mich immer noch, warum es response.Headersüberhaupt existiert.
Jez
Für die Header, die nicht in ContentBeziehung stehen.
dtb
5
Das ist einfach lächerlich. Ich bin so froh, dass WebApi fertig ist. Es lebe MVC.
Chris Marisic
1

In der ASP-Web-API fehlt etwas: der EmptyContentTyp. Es ermöglicht das Senden eines leeren Körpers, während weiterhin alle inhaltsspezifischen Header zulässig sind.

Fügen Sie die folgende Klasse irgendwo in Ihren Code ein:

public class EmptyContent : HttpContent
{
    protected override Task SerializeToStreamAsync(Stream stream, TransportContext context)
    {
        return Task.CompletedTask;
    }
    protected override bool TryComputeLength(out long length)
    {
        length = 0L;
        return true;
    }
}

Dann benutze es wie du willst. Sie haben jetzt ein Inhaltsobjekt für Ihre zusätzlichen Header.

response.Content = new EmptyContent();
response.Content.Headers.LastModified = file.DateUpdatedUtc;

Warum EmptyContentstatt verwenden new StringContent(string.Empty)?

  • StringContentist eine schwere Klasse, die viele Codes ausführt (weil sie erbt ByteArrayContent)
    • Sparen wir also ein paar Nanosekunden
  • StringContent fügt einen zusätzlichen nutzlosen / problematischen Header hinzu: Content-Type: plain/text; charset=...
    • Speichern wir also ein paar Netzwerkbytes
SandRock
quelle