尝试在 ASP.NET 网站中托管时出现 WCF 服务异常错误
Posted
技术标签:
【中文标题】尝试在 ASP.NET 网站中托管时出现 WCF 服务异常错误【英文标题】:WCF Service exception error when try to host in ASP.NET Web Site 【发布时间】: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 网页...
【问题讨论】:
【参考方案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。
【讨论】:
以上是关于尝试在 ASP.NET 网站中托管时出现 WCF 服务异常错误的主要内容,如果未能解决你的问题,请参考以下文章
使用 wcf 对 sql server 运行查询时出现奇怪的错误
使用 Windows 服务中托管的 WCF 服务时出现 HTTP 获取错误
WCF 服务 - ASP.net 托管 - 单点登录,如何传递凭据