2011-07-26 75 views
1

我寫了一個自定義的OperationHandler我的WCF的WebAPI項目如下InputParameters:HttpOperationHandlerFactory和問題

public class AuthenticationOperationHandler : HttpOperationHandlerFactory 
{ 
    protected override Collection<HttpOperationHandler> OnCreateRequestHandlers(ServiceEndpoint endpoint, HttpOperationDescription operation) 
    { 
     var baseHandlers = base.OnCreateRequestHandlers(endpoint, operation); 

     if (operation.InputParameters.Where(p => p.Name.ToLower() == "username").Any() && 
      operation.InputParameters.Where(p => p.Name.ToLower() == "password").Any()) 
     { 
      baseHandlers.Add(new AuthenticateRequestHandler(string.Format("{0}:{1}", operation.InputParameters.Where(p => p.Name == "username").First       ().Name, operation.InputParameters.Where(p => p.Name == "password").First().Name))); 
     } 
     else 
     { 
      throw new WebFaultException(HttpStatusCode.Forbidden); 
     } 

     return baseHandlers; 
    } 
} 

除了被添加到管道這個自定義RequestHandler:

public class AuthenticateRequestHandler : HttpOperationHandler<HttpRequestMessage, string> 
{ 
    public AuthenticateRequestHandler(string outputParameterName) 
     : base(outputParameterName) 
    { 
    } 

    public override string OnHandle(HttpRequestMessage input) 
    { 
     var stringValue = input.Content.ReadAsString(); 
     var username = stringValue.Split(':')[0]; 
     var password = stringValue.Split(':')[1]; 

     var isAuthenticated = ((BocaMembershipProvider)Membership.Provider).ValidateUser(username, password); 
     if (!isAuthenticated) 
     { 
      throw new WebFaultException(HttpStatusCode.Forbidden); 
     } 

     return stringValue; 
    } 
} 

和這是我的API實現:

[ServiceContract] 
public class CompanyService 
{ 
    [WebInvoke(UriTemplate = "", Method = "POST")] 
    public bool Post(string username, string password) 
    { 
     return true; 
    } 
} 

我在Global.as中的配置斧頭文件

public static void RegisterRoutes(RouteCollection routes) 
{ 
    var config = HttpHostConfiguration.Create().SetOperationHandlerFactory(new AuthenticationOperationHandler()); 
    routes.MapServiceRoute<AuthenticationService>("login", config); 
    routes.MapServiceRoute<CompanyService>("companies", config); 
} 

當試圖發送一個POST請求/年我公司收到以下錯誤信息:

的HttpOperationHandlerFactory無法確定應與該請求相關的輸入 參數消息內容 用於服務操作'Post'。如果操作不期望請求消息中的內容 與操作一起使用HTTP GET方法。 否則,確保一個輸入參數要麼有它 IsContentParameter屬性設置爲「true」或是一類是 可分配給下列之一:HttpContent,ObjectContent 1, HttpRequestMessage or HttpRequestMessage 1.

在這條線:

var baseHandlers = base.OnCreateRequestHandlers(endpoint, operation); 

任何想法爲什麼會發生這種情況,以及如何解決這個問題,以強制用戶在每個請求中發送用戶名/密碼參數,並在事後對Membership API進行驗證?

回答

0

要回答你的問題,你的UriTemplate屬性是空的,這就是拋出異常的原因。

UriTemplate = "&username={username}&password={password}" 

那裏,因爲兩個輸入參數收到相同的字符串,即用戶名= JOHNDOE仍然在你的代碼中的錯誤:密碼= QWERTY

解決您的問題,這應該設置如下關於如何使用WCF Web API實現HTTP基本認證是一個很好的article