【问题标题】:WCF Service exception error when try to host in ASP.NET Web Site尝试在 ASP.NET 网站中托管时出现 WCF 服务异常错误
【发布时间】:2012-03-07 15:25:33
【问题描述】:

尝试浏览我的 .svc 文件时出现以下错误。

An ExceptionDetail, likely created by IncludeExceptionDetailInFaults=true, whose value is:
System.NullReferenceException: Object reference not set to an instance of an object.
   at System.ServiceModel.Description.WsdlExporter.CreateWsdlBindingAndPort(ServiceEndpoint endpoint, XmlQualifiedName wsdlServiceQName, Port& wsdlPort, Boolean& newBinding, Boolean& bindingNameWasUniquified)
   at System.ServiceModel.Description.WsdlExporter.ExportEndpoint(ServiceEndpoint endpoint, XmlQualifiedName wsdlServiceQName)
   at System.ServiceModel.Description.WsdlExporter.ExportEndpoints(IEnumerable`1 endpoints, XmlQualifiedName wsdlServiceQName)
   at System.ServiceModel.Description.ServiceMetadataBehavior.MetadataExtensionInitializer.GenerateMetadata()
   at System.ServiceModel.Description.ServiceMetadataExtension.EnsureInitialized()
   at System.ServiceModel.Description.ServiceMetadataExtension.HttpGetImpl.InitializationData.InitializeFrom(ServiceMetadataExtension extension)
   at System.ServiceModel.Description.ServiceMetadataExtension.HttpGetImpl.GetInitData()
   at System.ServiceModel.Description.ServiceMetadataExtension.HttpGetImpl.TryHandleDocumentationRequest(Message httpGetRequest, String[] queries, Message& replyMessage)
   at System.ServiceModel.Description.ServiceMetadataExtension.HttpGetImpl.ProcessHttpRequest(Message httpGetRequest)
   at System.ServiceModel.Description.ServiceMetadataExtension.HttpGetImpl.Get(Message message)
   at SyncInvokeGet(Object , Object[] , Object[] )
   at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
   at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage41(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)

这是我的 web.config 配置:

  <system.serviceModel>
    <services>
      <service name="WcfServiceLib.WcfService"
               behaviorConfiguration="Default">
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8080/WebService"/>
          </baseAddresses>
        </host>
        <!-- Service Endpoints -->
        <!-- Unless fully qualified, address is relative to base address supplied above -->
        <endpoint address="" binding="wsHttpBinding" contract="WcfServiceContractLib.IWcfContract"/>
        <endpoint address="web" binding="webHttpBinding" contract="WcfServiceContractLib.IWcfContract"
                  behaviorConfiguration="web"/>
        <endpoint address="webJson" binding="webHttpBinding" contract="WcfServiceContractLib.IWcfContract"
                behaviorConfiguration="webJson"/>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
      </service>
    </services>
    <behaviors>
      <endpointBehaviors>
        <behavior name="web">
          <webHttp defaultOutgoingResponseFormat="Xml" helpEnabled="true"/>
        </behavior>
        <behavior name="webJson">
          <webHttp defaultOutgoingResponseFormat="Json" helpEnabled="true"/>
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior name="Default">
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment aspNetCompatibilityEnabled ="true" />
  </system.serviceModel>

有类似情况的人吗?

我应该提到,当它托管在我用来运行测试的控制台应用程序中时,一切都很好。

[编辑] 尝试在控制台应用程序中加载服务时发生相同的错误。未显示可以查看 wsdl 信息等的 WCF 网页...

【问题讨论】:

    标签: c# wcf .net-4.0 exception-handling wcf-configuration


    【解决方案1】:

    如果您使用 .NET 4.0 并尝试同时托管 SOAP、Xml 和 Json 端点,您会遇到异常。只需注释掉您的 Json 或 Xml 端点,这应该可以正常工作。

    这是我在Microsoft Connect 上提出的一个已知问题,MS 开发团队已将其关闭,因为无法修复。

    为了支持 Json 和 Xml,如果客户端仅在请求中传递所需的 Accept 标头,如“application/xml”或“application/json”,框架会自动处理它并以适当的格式发回响应。

    【讨论】:

    • 谢谢,你在发布答案之前就得到了我,你应该得到这个标记。我删除了第二个端点,并让一个使用基于 Accept、Content-Type 的自动格式选择。它现在工作正常。我也为 REST 操作创建了不同的接口定义,但现在保持相同的具体实现。
    • @TaskosGeorge/@Rajesh:我正在寻找相同问题的答案。正如你所说,我的配置文件中没有指定任何端点。你能告诉我这背后的原因是什么吗?
    【解决方案2】:

    这就是我的工作:

    在 VS2012 中创建 WCF 类库项目。

    数据类型的 Xsd 架构:

    <?xml version="1.0" encoding="utf-8"?>
    <xs:schema xmlns="urn:wcf:hydra:datatypes.xsd:1.5" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:wcf:hydra:datatypes.xsd:1.5" elementFormDefault="qualified" attributeFormDefault="unqualified">
        <xs:element name="IncomingDocument">
            <xs:complexType>
                <xs:sequence>
                    <xs:element name="Firstname" type="xs:string"/>
                    <xs:element name="Surname" type="xs:string"/>
                    <xs:element name="ChildrensNames" minOccurs="0">
                        <xs:complexType>
                            <xs:sequence>
                                <xs:element name="ChildsName" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
                            </xs:sequence>
                        </xs:complexType>
                    </xs:element>
                    <xs:element name="Gender" minOccurs="0">
                        <xs:simpleType>
                            <xs:restriction base="xs:string">
                                <xs:enumeration value="Male"/>
                                <xs:enumeration value="Female"/>
                                <xs:enumeration value="Other"/>
                            </xs:restriction>
                        </xs:simpleType>
                    </xs:element>
                </xs:sequence>
                <xs:attribute name="Version" type="xs:string" use="required" fixed="1.5"/>
            </xs:complexType>
        </xs:element>
        <xs:element name="ResponseDocument">
            <xs:complexType>
                <xs:sequence>
                    <xs:element name="NumberOfChildren" type="xs:int"/>
                </xs:sequence>
            </xs:complexType>
        </xs:element>
        <xs:element name="DayDetails">
            <xs:complexType>
                <xs:sequence>
                    <xs:element name="CurrentDateTime" type="xs:dateTime"/>
                    <xs:element name="WeatherDetails" type="xs:string"/>
                </xs:sequence>
            </xs:complexType>
        </xs:element>
    </xs:schema>
    

    两个ServiceContracts,注意一个添加了神奇的词,[XmlSerializserFormat]

    [ServiceContract]
    public interface ITestMutliHeadService
    {
        [OperationContract]
        [WebInvoke(UriTemplate = "loadchildren")]
        ResponseDocument LoadChildren(IncomingDocument request);
    
        [OperationContract]
        [WebGet(UriTemplate = "daydetails")]
        DayDetails DayDetails();
    
        [OperationContract]
        [WebGet(UriTemplate = "test/{input}")]
        string Test(string input);
    }
    
    [ServiceContract]
    [XmlSerializerFormat]
    public interface ITestMutliHeadServiceSchemaCompliant : ITestMutliHeadService
    {
    }
    

    用两个接口实现你的具体类:

    public sealed class TestMutliHeadService : ITestMutliHeadService, ITestMutliHeadServiceSchemaCompliant
    {
        public ResponseDocument LoadChildren(IncomingDocument request)
        {
            int count = 0;
            if (request.ChildrensNames != null)
            {
                count = request.ChildrensNames.Count();
            }
    
            return new ResponseDocument()
            {
                NumberOfChildren = count,
            };
        }
    
        public DayDetails DayDetails()
        {
            return new DayDetails()
            {
                CurrentDateTime = DateTime.Now,
                WeatherDetails = "It's rather nice, really.",
            };
        }
    
        public string Test(string input)
        {
            return input;
        }
    }
    

    现在创建一个空白的 ASP.NET 项目并添加一个 web.config 和一个 Global.asax 以及对 System.ServiceModel.Activation 的引用

    Global.asax.cs:

    public class Global : HttpApplication
    {
        void Application_Start(object sender, EventArgs e)
        {
            RegisterRoutes();
        }
    
        private void RegisterRoutes()
        {
            var factory = new ServiceHostFactory();
            RouteTable.Routes.Add(new ServiceRoute("", factory, typeof(TestMutliHeadService)));
        }
    }
    

    这是 web.config 中的魔法怪物 system.serviceModel:

    <system.serviceModel>
        <!-- Services -->
        <services>
          <service name="WCF.Hydra.BL.TestMutliHeadService">
            <endpoint name="restJson"       address="rest/json" behaviorConfiguration="restJsonEndpointBehaviour" binding="webHttpBinding"    bindingConfiguration="restBindingConfig"       contract="WCF.Hydra.BL.ITestMutliHeadService"/>
            <endpoint name="restJsonSecure" address="rest/json" behaviorConfiguration="restJsonEndpointBehaviour" binding="webHttpBinding"    bindingConfiguration="restSecureBindingConfig" contract="WCF.Hydra.BL.ITestMutliHeadService"/>
            <endpoint name="restXml"        address="rest/xml"  behaviorConfiguration="restXmlEndpointBehaviour"  binding="webHttpBinding"    bindingConfiguration="restBindingConfig"       contract="WCF.Hydra.BL.ITestMutliHeadServiceSchemaCompliant"/>
            <endpoint name="restXmlSecure"  address="rest/xml"  behaviorConfiguration="restXmlEndpointBehaviour"  binding="webHttpBinding"    bindingConfiguration="restSecureBindingConfig" contract="WCF.Hydra.BL.ITestMutliHeadServiceSchemaCompliant"/>
            <endpoint name="mex"            address="mex"       behaviorConfiguration=""                          binding="mexHttpBinding"    bindingConfiguration="mexBindingConfig"        contract="WCF.Hydra.BL.ITestMutliHeadService"/>
            <endpoint name="mexSecure"      address="mex"       behaviorConfiguration=""                          binding="mexHttpsBinding"   bindingConfiguration="mexSecureBindingConfig"  contract="WCF.Hydra.BL.ITestMutliHeadService"/>
            <endpoint name="soapXsd"        address="soap"      behaviorConfiguration=""                          binding="basicHttpBinding"  bindingConfiguration="soapBindingConfig"       contract="WCF.Hydra.BL.ITestMutliHeadService"/>
            <endpoint name="soapXsdSecure"  address="soap"      behaviorConfiguration=""                          binding="basicHttpsBinding" bindingConfiguration="soapSecureBindingConfig" contract="WCF.Hydra.BL.ITestMutliHeadService"/>
          </service>
        </services>
        <!--  Binding Configurations -->
        <bindings>
          <webHttpBinding>
            <binding name="restBindingConfig">
              <security mode="None"/>
            </binding>
            <binding name="restSecureBindingConfig">
              <security mode="Transport"/>
            </binding>
          </webHttpBinding>
          <mexHttpBinding>
            <binding name="mexBindingConfig"/>
          </mexHttpBinding>
          <mexHttpsBinding>
            <binding name="mexSecureBindingConfig"/>
          </mexHttpsBinding>
          <basicHttpsBinding>
            <binding name="soapSecureBindingConfig">
              <security mode="Transport"/>
            </binding>
          </basicHttpsBinding>
          <basicHttpBinding>
            <binding name="soapBindingConfig">
              <security mode="None"/>
            </binding>
          </basicHttpBinding>
        </bindings>
        <!-- Behaviour Configurations -->
        <behaviors>
          <endpointBehaviors>
            <behavior name="restJsonEndpointBehaviour">
              <webHttp helpEnabled="true" defaultBodyStyle="Bare" defaultOutgoingResponseFormat="Json" automaticFormatSelectionEnabled="false" faultExceptionEnabled="true" />
            </behavior>
            <behavior name="restXmlEndpointBehaviour">
              <webHttp helpEnabled="true" defaultBodyStyle="Bare" defaultOutgoingResponseFormat="Xml" automaticFormatSelectionEnabled="false" faultExceptionEnabled="true" />
            </behavior>
          </endpointBehaviors>
          <serviceBehaviors>
            <behavior name="">
              <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
              <serviceDebug includeExceptionDetailInFaults="true" />
              <dataContractSerializer maxItemsInObjectGraph="2147483647" />
            </behavior>
          </serviceBehaviors>
        </behaviors>
        <!-- Hosting Environment Settings -->
        <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
      </system.serviceModel>
    

    浏览到 /soap 以获取 soap,/rest/json 以获取 restful json 和 /rest/xml 以获取 schema-compliant-ish xml。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-04-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-10
      • 1970-01-01
      相关资源
      最近更新 更多