我有一个 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 接口(interface)
public interface IRequest
{
int PageSize { get; set; }
int PageIndex { get; set; }
}
我有一个围绕我的服务调用的包装器类。这是类(class)。
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 服务器”。
并且需要在添加/删除windows功能中启用Microsoft .Net Framework 3.1 -> Windows communication foundation http激活。
打开你的visual studio命令窗口
然后你必须运行aspnet_regiis -i
你需要运行 servicemodelreg -ia
运行了很多次,出现错误,搜索谷歌,冲洗,重复。花了大约一个小时才弄清楚。皮塔饼。
关于c# - WCF 服务返回 400 错误 : The body of the message cannot be read because it is empty,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3934209/