У меня есть служба 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);
}
}
Конфигурация для веб-службы (на стороне сервера) выглядит следующим образом:
<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 целочисленных свойства, я не могу себе представить, что это вызывает проблему.