ASP.NET MVC 3: le Serveur ne peut pas ajouter l'en-tête après les en-têtes HTTP ont été envoyés
Nous sommes occupés de la mise à niveau d'un ASP.NET MVC 2 Application à l'aide du framework 3.5 pour un ASP.NET MVC 3 Application en cours d'exécution sur le framework 4.0.
Il y a une page qui déclenche une exception lorsqu'il est sollicité en utilisant le bouton précédent du navigateur. Pour appuyer le bouton précédent du navigateur sur cette page, nous avons mis en place un système qui demande les résultats de la page à nouveau lors de l'arrivée de nouveau sur la page. Je n'ai pas d'indications claires où chercher le problème, toutefois, depuis que je suis toujours seul à trouver l'erreur
Server cannot append header after HTTP headers have been sent.
Avec stacktrace
at System.Web.HttpResponse.AppendHeader(String name, String value)
at System.Web.HttpResponseWrapper.AppendHeader(String name, String value)
at System.Web.Mvc.MvcHandler.AddVersionHeader(HttpContextBase httpContext)
at System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext, IController& controller, IControllerFactory& factory)
at System.Web.Mvc.MvcHandler.<>c__DisplayClass6.<BeginProcessRequest>b__2()
at System.Web.Mvc.SecurityUtil.<>c__DisplayClassb`1.<ProcessInApplicationTrust>b__a()
at System.Web.Mvc.SecurityUtil.<GetCallInAppTrustThunk>b__0(Action f)
at System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action action)
at System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust[TResult](Func`1 func)
at System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state)
at System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state)
at System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData)
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
Comment se les en-têtes HTTP ont déjà été envoyés?
Vous en remercie d'avance,
IvanL
EDIT:
Je suis de l'ajout de nouvelles informations et idées que j'ai acquise pendant la chasse pour ce problème. Le Asynch Contrôleur mention de l'une des réponses que m'a demande. Quand j'ai découvert que je devais changer les données suivantes pour le vieux MVC2 méthode de travail:
[HttpPost, ValidateInput(false)]
public void SearchResultOverview(SearchResultViewModel model, string searchUrl)
{
if (!string.IsNullOrEmpty(searchUrl))
{
searchUrl = searchUrl.Replace("SearchPartial", "SearchPartialInternal");
//NOTE MVC 3
HttpContext.Server.TransferRequest(searchUrl, true);
//NOTE MVC 2
//System.Web.HttpContext.Current.RewritePath(searchUrl, false);
//IHttpHandler httpHandler = new MvcHttpHandler();
////Process request
//httpHandler.ProcessRequest(System.Web.HttpContext.Current);
}
}
Quand j'ai regardé la TransferRequest méthode, j'ai trouvé qu'il Performs an asynchronous execution of the specified URL and preserves query string parameters.
( http://msdn.microsoft.com/en-us/library/system.web.httpserverutility.transferrequest.aspx )
Il y a aussi une Exception levée avant l'exception que j'ai posté (j'ai simplement manqué de il depuis que j'ai intercepté la fin de l'exception). Cette exception est:
The SessionStateTempDataProvider class requires session state to be enabled.
at System.Web.Mvc.SessionStateTempDataProvider.SaveTempData(ControllerContext controllerContext, IDictionary`2 values)
at System.Web.Mvc.TempDataDictionary.Save(ControllerContext controllerContext, ITempDataProvider tempDataProvider)
at System.Web.Mvc.Controller.PossiblySaveTempData()
at System.Web.Mvc.Controller.ExecuteCore()
at System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext)
at System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext)
at System.Web.Mvc.MvcHandler.<>c__DisplayClass6.<>c__DisplayClassb.<BeginProcessRequest>b__5()
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.<>c__DisplayClasse.<EndProcessRequest>b__d()
at System.Web.Mvc.SecurityUtil.<GetCallInAppTrustThunk>b__0(Action f)
at System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action action)
at System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult)
at System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result)
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
Alors, comment dois-je faire ce travail?
Peut-être cela va aider: stackoverflow.com/questions/2383169/...
L'homme: C'est exactement le point. Je ne suis pas en ajoutant tout les en-têtes de moi-même, il semble que le changement de MVC2 à MVC3 créé ce problème étant donné que le code fonctionne très bien sans aucune exception dans MVC2. Si vous regardez dans le stacktrace vous avis:
at System.Web.Mvc.MvcHandler.AddVersionHeader(HttpContextBase httpContext)
qui signifie MVC lui-même est d'essayer d'ajouter un en-tête, mais il ne peut pas. J'ai essayé la solution de la question que vous me lie avec reponse.BufferOutput = true
mais il ne fonctionne pas. Je reçois toujours de cette exception et stacktrace.Pourquoi êtes-vous créer un nouveau HttpHandler à l'intérieur d'une méthode d'action?
Salon de coiffure: Cela a été fait pour gérer de grandes Url. La chaîne searchUrl est l'URL réelle, mais il est tellement grand que certains navigateurs refusent de travailler avec elle. Pour contourner cela, l'URL a été effectivement publié et traitées en interne. Dans MVC 2 cela a été fait par le tir d'un nouveau requesthandler et de le laisser gérer l'URL réelle, depuis MVC 3 ce n'est plus possible et la solution que j'ai trouvé pour cela est d'utiliser
Server.TransferRequest()
. Il semble cependant que cette méthode ne fonctionne pas lorsqu'il est sollicité par le bouton précédent du navigateur... (il fonctionne parfaitement lorsque la page est régulièrement chargé)
OriginalL'auteur IvanL | 2011-12-14
Vous devez vous connecter pour publier un commentaire.
Cela peut se produire si la mémoire tampon a été désactivée sur la page. Mise en mémoire tampon signifie que asp.net attend pour l'ensemble de la demande pour être achevé avant l'envoi de la réponse. Cela signifie que l'en-tête peut être modifié à tout moment. Lorsque la mémoire tampon est désactivé, la sortie est envoyée au client, car il est généré. Vous ne pouvez donc modifier les en-têtes à volonté, comme ils l'ont déjà été envoyés.
De votre stacktrace, il semble être un contrôleur async & je me demande si cela a quelque chose à faire avec elle. Je suis seulement deviner à partir de ce que vous avez posté.
Mise à jour
Correction, la async mention est réellement cadre code & rien à voir avec votre code. Cependant à partir de votre code ci-dessus, est
SearchResultOverview
une action sur un contrôleur? Si oui, alors en utilisant les méthodes que vous utilisez pour transférer l'exécution est, je pense, la cause de vos problèmes.Elle causant 2 mvchandlers pour exécuter & ils interfèrent les uns avec les autres. Routage serait une meilleure façon de rediriger la requête.
En effet, j'ai eu tort à propos de l'asynchrone. MVC 3 s'occupe de tout. Il avait un cadre de chose, pas votre code. J'
OriginalL'auteur Simon Halsey
Bonnes nouvelles, aujourd'hui, j'ai résolu mon problème après plus d'une recherche approfondie sur la cause de l'exception. Le premier lien qui m'a aidé à comprendre ce qu'est exactement peut-être la cause de mon exceptions et des erreurs est la suivante: http://www.eggheadcafe.com/tutorials/asp-net/79c73563-408a-493e-a369-d4b380bce549/aspnet-using-servertransferrequest.aspx
Il détaille le fonctionnement du Serveur.TransferRequest et mentionne toutes les importantes mise en garde: Session doit être libéré par la requête principale avant le transfert à l'enfant le demande. Creuser plus profond dans la façon dont je voudrais faire cela avec MVC, je suis tombé sur le post suivant, ici sur stackoverflow: Comment simuler Serveur.Transfert en ASP.NET MVC?
Ce post, à son tour, m'a signalé une question très importante à savoir:
throw new ApplicationException("TempData won't work with Server.TransferRequest!");
j'ai Donc créé le TransferResult classe qui peut être trouvé dans ce post et de laisser les actions qui en font la demande de retour via ce point. J'ai trouvé maintenant que cette exception a été frappé dans le cas précis je l'ai mentionné avant. J'ai moi-même jamais utilisé TempData mais apparemment, un de mes collègues l'a fait.En raison de la nature de l'importance des données à l'intérieur, j'ai décidé de
Clear()
la TempData avant toutServer.TransferRequest()
qui fait mon exceptions et des problèmes de fondre comme neige au soleil.Je tiens à remercier toutes les personnes qui ressemblait à résoudre ce problème et je suis heureux que je peux fournir une clôture de la conclusion et de la solution de sorte qu'il peut profiter à ceux qui cherchent à le même problème.
Sincèrement, IvanL
Comme mentionné ci-dessus l'état de la session doit être libéré et tempdata semble pour "verrouiller" la session, vous rendant incapable de transmettre la demande.
merci pour la réponse
OriginalL'auteur IvanL
Je me souviens avoir eu ce problème il y a quelques temps. Je ne me souviens pas des termes exacts, mais il avait quelque chose à voir avec la définition des en-têtes et le code d'état http directement à l'intérieur d'une action personnalisée filtre.
Mon objectif à l'époque était de montrer une page personnalisée/message lors de l'authentification de l'utilisateur a expiré et cliqué sur un ajax lien d'action (comme lorsqu'il laisse la page ouverte pendant un moment puis il revient et clique sur le lien), donc asp.net mvc n'a pas montré la valeur par défaut de la page de login à l'intérieur d'un div (un peu moche). Je n'ai pas le code sous la main en ce moment, mais c'était quelque chose comme ceci:
Le truc, c'est d'essayer de ce même code sur une version antérieure de asp.net mvc m'a donné le "impossible d'ajouter l'en-tête" erreur. Je ne me souviens pas comment je l'ai corrigé, mais ce n'était pas facile de toute façon. Je peux rechercher par le biais de mes vieux projets pour le code fixe si vous pensez que ce cas s'applique à vous.
Espère que cela aide
Je suis confronté au même problème. La seule différence est que j'ai la logique dans OnActionExecuted. Auriez-vous l'esprit de partage de la réparer?
Je ne l'ai pas, il est perdu dans le temps... mais la clé est de définir le résultat directement, comme ceci par exemple: filterContext.Résultat = new HttpUnauthorizedResult();
Le downvote est probablement parce que votre réponse n'est pas une réponse. "J'ai eu ce problème, mais je ne me souviens pas comment résoudre le problème". Wat.
OriginalL'auteur Francisco