Comment ajouter et obtenir des valeurs d'en-tête dans WebApi

99

Je dois créer une méthode POST dans WebApi pour pouvoir envoyer des données de l'application à la méthode WebApi. Je ne parviens pas à obtenir la valeur de l'en-tête.

Ici, j'ai ajouté des valeurs d'en-tête dans l'application:

 using (var client = new WebClient())
        {
            // Set the header so it knows we are sending JSON.
            client.Headers[HttpRequestHeader.ContentType] = "application/json";

            client.Headers.Add("Custom", "sample");
            // Make the request
            var response = client.UploadString(url, jsonObj);
        }

En suivant la méthode de publication WebApi:

 public string Postsam([FromBody]object jsonData)
    {
        HttpRequestMessage re = new HttpRequestMessage();
        var headers = re.Headers;

        if (headers.Contains("Custom"))
        {
            string token = headers.GetValues("Custom").First();
        }
    }

Quelle est la méthode correcte pour obtenir les valeurs d'en-tête?

Merci.

AndrewRalon
la source

Réponses:

186

Du côté de l'API Web, utilisez simplement l'objet Request au lieu de créer un nouveau HttpRequestMessage

     var re = Request;
    var headers = re.Headers;

    if (headers.Contains("Custom"))
    {
        string token = headers.GetValues("Custom").First();
    }

    return null;

Production -

entrez la description de l'image ici

ramiramilu
la source
Vous ne pouvez pas utiliser string token = headers.GetValues("Custom").FirstOrDefault();? Edit: Je viens de remarquer que vous correspondiez au style original de Qs.
Aidanapword
Répondre à ma propre Q: Non. Les headers.GetValues("somethingNotFound")lancers un InvalidOperationException.
Aidanapword
Dois-je utiliser beforeSenddans JQuery ajax pour envoyer l'en-tête?
Si8
Parfait ... J'ai utilisé le beforeSendet cela a fonctionné. Awesome :) +1
Si8
quel est le type de la variable Request et puis-je y accéder dans la méthode du contrôleur? J'utilise web api 2. De quel espace de noms ai-je besoin pour importer?
lohiarahul
21

Supposons que nous ayons un contrôleur API ProductsController: ApiController

Il y a une fonction Get qui renvoie une valeur et attend un en-tête d'entrée (par exemple. Nom d'utilisateur et mot de passe)

[HttpGet]
public IHttpActionResult GetProduct(int id)
{
    System.Net.Http.Headers.HttpRequestHeaders headers = this.Request.Headers;
    string token = string.Empty;
    string pwd = string.Empty;
    if (headers.Contains("username"))
    {
        token = headers.GetValues("username").First();
    }
    if (headers.Contains("password"))
    {
        pwd = headers.GetValues("password").First();
    }
    //code to authenticate and return some thing
    if (!Authenticated(token, pwd)
        return Unauthorized();
    var product = products.FirstOrDefault((p) => p.Id == id);
    if (product == null)
    {
        return NotFound();
    }
    return Ok(product);
}

Nous pouvons maintenant envoyer la demande depuis la page en utilisant JQuery:

$.ajax({
    url: 'api/products/10',
    type: 'GET',
    headers: { 'username': 'test','password':'123' },
    success: function (data) {
        alert(data);
    },
    failure: function (result) {
        alert('Error: ' + result);
    }
});

J'espère que cela aide quelqu'un ...

Venugopal M
la source
9

Une autre façon d'utiliser une méthode TryGetValues.

public string Postsam([FromBody]object jsonData)
{
    IEnumerable<string> headerValues;

    if (Request.Headers.TryGetValues("Custom", out headerValues))
    {
        string token = headerValues.First();
    }
}   
Schandlich
la source
6

Pour .NET Core:

string Token = Request.Headers["Custom"];

Ou

var re = Request;
var headers = re.Headers;
string token = string.Empty;
StringValues x = default(StringValues);
if (headers.ContainsKey("Custom"))
{
   var m = headers.TryGetValue("Custom", out x);
}
SaadK
la source
6

Au cas où quelqu'un utilise ASP.NET Core pour la liaison de modèle,

https://docs.microsoft.com/en-us/aspnet/core/mvc/models/model-binding

Il existe une prise en charge intégrée de la récupération des valeurs de l'en-tête à l'aide de l'attribut [FromHeader]

public string Test([FromHeader]string Host, [FromHeader]string Content-Type )
{
     return $"Host: {Host} Content-Type: {Content-Type}";
}
wonster
la source
3
Content-Typen'est pas un identifiant C # valide
thepirat000
5

essayez cette ligne de codes fonctionnant dans mon cas:

IEnumerable<string> values = new List<string>();
this.Request.Headers.TryGetValues("Authorization", out values);
Sufyan Ahmad
la source
5

Comme quelqu'un a déjà indiqué comment faire cela avec .Net Core, si votre en-tête contient un "-" ou un autre caractère interdit par .Net, vous pouvez faire quelque chose comme:

public string Test([FromHeader]string host, [FromHeader(Name = "Content-Type")] string contentType)
{
}
Scott
la source
1

Pour l'API WEB 2.0:

Je devais utiliser Request.Content.Headersau lieu de Request.Headers

puis j'ai déclaré une extestion comme ci-dessous

  /// <summary>
    /// Returns an individual HTTP Header value
    /// </summary>
    /// <param name="headers"></param>
    /// <param name="key"></param>
    /// <returns></returns>
    public static string GetHeader(this HttpContentHeaders headers, string key, string defaultValue)
    {
        IEnumerable<string> keys = null;
        if (!headers.TryGetValues(key, out keys))
            return defaultValue;

        return keys.First();
    }

Et puis je l'ai invoqué de cette façon.

  var headerValue = Request.Content.Headers.GetHeader("custom-header-key", "default-value");

J'espère que ça pourrait être utile

Oscar Emilio Perez Martinez
la source
0

Vous devez obtenir le HttpRequestMessage à partir du OperationContext actuel. En utilisant OperationContext, vous pouvez le faire comme ceci

OperationContext context = OperationContext.Current;
MessageProperties messageProperties = context.IncomingMessageProperties;

HttpRequestMessageProperty requestProperty = messageProperties[HttpRequestMessageProperty.Name] as HttpRequestMessageProperty;

string customHeaderValue = requestProperty.Headers["Custom"];
Jehof
la source
0

Pour .net Core dans la méthode GET, vous pouvez faire comme ceci:

 StringValues value1;
 string DeviceId = string.Empty;

  if (Request.Headers.TryGetValue("param1", out value1))
      {
                DeviceId = value1.FirstOrDefault();
      }
Sharif Yazdian
la source