REST Web Service 400 ошибка при вызове функции - PullRequest
5 голосов
/ 15 февраля 2012

Я создал REST Web-сервис, который работает с тестовым клиентом Visual Studios WCF.Может вызывать его с веб-сайта, который находится рядом с ним и использует класс «прокси», который был создан с помощью svcutil.

Я также вижу, что служба существует, когда я просматриваю файл .svc.(http://localhost/service1.svc) Появляется веб-страница «Вы создали службу.».

ОДНАКО

Когда я пытаюсь вызвать функцию в службе, (http://localhost/service.svc/firstName/lastName) возвращаетКод ошибки 400.

Недавно у меня возникла отдельная ошибка, которую я не смог понять, поэтому я нашел учебник по ОЧЕНЬ базовому веб-сервису "http://blog.weareon.net/how-to-create-and-consume-rest-web-service-using-wcf/", который остановил предыдущую ошибку, нопо-прежнему ошибка 400 при попытке вызвать функцию.

Мой файл .config был обрезан до костей, чтобы попытаться заставить его работать, прежде чем я зайду слишком далеко.

    <?xml version="1.0"?>
<configuration>

  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <services>
      <service name="VService">
        <endpoint address="" binding="webHttpBinding" contract="ServiceName.IService1" behaviorConfiguration="webBehavior" />
      </service>
    </services>
    <behaviors>
      <endpointBehaviors>
        <behavior name="webBehavior">
          <webHttp/>
        </behavior>
      </endpointBehaviors>

      <serviceBehaviors>        
        <behavior>
          <!-- 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"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
 <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>

  <system.diagnostics>
    <trace autoflush="true"  />
    <sources>
      <source name="System.ServiceModel"
              switchValue="Information, Error"
              propagateActivity="true">
        <listeners>
          <add name="sdt"
              type="System.Diagnostics.XmlWriterTraceListener"
              initializeData= "SdrConfigExample1.e2e" />
        </listeners>
      </source>
    </sources>
  </system.diagnostics>

</configuration>

В своих исследованиях я обнаружил такие вещи, как настройки прокси в браузере, типы возвращаемых данных, проблемы с размером, но пока что ни одна из них не сработала.

Если у вас есть какие-либо идеи, пожалуйста, дайте мне знать. Заранее спасибо.

РЕДАКТИРОВАТЬ:

это XML из файла журнала, спасибо за комментарии, чтобы сообщить мне, что это существует:)

<E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent">
<System xmlns="http://schemas.microsoft.com/2004/06/windows/eventlog/system">
<EventID>131075</EventID>
<Type>3</Type>
<SubType Name="Error">0</SubType>
<Level>2</Level>
<TimeCreated SystemTime="2012-02-15T03:24:00.9952760Z" />
<Source Name="System.ServiceModel" />
<Correlation ActivityID="{00000000-0000-0000-0000-000000000000}" />
<Execution ProcessName="WebDev.WebServer40" ProcessID="3128" ThreadID="4" />
<Channel />
<Computer>ACKZ-01</Computer>
</System>
<ApplicationData>
<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>9b0666f2-9-129737498327838293</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>
</ApplicationData>
</E2ETraceEvent>

Не изучены полностьюэто еще, думал, что я отправлю это в то же время

РЕДАКТИРОВАТЬ 2

ХПКE ИЗ СЛУЖБЫ

namespace VeryBasicService
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IService1" in both code and config file together.
    [ServiceContract]
    public interface IService1
    {

        [OperationContract]
        string GetData(int value);

        [OperationContract]
        CompositeType GetDataUsingDataContract(CompositeType composite);

        [OperationContract]
        [WebGet(UriTemplate="/{firstname}/{lastname}")]
        string CallRestService(string firstName, string lastName);      


        // TODO: Add your service operations here
    }

КОД ФУНКЦИИ

namespace VeryBasicService
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in code, svc and config file together.
    public class Service1 : IService1
    {
        public string GetData(int value)
        {
            return string.Format("You entered: {0}", value);
        }

        public CompositeType GetDataUsingDataContract(CompositeType composite)
        {
            if (composite == null)
            {
                throw new ArgumentNullException("composite");
            }
            if (composite.BoolValue)
            {
                composite.StringValue += "Suffix";
            }
            return composite;
        }
        public string CallRestService(string firstName, string lastName)
        {
            return firstName + " " + lastName;            
        }      
    }
}

1 Ответ

4 голосов
/ 15 февраля 2012

Есть две проблемы, которые я вижу в вашем коде.Во-первых, атрибут name элемента <service> в web.config содержит только «serviceName» - если это не полное имя класса обслуживания, оно не будет использовано.Во-вторых, вы не должны использовать WebInvoke для запросов GET, вместо этого вы должны использовать WebGet:

[WebGet(UriTemplate="/{firstname}/{lastname}")]
...