2011-07-11 158 views
1

我正在使用WebScriptServiceHostFactory構建WCF休息服務以支持POX和Json消息格式,並實現了自定義屬性以處理操作的授權。我想發送狀態代碼作爲響應,並結束對未經授權的請求的請求,所以我拋出異常從自定義屬性和處理IErrorHandler。但我不能發送狀態碼給客戶端。身份驗證WCF REST服務

我得到的HTTP狀態代碼爲202(「接受」)而不是401(「未經授權」)。

下面的代碼有什麼不對嗎?

[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

試着做這裏面RestErrorHandler.ProvideFault:

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