WCF Service exception error when try to host in ASP.NET Web Site

随声附和 提交于 2019-12-10 10:13:42

问题


The following error occurs when trying to browse my .svc file.

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)

Here is my web.config configuration:

  <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>

Anyone with this similar situation?

I should mention that when this is hosted in a console application I use to run tests everything is fine.

[EDIT] Same error occurs when trying to load the service in a console app. Not showing the WCF web page where you can see the wsdl info etc...


回答1:


If you are using .NET 4.0 and trying to host SOAP, Xml and Json endpoints togeather you would get the exception. Just commment out either your Json or Xml endpoint and that should work fine.

This is a known issue which I have raised on Microsoft Connect and the MS dev team has closed it out as won't fix.

In order to support both Json and Xml if the client passes just the required Accept header in the request like "application/xml" or "application/json" the framework autoamtically handles it and sends back the response in appropriate format.




回答2:


This is what I've got working:

Create a WCF Class Library project in VS2012.

Xsd Schema for data types:

<?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>

Two ServiceContracts, note one adds the magic word, [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
{
}

Implement your concrete class with the two interfaces:

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;
    }
}

Now create a blank ASP.NET project and add a web.config and a Global.asax and a reference to 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)));
    }
}

Here's the magic monster, system.serviceModel in web.config:

<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>

Browse to /soap for soap, /rest/json for restful json and /rest/xml for schema-compliant-ish xml.



来源:https://stackoverflow.com/questions/9307750/wcf-service-exception-error-when-try-to-host-in-asp-net-web-site

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!