मैं यहां नवीनतम बिट्स के आधार पर बात कर रहा हूं जो कोडप्लेक्स एएसपी.नेट वेब स्टैक रेपो पर उपलब्ध हैं।
आदेश उपयोगकर्ता द्वारा नियंत्रित किया जाता है और यहां कोई मनमाना आदेश नहीं है। मुझे समझाएं:
मान लें कि हमारे पास दो संदेश हैंडलर हैं: MyMessageHandler
और MyMessageHandler2
। यह मानते हुए कि हम उन्हें नीचे के रूप में रजिस्टर:
protected void Application_Start(object sender, EventArgs e) {
RouteConfig.RegisterRoutes(GlobalConfiguration.Configuration.Routes);
GlobalConfiguration.Configuration.MessageHandlers.Add(new MyMessageHandler());
GlobalConfiguration.Configuration.MessageHandlers.Add(new MyMessageHandler2());
}
क्या तुम यहाँ उम्मीद MyMessageHandler
दूसरे शब्दों फीफो में एक दूसरे के रूप में पहली और MyMessageHandler2
को चलाने के लिए, है।
अगर हम ढांचे के अंदर हुड के नीचे एक छोटा सा देखो, हम उस HttpServer
उदाहरण के Initialize
विधि System.Net.Http.HttpClientFactory
की CreatePipeline
विधि लागू होने पर देखेंगे (जो पहले HttpPipelineFactory.Create
पद्धति के रूप में जाना जाता था के रूप में अली का संकेत मिला।) CreatePipeline
विधि स्वीकार करता है दो पैरामीटर: HttpMessageHandler
और IEnumerable<DelegatingHandler>
। HttpServer.Initialize
विधि System.Web.Http.Dispatcher.HttpControllerDispatcher
HttpMessageHandler
पैरामीटर के लिए पिछले HttpMessageHandler
श्रृंखला और HttpConfiguration.MessageHandlers के लिए IEnumerable<DelegatingHandler>
पैरामीटर के लिए पास हो रही है।
क्या CreatePipeline
विधि के अंदर होता है IMO बहुत चालाक है:
public static HttpMessageHandler CreatePipeline(HttpMessageHandler innerHandler, IEnumerable<DelegatingHandler> handlers)
{
if (innerHandler == null)
{
throw Error.ArgumentNull("innerHandler");
}
if (handlers == null)
{
return innerHandler;
}
// Wire handlers up in reverse order starting with the inner handler
HttpMessageHandler pipeline = innerHandler;
IEnumerable<DelegatingHandler> reversedHandlers = handlers.Reverse();
foreach (DelegatingHandler handler in reversedHandlers)
{
if (handler == null)
{
throw Error.Argument("handlers", Properties.Resources.DelegatingHandlerArrayContainsNullItem, typeof(DelegatingHandler).Name);
}
if (handler.InnerHandler != null)
{
throw Error.Argument("handlers", Properties.Resources.DelegatingHandlerArrayHasNonNullInnerHandler, typeof(DelegatingHandler).Name, "InnerHandler", handler.GetType().Name);
}
handler.InnerHandler = pipeline;
pipeline = handler;
}
return pipeline;
}
आप देख सकते हैं, संदेश हैंडलर क्रम उलट है और Matryoshka doll बनाया है, लेकिन यहाँ सावधान रहना है: यह सुनिश्चित किया जाता है HttpControllerDispatcher
है कि चेन के अंदर चलाने के लिए अंतिम संदेश हैंडलर।
दो बार कॉल करने के लिए, यह वास्तव में काफी सच नहीं है। संदेश हैंडलर को दो बार नहीं कहा जाएगा, दूसरी तरफ जारी रखने वाली निरंतरता विधि होगी। ऐसा करने के लिए आप पर निर्भर है। यदि आप कॉलबैक प्रदान करते हैं (दूसरे शब्दों में निरंतरता में), तो आपके संदेश हैंडलर को क्लाइंट को वापस जेनरेट किए गए प्रतिक्रिया संदेश के साथ कॉल किया जाएगा, जिसके साथ आप खेल सकते हैं।
उदाहरण के लिए, मान लेते हैं कि निम्न दो संदेश संचालकों हम ऊपर पंजीकृत किया है हैं:
public class MyMessageHandler : DelegatingHandler {
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) {
//inspect request here
return base.SendAsync(request, cancellationToken).ContinueWith(task => {
//inspect the generated response
var response = task.Result;
return response;
});
}
}
और यह अन्य एक है:
public class MyMessageHandler2 : DelegatingHandler {
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) {
//inspect request here
return base.SendAsync(request, cancellationToken).ContinueWith(task => {
//inspect the generated response
var response = task.Result;
return response;
});
}
}
हम निरंतरता प्रदान की है, हमारे संदेश हैंडलर को फिलो ऑर्डर में क्लाइंट के रास्ते पर वापस बुलाया जाएगा। इसलिए, MyMessageHandler2
के अंदर निरंतरता विधि पहले रास्ते पर आने वाली होगी और MyMessageHandler
के अंदर एक दूसरा होगा।
यही मैंने सोचा था। मुझे नहीं लगता कि यह प्रदाताओं की अवधारणा का समर्थन करता है। एमवीसी में IFilterprovider इंटरफ़ेस की तरह। – Darren
मैं मानता हूं कि 'Async/ContinueWith' सामान इसे घोंसले की गुड़िया की तरह महसूस करता है। यह मेरी राय में, एमएस के रूप में आदेश के रूप में वर्णन करने के लिए, यह अधिक सटीक है। प्रत्येक हैंडलर को दो बार बुलाया जाता है - एक बार रास्ते में (क्रम में क्रम में) और एक बार रिवर्स ऑर्डर में बाहर निकलने पर। निम्नलिखित आलेख में तीसरा आरेख यह स्पष्ट करता है .. http://www.asp.net/web-api/overview/working-with-http/http-message-handlers – EBarr