Question

Quelle est la meilleure façon de cloner l'instance HttpContext de la demande actuelle?

Je développe une application Asp.net MVC v1 . Je mis à jour les capacités de PartialView régulières pour avoir fait des sous-contrôleurs qui agissent très semblables, mais qui ont leur propre contexte. Lorsque vous utilisez PartialViews vous devez remplir les données pour la vue partielle dans l'action du contrôleur de votre point de vue principal. J'ai créé ma propre fonctionnalité qui permet d'appeler des actions de contrôleur à partir d'une vue. De cette façon, je reçois:

  • Je n'ai pas de fournir les données de sous-vue dans l'action du contrôleur de mon point de vue principal
  • sous méthodes de régulation peut manipuler des données plus encapsulés sans aucune relation avec d'autres affichages / contrôleurs

Le problème est que chaque demande de sous-contrôleur utilise HttpContext. Alors, quand je plaçai quelques-uns HttpContext.Item dans un sous-contrôleur, il remplit effectivement HttpContext de la demande réelle.

Voilà pourquoi je veux cloner HttpContext. J'utilise déjà:

HttpContext subContext = new HttpContext(request, response);
// what happened to Session, User, Items etc. properties?

mais cela ne fixe rien d'autre que la demande et la réponse. Mais je serais probablement aussi besoin d'autres propriétés et collections ... Comme session, Articles, utilisateur ... etc.

Était-ce utile?

La solution 2

Pas possible

Je suppose que le clonage d'un profond réel est impossible en raison de l'état de session du serveur. Le clonage devrait également cloner cette valeur, qui est la ressource interne spécifique du serveur Web qui est intrinsèquement statique et ne peut pas être cloné. Dans ce cas, un serveur web aurait plusieurs objets de session, par exemple.

Solution En tous cas. La solution a été de définir des valeurs de contexte supplémentaires avant l'instanciation traitement de sous-contrôleur. Une fois le traitement terminé, je revins des valeurs Retour à l'original. Donc je contexte avais fait comme avant.

Autres conseils

Alors que le « impossible » réponse est correcte, il existe une alternative qui est beaucoup plus propre que l'écriture de valeurs dans le contexte actuel, puis réécrire à son état d'origine. La solution est de faire un nouvel objet HttpContext qui est entièrement basé sur l'URL de votre choix.

// A new request/response is constructed to using a new URL.
// The new response is using a StreamWriter with null stream as a backing stream 
// which doesn't consume resources

using (var nullWriter = new StreamWriter(Stream.Null))
{
    var newRequestUri = new Uri("http://www.somewhere.com/some-resource/");
    var newRequest = new HttpRequest("", newRequestUri.ToString(), newRequestUri.Query);

    var newResponse = new HttpResponse(nullWriter);
    var newContext = new HttpContextWrapper(new HttpContext(newRequest, newResponse));

    // Work with the new context here before it is disposed...
} 

Référence: https://github.com/maartenba/MvcSiteMapProvider/issues/ 278 # issuecomment-34905271

Le framework ASP.NET MVC fait intentionnellement des dépendances aux classes abstraites avec tous les membres virtuels. Cela dit simplement -. Sous la Extensibilité

Les contrôleurs dépendent HttpContextBase, non HttpContext. Peut-être que vous pouvez faire vos sous-contrôleurs dépendent HttpContextBase trop pour que vous puissiez l'envelopper. Juste mes 2 cents.

Je l'ai utilisé

<% Html.RenderAction("Action", "Controller"); %>

à grand effet, me permettant de créer complètement des actions isolées / escapsulated sans avoir recours à un code complexe. Cela semble offrir les mêmes fonctionnalités sans la même complexité.

Les vues rendus sont des vues partielles standard et les actions du contrôleur comme tout autre.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top