У меня есть служба WCF, которая вызывает небольшую головную боль. Я трассировка включена, у меня есть объект с контрактом данных строится и прошло, но я вижу эту ошибку в журнале:WCF Service, возвращающий ошибку 400: тело сообщения не может быть прочитано, потому что оно пусто
<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 целочисленных свойства, я не могу себе представить, что это вызывает проблему.
Поскольку я смотрю на это, мне интересно, является ли это запрос или ответ, который является проблемой. У меня есть трассировка сообщений, но ни один журнал не генерируется, что приводит меня к предположению, что именно запрос был проблемой, а не ответом. – Josh
На стороне примечание, RulesException и все классы внутри сериализуемы, хотя он также имеет коллекцию IEnumberable как одно из ее свойств. – Josh
Я просто исключил ответ, комментируя результаты и исключение. Он по-прежнему возвратил ошибку 400. – Josh