L'Accès Raw Du Corps De La Requête
J'essaye d'accéder à une demande de brut de l'entrée de carrosserie/flux de ASP.net 5. Dans le passé, j'ai été en mesure de réinitialiser la position du flux d'entrée de 0 et de le lire dans un flux de mémoire, mais lorsque je tente de le faire le contexte le flux d'entrée est soit null ou renvoie une erreur (le Système.NotSupportedException => "méthode Spécifiée n'est pas prise en charge.").
Dans le premier exemple ci-dessous je peux accéder à la demande brute dans un contrôleur, si je déclare la méthode de contrôleur de paramètre du type d'objet dynamique. Pour diverses raisons, ce n'est pas une solution et j'ai besoin d'accéder à la demande brute corps dans un filtre d'authentification, de toute façon.
Que cet Exemple Fonctionne, Mais n'Est Pas une Solution Raisonnable:
[HttpPost("requestme")]
public string GetRequestBody([FromBody] dynamic body)
{
return body.ToString();
}
Déclenche Une Erreur:
[HttpPost("requestme")]
public string GetRequestBody()
{
var m = new MemoryStream();
Request.Body.CopyTo(m);
var contentLength = m.Length;
var b = System.Text.Encoding.UTF8.GetString(m.ToArray());
return b;
}
Déclenche Une Erreur:
[HttpPost("requestme")]
public string GetRequestBody()
{
Request.Body.Position = 0;
var input = new StreamReader(Request.Body).ReadToEnd();
return input;
}
Déclenche Une Erreur:
[HttpPost("requestme")]
public string GetRequestBody()
{
Request.Body.Position = 0;
var input = new MemoryStream();
Request.Body.CopyTo(input);
var inputString = System.Text.Encoding.UTF8.GetString(input.ToArray());
return inputString;
}
J'ai besoin d'accéder à la demande brute corps de chaque demande qui concerne une API que je suis bâtiment.
Toute aide ou une orientation serait grandement apprécié!
EDIT:
Voici le code que je voudrais lire le corps de la requête.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNet.Mvc;
using Microsoft.AspNet.Http;
namespace API.Filters
{
public class CustomAuthorizationAttribute : Attribute, IAuthorizationFilter
{
public CustomAuthorizationAttribute()
{ }
public void OnAuthorization(AuthorizationContext context)
{
if (context == null)
throw new ArgumentNullException("OnAuthorization AuthorizationContext context can not be null.");
else
{
if (this.AuthorizeCore(context.HttpContext) == false)
{
//Do Other Stuff To Check Auth
}
else
{
context.Result = new HttpUnauthorizedResult();
}
}
}
protected virtual bool AuthorizeCore(HttpContext httpContext)
{
var result = false;
using (System.IO.MemoryStream m = new System.IO.MemoryStream())
{
try
{
if (httpContext.Request.Body.CanSeek == true)
httpContext.Request.Body.Position = 0;
httpContext.Request.Body.CopyTo(m);
var bodyString = System.Text.Encoding.UTF8.GetString(m.ToArray());
return CheckBody(bodyString); //Initial Auth Check returns true/false <-- Not Shown In Code Here on Stack Overflow
}
catch (Exception ex)
{
Logger.WriteLine(ex.Message);
}
}
return false;
}
}
}
Le code pourrait être accessibles lorsqu'un appel est effectué à une méthode de contrôleur marqué avec le CustomAuthorization attribut comme si.
[Filters.CustomAuthorizationAuthorization]
[HttpPost]
public ActionResult Post([FromBody]UserModel Profile)
{
//Process Profile
}
j'ai besoin d'accéder à la demande brute corps dans un filtre d'authentification de toute façon ... ce q&a peut vous être utile stackoverflow.com/q/31464359/571637
l'erreur est le haut de mon post de son Système.NotSupportedException Message -> "méthode Spécifiée n'est pas prise en charge."
OriginalL'auteur Badger Dev | 2015-07-28
Vous devez vous connecter pour publier un commentaire.
La mise en œuvre de
Request.Body
dépend de l'action du contrôleur.Si le script contient des paramètres, il est mis en œuvre par
Microsoft.AspNet.WebUtilities.FileBufferingReadStream
, qui prend en charge la recherche (Request.Body.CanSeek == true
). Ce type prend également en charge le réglage de laRequest.Body.Position
.Toutefois, si votre action ne contient pas de paramètres, il est mis en œuvre par
Microsoft.AspNet.Loader.IIS.FeatureModel.RequestBody
, qui ne pas soutien à la recherche (Request.Body.CanSeek == false
). Cela signifie que vous ne pouvez pas régler lePosition
propriété et vous pouvez juste commencer à lire le flux.Cette différence a probablement à voir avec le fait que MVC besoin d'extraire les valeurs des paramètres à partir de la demande du corps, par conséquent, il convient de lire la demande.
Dans votre cas, votre action n'a pas de paramètres. Ainsi, le
Microsoft.AspNet.Loader.IIS.FeatureModel.RequestBody
est utilisé, ce qui lève une exception si vous essayez de définir laPosition
propriété.Solution: ne pas régler la position ou vérifier si vous avez réellement peut définir d'abord la position:
pouvez-vous montrer le code dans le filtre? Et ce d'exception-vous recevoir?
C'est une réponse intéressante, si vous êtes en supposant que l'OP est à l'aide de IIS. Les mêmes remarques peuvent en effet s'appliquer à tous les cours d'eau de l'hôte comme IIS ou WebListener.
Je suis d'hébergement de la dernière application sur IIS 8.5 dans un DNX. Cela pourrait changer à un certain point, que les choses peuvent être fluide autour d'ici. @HenkMollema j'ai édité le post original pour inclure un exemple de code que je veux lancer. J'ai essayé votre exemple mais pour une raison quelconque, le débogueur en VS 2015 est juste sauter sur elle.
Juste une suite. Il n'a pas d'importance si la demande comporte des paramètres ou pas. Je n'ai pas vu une demande de venir où je peux régler la position de la rivière et à chaque requête lorsque j'ai essayé de lire le flux indépendamment de sa position, le flux est essentiellement vide. Il y a quelque chose dans le Réseau de pipelines qui est de la vidange de la diffuser ou de ne pas la copie de retour le flux après il travaille avec elle.
OriginalL'auteur Henk Mollema
Les exceptions que vous voyez dans vos trois derniers extraits sont la conséquence directe d'essayer de lire le corps de la requête plusieurs fois - une fois par MVC 6 et une fois dans votre code personnalisé - lors de l'utilisation d'une diffusion en continu de l'hôte comme IIS ou WebListener. Vous pouvez voir ce DONC, la question pour plus d'informations: Lire corps deux fois dans Asp.Net 5.
Cela dit, j'avais seulement s'attendre à ce que cela arrive lors de l'utilisation de
application/x-www-form-urlencoded
, car il ne serait pas sans danger pour MVC pour lancer la lecture de la demande de flux avec de longues requêtes comme les uploads de fichier. Si ce n'est pas le cas, alors c'est probablement un MVC bug que vous devriez rapport sur https://github.com/aspnet/Mvc.Pour les solutions, vous devriez jeter un oeil à cette SORTE de réponse, qui explique comment vous pouvez utiliser
context.Request.ReadFormAsync
ou ajouter manuel de mise en mémoire tampon: Lire corps deux fois dans Asp.Net 5OriginalL'auteur Pinpoint
J'ai juste eu ce même problème. Supprimer les paramètres de la signature de la méthode, et ensuite de lire les
Request.Body
Flux de la façon dont vous voulez.OriginalL'auteur joe
Vous avez besoin de Demande d'appel.EnableRewind() pour permettre le flux de rembobinage de sorte que vous pouvez le lire.
OriginalL'auteur Steve Peirce