Parfois, je reçois une exception dans mon environnement de production:
- Traitement de l'information
- ID de processus: 3832
- Nom du processus: w3wp.exe
- Nom du compte: NT AUTHORITY\NETWORK SERVICE
- Informations sur les exceptions
- Type d'exception: System.Web.HttpException
- Message d'exception: Le serveur ne peut pas définir l'état après l'envoi des en-têtes HTTP.
- Informations requises
- URL de la demande: http://www.myulr.pl/logon
- Chemin de la demande:/logon
- Adresse de l'hôte utilisateur: 10.11.9.1
- Utilisateur: user001
- Est authentifié: True
- Type d'authentification: Formulaires
- Nom du compte de fil: NT AUTHORITY\NETWORK SERVICE
- Informations sur le fil
- ID de fil: 10
- Nom du compte de fil: NT AUTHORITY\NETWORK SERVICE
- Se fait passer pour: Faux
Stack trace: at System.Web.HttpResponse.set_StatusCode(Int32 value) at
System.Web.HttpResponseWrapper.set_StatusCode(Int32 value) at
System.Web.Mvc.HandleErrorAttribute.OnException(ExceptionContext filterContext) at
System.Web.Mvc.ControllerActionInvoker.InvokeExceptionFilters(ControllerContext controllerContext, IList(1) filters, Exception exception) at
System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) at System.Web.Mvc.Controller.ExecuteCore() at
System.Web.Mvc.MvcHandler.<>c__DisplayClass8.<BeginProcessRequest>b__4() at
System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass1.<MakeVoidDelegate>b__0() at
System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass8(1).<BeginSynchronous>b__7(IAsyncResult _) at
System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult(1).End() at
System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) at
System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() at
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& ompletedSynchronously)
Je n'ai pas remarqué cette erreur sur mon environnement de test. Que dois-je vérifier?
J'utilise ASP.NET MVC 2 (Release Candidate 2)
Je suis largement d'accord avec Vagrant sur la cause:
Si je ne suis pas d’accord avec Vagrant, c’est le remède "ne créez aucune erreur de liaison" - vous pouvez toujours rencontrer des erreurs d’exécution dans View binding, par exemple exceptions de référence nulles.
Une meilleure solution consiste à s'assurer que Response.BufferOutput = true;
avant tout octet est envoyé au flux de réponse. par exemple. dans votre action de contrôleur ou On_Begin_Request dans l'application. Cela permet de définir les transferts de serveur, les cookies/en-têtes, etc. jusqu'à la réponse se terminant naturellement, ou l'appelant la fin/le vidage.
Bien sûr, vérifiez également que la mémoire tampon n'est pas vidée/définie sur false plus loin dans la pile.
Référence MSDN: HttpResponse.BufferOutput
Juste pour ajouter aux réponses ci-dessus. J'ai eu le même problème quand j'ai commencé à utiliser ASP.Net MVC et que je faisais Response.Redirect lors d'une action du contrôleur:
Response.Redirect("/blah", true);
Au lieu de renvoyer une action Response.Redirect
, j'aurais dû renvoyer une RedirectAction
:
return Redirect("/blah");
Le serveur HTTP n'envoie pas l'en-tête de réponse au client jusqu'à ce que vous spécifiiez une erreur ou que vous commenciez à envoyer des données. Si vous commencez à renvoyer des données au client, le serveur doit d'abord envoyer l'en-tête de la réponse (qui contient le code d'état). Une fois que l'en-tête a été envoyé, vous ne pouvez évidemment plus insérer de code d'état dans l'en-tête.
Voici le problème habituel. Vous démarrez la page et envoyez des balises initiales (c'est-à-dire <head>
). Le serveur envoie ensuite ces balises au client, après avoir d'abord envoyé l'en-tête de réponse HTTP avec un statut supposé SUCCESS. Maintenant, vous commencez à travailler sur la viande de la page et découvrez un problème. Vous ne pouvez pas envoyer d'erreur à ce stade car l'en-tête de la réponse, qui contiendrait le statut de l'erreur, a déjà été envoyé.
La solution est la suivante: Avant de générer du contenu, vérifiez s'il y a des erreurs. Alors seulement, quand vous aurez la certitude qu'il n'y aura pas de problèmes, vous pourrez alors envoyer du contenu, comme le tag.
Dans votre cas, il semble que vous ayez une page de connexion qui traite une demande POST à partir d'un formulaire. Vous jetez probablement du code HTML initial, puis vérifiez si le nom d'utilisateur et le mot de passe sont valides. Au lieu de cela, vous devez d'abord authentifier l'utilisateur/mot de passe avant de générer any HTML.
J'ai eu le même problème avec la définition de StatusCode
et ensuite Response.End
dans la méthode HandleUnauthorizedRequest
de AuthorizeAttribute
var ctx = filterContext.HttpContext;
ctx.Response.StatusCode = (int)HttpStatusCode.Forbidden;
ctx.Response.End();
Si vous utilisez .NET 4.5+, ajoutez cette ligne avant Response.StatusCode
filterContext.HttpContext.Response.SuppressFormsAuthenticationRedirect = true;
Si vous utilisez .NET 4.0, essayez SuppressFormsAuthenticationRedirectModule .
Pourquoi ne pas vérifier ceci avant de faire la redirection:
if (!Response.IsRequestBeingRedirected)
{
//do the redirect
}
Vous essayez en réalité de rediriger une page qui a une réponse à jeter. Donc, tout d’abord, vous conservez les informations que vous avez jetées dans un tampon en utilisant response.buffer = true
au début de la page, puis vous le videz si nécessaire en utilisant response.flush
.
Je me souviens de la partie de cette exception: "Impossible de modifier les informations d'en-tête - les en-têtes déjà envoyés par" apparaissant en PHP. Il s’est produit lorsque les en-têtes ont déjà été envoyés dans la phase de redirection et que toute autre sortie a été générée, par exemple:
echo "hello"; header ("Location: http://stackoverflow.com ");
Excusez-moi et corrigez-moi si je me trompe, mais j'apprends toujours MS Technologies et j'essayais d'aider.
Je m'excuse, mais j'ajoute mes 2 centimes au fil juste au cas où quelqu'un aurait le même problème.
return new HttpStatusCodeResult(401)
- et ASP.NET est super sympa de le détecter, et cela redirige l'utilisateur vers la page de connexion! Magie, c'est ça? Il a même le paramètre ReturnUrl
approprié, etc.Mais vous voyez où je vais ici? I retour 401 . Et ASP.NET redirige l'utilisateur. Ce qui est essentiellement retourne 302. Un code d'état est remplacé par un autre.
Et certains IIS serveurs (quelques-uns seulement) lèvent cette exception. Certains non. - Je ne l'ai pas sur mon test serevr, seulement sur mon serveur de production (n'est-ce pas toujours le cas juste o_O)
Je sais que ma réponse consiste essentiellement à répéter ce qui a déjà été dit ici, mais il est parfois difficile de savoir exactement où se produit cet écrasement.
Nous obtenions la même erreur - cela peut donc être utile à certains.
Pour nous la cause était super simple. Un changement d'interface a dérouté l'utilisateur final qui appuyait sur le bouton Précédent du navigateur à un «mauvais moment» après la soumission d'un formulaire (nous aurions probablement dû utiliser un modèle PRG, mais ce n'est pas le cas).
Nous avons résolu le problème et l’utilisateur n’appuie plus sur le bouton Précédent. Problème résolu.
Si quelqu'un a toujours ce problème.Essayez d'utiliser au lieu de trop faire
public void OnActionExecuting(ActionExecutingContext context)
{
try
{
if (!HttpContext.Current.User.Identity.IsAuthenticated)
{
if (!HttpContext.Current.Response.IsRequestBeingRedirected)
{
context.Result = new RedirectToRouteResult(
new RouteValueDictionary { { "controller", "Login" }, { "action", "Index" } });
}
}
}
catch (Exception ex)
{
new RouteValueDictionary { { "controller", "Login" }, { "action", "Index" } });
}
}