2011-07-11 35 views
1

WebScriptServiceHostFactoryを使用してWCF restサービスを構築し、POXとJsonの両方のメッセージ形式をサポートし、カスタム属性を実装して操作の承認を処理します。私はレスポンスとしてステータスコードを送信し、許可されていないリクエストのリクエストを終了したいので、カスタム属性から例外をスローして、IErrorHandlerで処理しています。しかし、私はクライアントにステータスコードを送ることができません。認証WCF RESTサービス

401( "承認されていません")の代わりに202( "承認済み")としてHTTPステータスコードが取得されています。

下記のコードに間違いがありますか?

[ServiceContract] 
public interface Irestservice 
{ 
    [OperationContract] 
    [WebGet] 
    bool signin(string username, string password);  
} 


[ServiceBehavior(IncludeExceptionDetailInFaults = true, 
       InstanceContextMode = InstanceContextMode.PerCall), 
       AspNetCompatibilityRequirements(RequirementsMode = 
         AspNetCompatibilityRequirementsMode.Allowed)] 
public class restservice : Irestservice 
{ 

    [Authorization] 
    public bool signin(string username, string password) 
    {   
     return true;   
    } 
} 

public class AuthorizationAttribute : Attribute, IOperationBehavior, 
               IParameterInspector 
{ 

    public void ApplyDispatchBehavior(
     OperationDescription operationDescription, 
     DispatchOperation dispatchOperation) 
    {   
     dispatchOperation.ParameterInspectors.Add(this); 
    }  

    public void AfterCall(string operationName, object[] outputs, 
          object returnValue, object correlationState) 
    { 
    } 

    public object BeforeCall(string operationName, object[] inputs) 
    { 
     string publicKey = WebOperationContext.Current 
           .IncomingRequest.Headers["Authorization"]; 
     bool flag = AuthorizationHelper.CheckPartnerAuthorization(publicKey); 
     if (!flag) 
     { 
      WebOperationContext.Current.OutgoingResponse.StatusCode = 
       HttpStatusCode.Unauthorized; 
      throw new LicensingException("PartnerUnauthorized"); 
     } 

     return null; 
    }    
} 

public class LicensingBehavior : IServiceBehavior 
{   

    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, 
             ServiceHostBase serviceHostBase) 
    { 
     foreach (ChannelDispatcher channelDispatcher in 
       serviceHostBase.ChannelDispatchers) 
     {    
      RestErrorHandler newHandler = new RestErrorHandler(); 
      channelDispatcher.ErrorHandlers.Add(newHandler);    
     } 
    } 
} 

class AppServiceHostFactory : WebScriptServiceHostFactory 
{ 
    protected override ServiceHost CreateServiceHost(Type serviceType, 
                Uri[] baseAddresses) 
    { 
     ServiceHost serviceHost = 
      base.CreateServiceHost(serviceType, baseAddresses); 
     serviceHost.Description.Behaviors.Add(new LicensingBehavior()); 
     return serviceHost; 
    }  
} 

public class RestErrorHandler:IErrorHandler 
{ 
    #region IErrorHandler Members 

    public bool HandleError(Exception error) 
    { 
     return error is LicensingException; 
    } 

    public void ProvideFault(Exception error, MessageVersion version, 
          ref Message fault) 
    { 
     LicensingException licensingException = error as LicensingException; 
     if (licensingException != null) 
     { 

      fault = Message.CreateMessage(version, null, 
       new ValidationErrorBodyWriter(licensingException)); 
      HttpResponseMessageProperty prop = 
       new HttpResponseMessageProperty(); 
      prop.StatusCode = HttpStatusCode.Unauthorized; 
      prop.Headers[HttpResponseHeader.ContentType] = 
       "application/json; charset=utf-8"; 
      fault.Properties.Add(HttpResponseMessageProperty.Name, prop); 
      fault.Properties.Add(WebBodyFormatMessageProperty.Name, 
       new WebBodyFormatMessageProperty(WebContentFormat.Json)); 
     }    
    } 

    class ValidationErrorBodyWriter : BodyWriter 
    { 
     private LicensingException licensingException; 
     Encoding utf8Encoding = new UTF8Encoding(false); 

     public ValidationErrorBodyWriter(LicensingException exception) 
      : base(true) 
     { 
      this.licensingException = exception; 
     } 

     protected override void OnWriteBodyContents(XmlDictionaryWriter writer) 
     { 
      writer.WriteStartElement("root"); 
      writer.WriteAttributeString("type", "object"); 

      writer.WriteStartElement("ErrorMessage"); 
      writer.WriteAttributeString("type", "string"); 
      writer.WriteString(this.licensingException.Message); 
      writer.WriteEndElement(); 

      writer.WriteEndElement(); 
     } 
    } 
} 

答えて

0

私は工場とserice設定を使用していました。したがって、サービスの振る舞いは工場の振る舞いによって隠されていました。したがって、工場とサービスの構成を一緒に使用しないでください。

0

IErrorHandlerが受け取っているエラーは、実際にはライセンス例外ですか?このpost on error handling for webHttpBindingを見て、ProvideFaultメソッドを正しく実装していることを確認してください。

0

はRestErrorHandler.ProvideFaultの内側にこれをやってみてください。

var response = WebOperationContext.Current.OutgoingResponse; 
response.StatusCode = HttpStatusCode.Unauthorized;