Jas*_*ley 9 batch-processing asp.net-web-api
基于我的上一篇文章,我能够让批处理工作......直到某一点.除了注册路由特定处理程序之外,我还有2个委派处理程序
批处理程序通过委托处理程序验证用户并记录请求.当messagehandlerinvoker开始发送子/嵌套请求时,抛出以下异常.
System.ArgumentException was unhandled by user code
HResult=-2147024809
Message=The 'DelegatingHandler' list is invalid because the property 'InnerHandler' of 'AuthenticationMessageHandler' is not null.
Parameter name: handlers
Source=System.Net.Http.Formatting
ParamName=handlers
StackTrace:
at System.Net.Http.HttpClientFactory.CreatePipeline(HttpMessageHandler innerHandler, IEnumerable`1 handlers)
at System.Web.Http.HttpServer.Initialize()
at System.Web.Http.HttpServer.<EnsureInitialized>b__3()
at System.Threading.LazyInitializer.EnsureInitializedCore[T](T& target, Boolean& initialized, Object& syncLock, Func`1 valueFactory)
at System.Threading.LazyInitializer.EnsureInitialized[T](T& target, Boolean& initialized, Object& syncLock, Func`1 valueFactory)
at System.Web.Http.HttpServer.EnsureInitialized()
at System.Web.Http.HttpServer.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpMessageInvoker.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at RoutingRequest.Service.Startup.BatchMessageHandler.<>c__DisplayClassd.<PrcoessRequest>b__b(Task`1 m) in C:\CEI\Clients\Footlocker.com\FL - Vendor Routing Portal\source\RoutingRequest.Service\Startup\BatchMessageHandler.cs:line 45
at System.Threading.Tasks.ContinuationResultTaskFromResultTask`2.InnerInvoke()
at System.Threading.Tasks.Task.Execute()
InnerException:
Run Code Online (Sandbox Code Playgroud)
是否有我缺少的配置选项,或者我是否需要绕过委托处理程序?
编辑 这里是我的认证处理程序.
public class AuthenticationMessageHandler
: DelegatingHandler
{
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
SetCurrentUser(request);
return base.SendAsync(request, cancellationToken);
}
private void SetCurrentUser(HttpRequestMessage request)
{
var values = new List<string>().AsEnumerable();
if (request.Headers.TryGetValues("routingrequest-username", out values) == false) return;
var username = values.First();
var user = Membership.GetUser(username, true);
if (user == null)
{
var message = string.Format("membership information for '{0}' could not be found.", username);
throw new HttpRequestException(message);
}
var roles = Roles.GetRolesForUser(username);
Thread.CurrentPrincipal = new GenericPrincipal(new GenericIdentity(user.UserName), roles);
}
}
Run Code Online (Sandbox Code Playgroud)
根据Kiran的回答,子类的httpserver修复了一个问题并引入了另一个问题.我的角色提供程序正在获取空引用异常.现在正在调查
cri*_*mbo 15
该博客文章正确识别问题,但如果您使用Startup
或OwinStartup
类配置OWIN,则有一个更简单的解决方案:
更改OWIN配置调用
UseWebApi(this IAppBuilder builder, HttpConfiguration configuration);
,
UseWebApi(this IAppBuilder builder, HttpServer httpServer);
以便批处理程序和OWIN管道使用相同的HttpServer
实例.
其根本原因在于许多批处理文章/示例(例如http://bradwilson.typepad.com/blog/2012/06/batching-handler-for-web-api.html)创建了一个HttpServer
用于批处理的新内容除了HttpServer
处理HTTP请求的main之外; 两者HttpServer
都使用相同的HttpConfiguration
.
当HttpServer
第一次接收请求时初始化每个请求时,它会HttpClientFactory.CreatePipeline
通过反转所有已配置的委托处理程序(例如,跟踪处理程序或其他代理类型处理程序)并使用Web API调度程序终止管道来创建处理程序管道(in ).
如果您没有配置任何委派处理程序,那么这个问题不会让您感到困惑 - 您可以拥有2个HttpServer
使用相同的对象HttpConfiguration
.
但是,如果您有任何显式或隐式配置的委托处理程序(例如,通过启用Web API跟踪),那么Web API无法构建第二个管道 - 委托处理程序已在第一个管道中链接 - 并且此异常在第一个管道中引发要求到第二HttpServer
.
这个例外应该更清楚地说明发生了什么.更好的是,这个问题甚至不可能 - 配置应该是配置,而不是单个处理程序.配置可以是委派处理程序的工厂.但我离题了......
虽然这个问题有点难以理解,但有一个非常简单的方法:
HttpServer
您在批处理程序中使用的相同内容传递给OWIN管道UseWebApi(this IAppBuilder builder, HttpServer httpServer);
GlobalConfiguration.DefaultServer
转到批处理程序,以避免创建新的HttpServer
下面是一个示例OWIN启动类,它创建一个单独的HttpServer
并将其传递给批处理程序和Web API.此示例用于OData批处理程序:
[assembly: OwinStartup(typeof(My.Web.OwinStartup))]
namespace My.Web
{
/// <summary>
/// OWIN webapp configuration.
/// </summary>
public sealed class OwinStartup
{
/// <summary>
/// Configure all the OWIN modules that participate in each request.
/// </summary>
/// <param name="app">The OWIN appBuilder</param>
public void Configuration(IAppBuilder app)
{
HttpConfiguration webApiConfig = new HttpConfiguration();
webApiConfig.MapHttpAttributeRoutes();
HttpServer webApiServer = new HttpServer(webApiConfig);
// Configure batch handler
var batchHandler = new DefaultODataBatchHandler(webApiServer);
webApiConfig.Routes.MapODataServiceRoute("ODataRoute",
"odata",
BuildEdmModel(),
new DefaultODataPathHandler(),
ODataRoutingConventions.CreateDefault(),
batchHandler);
app.UseWebApi(webApiServer);
}
private EdmModel BuildEdmModel()
{
// ...
}
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
6313 次 |
最近记录: |