用于WCF的silverlightFaultBehavior-但仍获得代码500

用于WCF的silverlightFaultBehavior-但仍获得代码500,silverlight,wcf,silverlight-4.0,https,Silverlight,Wcf,Silverlight 4.0,Https,我想从我的Silverlight 4应用程序的WCF服务中获得一条有意义的错误消息。经过一些调查,我发现如果我希望silverlight能够读取有意义的错误消息,我需要将回复代码从500更改为200。以下是文章: 我已经实现了它,因为它写在那里,应用程序编译,我可以使用服务-但我仍然得到500返回代码。我看到的主要区别是,我通过HTTPS而不是HTTP调用服务。也许这就是它不起作用的原因?知道怎么得到返回码200吗 这是我的Web.Config: <?xml version="1.0" e

我想从我的Silverlight 4应用程序的WCF服务中获得一条有意义的错误消息。经过一些调查,我发现如果我希望silverlight能够读取有意义的错误消息,我需要将回复代码从500更改为200。以下是文章:

我已经实现了它,因为它写在那里,应用程序编译,我可以使用服务-但我仍然得到500返回代码。我看到的主要区别是,我通过HTTPS而不是HTTP调用服务。也许这就是它不起作用的原因?知道怎么得到返回码200吗

这是我的Web.Config:

<?xml version="1.0" encoding="utf-8"?>
<configuration>

  <configSections>
    <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
      <section name="ServiceConfiguratorDataSource.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
    </sectionGroup>
  </configSections>
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <extensions>
        <behaviorExtensions>
            <add name="silverlightFaults" type="ServiceConfiguratorDataSource.SilverlightFaultBehavior, ServiceConfiguratorDataSource, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
        </behaviorExtensions>
    </extensions>       
    <services>
        <service name="ServiceConfiguratorDataSource.Service" behaviorConfiguration="ServiceConfiguratorDataSourceBehaviour">
            <endpoint address="" binding="customBinding" behaviorConfiguration="SLFaultBehavior" bindingConfiguration="ServiceConfiguratorCustomBinding" contract="ServiceConfiguratorDataSource.IService" />
        </service>
    </services>
    <bindings>
        <customBinding>
            <binding name="ServiceConfiguratorCustomBinding">
                <security authenticationMode="UserNameOverTransport"></security>
                <binaryMessageEncoding></binaryMessageEncoding>
                <httpsTransport/>
            </binding>
        </customBinding>
    </bindings>
<behaviors>
  <serviceBehaviors>
    <behavior name="ServiceConfiguratorDataSourceBehaviour">
      <serviceMetadata httpsGetEnabled="true" />
      <serviceDebug includeExceptionDetailInFaults="True"/>
                <serviceCredentials>
                    <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="ServiceConfiguratorDataSource.UserCredentialsValidator,ServiceConfiguratorDataSource" />
                </serviceCredentials>
    </behavior>
  </serviceBehaviors>
        <endpointBehaviors>
            <behavior name="SLFaultBehavior">
                <silverlightFaults/>
            </behavior>
        </endpointBehaviors>            
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
 <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>
</configuration>
有人知道这是不是因为https。。。如果是的话,如何让它发挥作用

提前感谢,
坦率的


EDITH说:我刚刚添加了一些日志记录:调用了ApplyDispatchBehavior-method,但没有调用BeforeSendReply-method。。。知道为什么吗?

如果我没记错的话,UserNamePasswordValidator在管道中很早就被调用了,在调度程序被调用之前,这就是为什么自定义调度行为不会影响任何事情。(原因是安全性:WCF希望尽早“抛出”未经授权的请求,同时为它们运行尽可能少的代码)。
正如您自己在评论中所建议的,一种解决方案是稍后在管道中验证凭据-例如,在每次操作中(甚至可能在message inspector的AfterReceiveRequest中?)

如果我没记错的话,在调用dispatcher之前,UserNamePasswordValidator在管道中很早就被调用了,这就是为什么您的自定义分派行为不会影响任何东西。(原因是安全性:WCF希望尽早“抛出”未经授权的请求,同时为它们运行尽可能少的代码)。
正如您自己在评论中所建议的,一种解决方案是稍后在管道中验证凭据-例如,在每次操作中(甚至可能在消息检查器的AfterReceiveRequest中?)

当您看到500响应代码时,首先是什么导致了故障?(这是[OperationContract]方法内部引发的异常吗?FaultException的显式引发?其他什么?您是否可以尝试显式引发FaultException,看看是否仍然发生?)这是我在UserNamePasswordValidator派生类中引发的显式FaultException。我故意发送错误的用户凭据,因此验证程序抛出异常。如果这就是为什么我还有500。。。还有一个原因需要取消这个该死的UserNameOverTransport身份验证,只需检查我的服务的每个方法调用的凭据。当您看到500响应代码时,首先是什么导致了故障?(这是[OperationContract]方法内部引发的异常吗?FaultException的显式引发?其他什么?您是否可以尝试显式引发FaultException,看看是否仍然发生?)这是我在UserNamePasswordValidator派生类中引发的显式FaultException。我故意发送错误的用户凭据,因此验证程序抛出异常。如果这就是为什么我还有500。。。还有一个原因,就是取消这个该死的UserNameOverTransport身份验证,只需检查我服务的每个方法调用的凭据。我想我会在每个操作中验证凭据。无论如何,我都需要访问其中一些文件中关于用户的信息,因为结果可能很大程度上取决于为当前用户授予的权限。非常感谢:)我想我会在每次操作中验证凭据。无论如何,我都需要访问其中一些文件中关于用户的信息,因为结果可能很大程度上取决于为当前用户授予的权限。非常感谢:)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ServiceModel.Configuration;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Channels;
using System.ServiceModel;

namespace ServiceConfiguratorDataSource
{
public class SilverlightFaultBehavior : BehaviorExtensionElement, IEndpointBehavior
{
    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
    {
        SilverlightFaultMessageInspector inspector = new SilverlightFaultMessageInspector();
        endpointDispatcher.DispatchRuntime.MessageInspectors.Add(inspector);
    }
    public class SilverlightFaultMessageInspector : IDispatchMessageInspector
    {
        public void BeforeSendReply(ref Message reply, object correlationState)
        {
            if (reply.IsFault)
            {
                HttpResponseMessageProperty property = new HttpResponseMessageProperty();

                // Here the response code is changed to 200.
                property.StatusCode = System.Net.HttpStatusCode.OK;

                reply.Properties[HttpResponseMessageProperty.Name] = property;
            }
        }

        public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
        {
            // Do nothing to the incoming message.
            return null;
        }
    }

    // The following methods are stubs and not relevant. 
    public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
    {
    }

    public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
    {
    }

    public void Validate(ServiceEndpoint endpoint)
    {
    }

    public override System.Type BehaviorType
    {
        get { return typeof(SilverlightFaultBehavior); }
    }

    protected override object CreateBehavior()
    {
        return new SilverlightFaultBehavior();
    }

}
}