我有一个令人头疼的WCF服务。我已启用跟踪,我有一个正在构建并传入数据协定的对象,但我在日志中看到此错误:
<TraceData>
<DataItem>
<TraceRecord xmlns="http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord" Severity="Error">
<TraceIdentifier>http://msdn.microsoft.com/en-US/library/System.ServiceModel.Diagnostics.ThrowingException.aspx</TraceIdentifier>
<Description>Throwing an exception.</Description>
<AppDomain>efb0d0d7-1-129315381593520544</AppDomain>
<Exception>
<ExceptionType>System.ServiceModel.ProtocolException, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType>
<Message>There is a problem with the XML that was received from the network. See inner exception for more details.</Message>
<StackTrace>
at System.ServiceModel.Channels.HttpRequestContext.CreateMessage()
at System.ServiceModel.Channels.HttpChannelListener.HttpContextReceived(HttpRequestContext context, Action callback)
at System.ServiceModel.Activation.HostedHttpTransportManager.HttpContextReceived(HostedHttpRequestAsyncResult result)
at System.ServiceModel.Activation.HostedHttpRequestAsyncResult.HandleRequest()
at System.ServiceModel.Activation.HostedHttpRequestAsyncResult.BeginRequest()
at System.ServiceModel.Activation.HostedHttpRequestAsyncResult.OnBeginRequest(Object state)
at System.Runtime.IOThreadScheduler.ScheduledOverlapped.IOCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
at System.Runtime.Fx.IOCompletionThunk.UnhandledExceptionFrame(UInt32 error, UInt32 bytesRead, NativeOverlapped* nativeOverlapped)
at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
</StackTrace>
<ExceptionString>
System.ServiceModel.ProtocolException: There is a problem with the XML that was received from the network. See inner exception for more details. ---&gt; System.Xml.XmlException: The body of the message cannot be read because it is empty.
--- End of inner exception stack trace ---
</ExceptionString>
<InnerException>
<ExceptionType>System.Xml.XmlException, System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType>
<Message>The body of the message cannot be read because it is empty.</Message>
<StackTrace>
at System.ServiceModel.Channels.HttpRequestContext.CreateMessage()
at System.ServiceModel.Channels.HttpChannelListener.HttpContextReceived(HttpRequestContext context, Action callback)
at System.ServiceModel.Activation.HostedHttpTransportManager.HttpContextReceived(HostedHttpRequestAsyncResult result)
at System.ServiceModel.Activation.HostedHttpRequestAsyncResult.HandleRequest()
at System.ServiceModel.Activation.HostedHttpRequestAsyncResult.BeginRequest()
at System.ServiceModel.Activation.HostedHttpRequestAsyncResult.OnBeginRequest(Object state)
at System.Runtime.IOThreadScheduler.ScheduledOverlapped.IOCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
at System.Runtime.Fx.IOCompletionThunk.UnhandledExceptionFrame(UInt32 error, UInt32 bytesRead, NativeOverlapped* nativeOverlapped)
at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
</StackTrace>
<ExceptionString>System.Xml.XmlException: The body of the message cannot be read because it is empty.</ExceptionString>
</InnerException>
</Exception>
</TraceRecord>
</DataItem>
</TraceData>
所以,这是我的服务界面:
[ServiceContract]
public interface IRDCService
{
[OperationContract]
Response<Customer> GetCustomer(CustomerRequest request);
[OperationContract]
Response<Customer> GetSiteCustomers(CustomerRequest request);
}
这是我的服务实例
public class RDCService : IRDCService
{
ICustomerService customerService;
public RDCService()
{
//We have to locate the instance from structuremap manually because web services *REQUIRE* a default constructor
customerService = ServiceLocator.Locate<ICustomerService>();
}
public Response<Customer> GetCustomer(CustomerRequest request)
{
return customerService.GetCustomer(request);
}
public Response<Customer> GetSiteCustomers(CustomerRequest request)
{
return customerService.GetSiteCustomers(request);
}
}
Web服务(服务器端)的配置如下所示:
<system.serviceModel>
<diagnostics>
<messageLogging logMalformedMessages="true" logMessagesAtServiceLevel="true"
logMessagesAtTransportLevel="true" />
</diagnostics>
<services>
<service behaviorConfiguration="MySite.Web.Services.RDCServiceBehavior"
name="MySite.Web.Services.RDCService">
<endpoint address="http://localhost:27433" binding="wsHttpBinding"
contract="MySite.Common.Services.Web.IRDCService">
<identity>
<dns value="localhost:27433" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MySite.Web.Services.RDCServiceBehavior">
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="true"/>
<dataContractSerializer maxItemsInObjectGraph="6553600" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
这是我的请求对象的样子
[DataContract]
public class CustomerRequest : RequestBase
{
[DataMember]
public int Id { get; set; }
[DataMember]
public int SiteId { get; set; }
}
和RequestBase:
[DataContract]
public abstract class RequestBase : IRequest
{
#region IRequest Members
[DataMember]
public int PageSize { get; set; }
[DataMember]
public int PageIndex { get; set; }
#endregion
}
和我的IRequest接口
public interface IRequest
{
int PageSize { get; set; }
int PageIndex { get; set; }
}
我的服务调用周围有一个包装类。这是班级。
public class MyService : IMyService
{
IRDCService service;
public MyService()
{
//service = new MySite.RDCService.RDCServiceClient();
EndpointAddress address = new EndpointAddress(APISettings.Default.ServiceUrl);
BasicHttpBinding binding = new BasicHttpBinding(BasicHttpSecurityMode.None);
binding.TransferMode = TransferMode.Streamed;
binding.MaxBufferSize = 65536;
binding.MaxReceivedMessageSize = 4194304;
ChannelFactory<IRDCService> factory = new ChannelFactory<IRDCService>(binding, address);
service = factory.CreateChannel();
}
public Response<Customer> GetCustomer(CustomerRequest request)
{
return service.GetCustomer(request);
}
public Response<Customer> GetSiteCustomers(CustomerRequest request)
{
return service.GetSiteCustomers(request);
}
}
最后,响应对象。
[DataContract]
public class Response<T>
{
[DataMember]
public IEnumerable<T> Results { get; set; }
[DataMember]
public int TotalResults { get; set; }
[DataMember]
public int PageIndex { get; set; }
[DataMember]
public int PageSize { get; set; }
[DataMember]
public RulesException Exception { get; set; }
}
因此,当我构建我的CustomerRequest对象并将其传入时,由于某种原因,它将作为空请求命中服务器。有什么想法吗?我试过提高对象图和消息大小。当我调试时,它会在400错误的包装类中停止。我不确定是否存在序列化错误,但考虑到对象契约是4个整数属性,我无法想象它会导致问题。
如果遇到此问题,则需要在本地IIS上运行WCF应用程序。
转到wcf应用程序项目的“属性”,然后选择“使用本地iis Web服务器”。
并且您需要启用Microsoft .Net Framework 3.1 - > Windows通信基础http激活添加/删除Windows功能。
打开visual studio命令窗口
然后你必须运行aspnet_regiis -i
你需要运行servicemodelreg -ia
这是很多运行,得到一个错误,搜索谷歌,冲洗,重复。大约需要一个小时才能搞清楚。 PITA。
我有同样的问题,显然它是由URL中的.svc后面的尾随斜杠引起的。不要把斜线放在那里......它有效。
我遇到了同样的问题,但是由不同的问题引起了。
我为WCF REST服务实现了自己的服务主机,并且意外地从System.ServiceModel.ServiceHost
而不是System.ServiceModel.Web.WebServiceHost
派生了我的类
我可以通过浏览到根URL来激活服务,但是当我尝试访问其中一个公开的资源时,我会收到HTTP 400错误。连接调试器显示了上面提到的异常。
希望有一天这会帮助某人。
我们多次遇到同样的问题,请在IIS上托管,在性能和可扩展性方面要好得多。
当WCF服务出现问题,并且堕落或太忙时。这个问题有时会发生。
问候,
Mazhar Karimi
在App.config中将端点绑定设置为basicHttpBinding
导致相同的错误消息(即使System.ServiceModel.Web.WebServiceHost
用作@MvdD的答案):
<endpoint address="" binding="basicHttpBinding" contract="MySite.Common.Services.Web.IRDCService">
WebServiceHost
的正确绑定值是webHttpBinding
(也可能是ws
)
<endpoint address="" binding="webHttpBinding" contract="MySite.Common.Services.Web.IRDCService">
请注意,与basicHttpBinding
相反,https似乎没有相应的webHttpsBinding
对应物,应该使用安全模式传输。
因此,在Windows Server 2016上将服务部署到IIS 10并尝试导航到服务屏幕后,遇到了这个确切的错误。
在与它斗争了一段时间后,我去添加了多个具有不同绑定的端点,认为它可能不喜欢我正在使用的ws2007FederationHttpBinding。
这是原始端点配置:
<services>
<service name="Vendor.Services.Provider.Host.Implementation.ProviderService">
<endpoint
address="https://svc01dev/Services/Provider/4/0/ProviderService.svc"
binding="ws2007FederationHttpBinding"
bindingConfiguration="Vendor.Services.Provider.Contracts.ServiceContracts.IProviderService_ws2007FederationHttpBinding"
contract="Vendor.Services.Provider.Contracts.ServiceContracts.IProviderService"/>
</service>
</services>
我从端点删除了地址,准备尝试多端点服务:
<services>
<service name="Vendor.Services.Provider.Host.Implementation.ProviderService">
<endpoint
binding="ws2007FederationHttpBinding"
bindingConfiguration="Vendor.Services.Provider.Contracts.ServiceContracts.IProviderService_ws2007FederationHttpBinding"
contract="Vendor.Services.Provider.Contracts.ServiceContracts.IProviderService"/>
</service>
</services>
为了看看会发生什么,我再次导航到服务屏幕,然后弹出。没有更多的错误。我将更多地研究这个,但如果有人知道,我肯定会喜欢听到它。