web-dev-qa-db-fra.com

Impossible de définir l'en-tête Content-Type sur les en-têtes HttpResponseMessage?

J'utilise ASP.NET WebApi pour créer une API RESTful. Je crée une méthode PUT dans l'un de mes contrôleurs, et le code ressemble à ceci:

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;
}

Quand je passe à cet endroit avec le navigateur via AJAX, cela me donne cette exception:

Nom d'en-tête mal utilisé. Assurez-vous que les en-têtes de requête sont utilisés avec HttpRequestMessage, les en-têtes de réponse avec HttpResponseMessage et les en-têtes de contenu avec des objets HttpContent.

Mais n'est pas Content-Type un en-tête parfaitement valide pour une réponse? Pourquoi ai-je cette exception?

68
Jez

Jetez un coup d'œil à la propriété HttpContentHeaders.ContentType Property :

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.
}
108
dtb

Il manque quelque chose dans ASP API Web: le type EmptyContent. Il permettra d'envoyer un corps vide tout en autorisant tous les en-têtes spécifiques au contenu.

Mettez la classe suivante quelque part dans votre code:

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;
    }
}

Ensuite, utilisez-le comme vous le souhaitez. Vous avez maintenant un objet de contenu pour vos en-têtes supplémentaires.

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

Pourquoi utiliser EmptyContent au lieu de new StringContent(string.Empty)?

  • StringContent est une classe lourde qui exécute beaucoup de codes (car elle hérite de ByteArrayContent )
    • alors économisons quelques nanosecondes
  • StringContent ajoutera un en-tête inutile/problématique: Content-Type: plain/text; charset=...
    • alors sauvons quelques octets du réseau
0
SandRock