2013-05-28 14 views
7

Próbuję wysłać niektóre dane JSON do usługi, którą utworzyłem wC# i wcf. W Skrzypek moje żądanie POST jest następującyBłąd 415 podczas wysyłania danych JSON do usługi WCF

Skrzypek:

Request Header 
User-Agent: Fiddler 
Host: localhost 
Content-Length: 29 
Content-Type: application/json; charset=utf-8 

Request Body 
{sn:"2705", modelCode:1702 } 

Poniżej interfejs usługi. Że używa atrybutu WebInvoke zarządzać żądanie POST

[ServiceContract] 
public interface IProjectorService 
{ 
    [WebInvoke(Method="POST", UriTemplate="projectors", RequestFormat=WebMessageFormat.Json, ResponseFormat=WebMessageFormat.Json)] 
    [OperationContract] 
    void RecordBreakdown(Record record); 
} 

Realizacja interfejsu serwisowego odbywa zmienne przekazywane do argumentu i używa ADO wysłać te dane do db SQL.

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] 
[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)] 
public partial class ProjectorService : IProjectorService 
{ 

    public void RecordBreakdown(Record record) 
    { 
     //ado code to send data to db (ie do record.SerialNumber... 
    }   
} 

POCO obiektu do reprezentowania wielu parametrów

[DataContract] 
public class Record 
{  
    [DataMember] 
    public string SerialNumber { get; set; } 
    [DataMember] 
    public int ModelCode { get; set; } 
} 

.svc plik

<%@ ServiceHost Language="C#" Debug="true" Service="ProjectorService" CodeBehind="~/App_Code/ProjectorService.cs" %> 

Web.config:

<?xml version="1.0"?> 
<configuration> 
    <appSettings> 
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true"/> 
    </appSettings> 
    <system.web> 
    <compilation debug="true" targetFramework="4.5"/> 
    <httpRuntime targetFramework="4.5"/> 
    </system.web> 
    <system.serviceModel> 
    <behaviors> 
     <serviceBehaviors> 
     <behavior> 
      <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/> 
     <serviceDebug includeExceptionDetailInFaults="false"/> 
     </behavior> 
     </serviceBehaviors> 
    </behaviors> 
    <protocolMapping> 
     <add binding="basicHttpsBinding" scheme="https"/> 
    </protocolMapping> 
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/> 
    </system.serviceModel> 
    <system.webServer> 
    <modules runAllManagedModulesForAllRequests="true"/> 
    <directoryBrowse enabled="true"/> 
    </system.webServer> 
</configuration> 

W Skrzypek, po kliknięciu na " wykonaj ", pojawia się błąd 415" nieobsługiwany nośnik ty pe ". Moja obecna linia myślenia polega na tym, że w mojej klasie usług projektora, może powinienem stworzyć obiekt odpowiedzi i odesłać kod 200?

Odpowiedz

8

Dla końcowego WCF rozpoznać [WebInvoke] (lub [WebGet]) adnotacje, musi być określone jako punkt końcowy WebHTTP (a.k.a. końcowego spoczynku) - co oznacza, że ​​za pomocą webHttpBinding i zachowanie webHttp końcowego. Ponieważ nie zdefiniowałeś żadnych punktów końcowych w pliku web.config, używa on domyślnego powiązania dla schematu, którym jest BasicHttpBinding. Punkty końcowe z tym wiązaniem odpowiadają tylko na żądania XML (SOAP), dlatego pojawia się ten błąd podczas wysyłania żądania JSON.

Spróbuj wymienić swój punkt <system.serviceModel> w Twojej web.config, i że należy zdefiniować punkt końcowy, jak trzeba go:

<system.serviceModel> 
    <behaviors> 
     <serviceBehaviors> 
     <behavior> 
      <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/> 
      <serviceDebug includeExceptionDetailInFaults="false"/> 
     </behavior> 
     </serviceBehaviors> 
     <endpointBehaviors> 
     <behavior name="Web"> 
      <webHttp/> 
     </behavior> 
     </endpointBehaviors> 
    </behaviors> 
    <services> 
     <service name="ProjectorService"> 
     <endpoint address="" 
        behaviorConfiguration="Web" 
        binding="webHttpBinding" 
        contract="IProjectorService" /> 
     </service> 
    </services> 
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/> 
    </system.serviceModel> 
+0

To zadziałało. Myślałem, że powiązanie sieci zostało wygenerowane automatycznie przy użyciu metody fabrycznej w pliku svc (które i tak nie zawierałem). Oprócz tych zmian potrzebowałem dodać "BodyStyle = WebMessageBodyStyle.Bare" do metody usługi, ponieważ dane JSON nie były zapakowane w inny obiekt. – beaumondo

5

Najprawdopodobniej problem polega na tym, że twoja metoda serwisowa wymaga 2 parametrów. Domyślnie może być obecny tylko jeden parametr body.

Możesz to naprawić na 2 sposoby. Pierwszy sposób: Dodaj Nadwozie = WebMessageBodyStyle.Wrapped do WebInvoke Atrybuty tak:

[WebInvoke(Method = "POST", UriTemplate = "projectors", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped)] 
void RecordBreakdown(string sn, int modelCode); 

Drugi sposób: Utwórz klasę dla danych POST. Możesz na przykład utworzyć klasę dla wszystkich zmiennych, które chcesz opublikować w swojej usłudze jako JSON. Aby utworzyć klasy z JSON, możesz użyć Json2CSharp (lub Wkleić JSON jako Classes w VS2012 Update 2). Poniższy JSON

{"sn":2705, "modelCode":1702 } 

spowoduje poniższej klasy:

Potem trzeba będzie zmienić swoje metody do zaakceptowania tej klasy tak:

void RecordBreakdown(string sn, int modelCode); 

do:

void RecordBreakdown(Record record); 

Po tym czasie powinieneś móc wysłać JSON do usługi.

Mam nadzieję, że to pomoże!

Edytuj:Przyłącz się do mojej odpowiedzi od dołu za pomocą tego.

Po ponownym przejrzeniu pliku konfiguracyjnego wygląda również na błędną konfigurację wiązania.Domyślne powiązanie dla WCF to "bassicHttpBinding", które zasadniczo używa SOAP 1.1.

Ponieważ chcesz używać JSON i usługi RESTFul, będziesz musiał użyć 'webHttpBinding'. Here is a link do konfiguracji podstawowej używamy zawsze dla naszych usług RESTFul. Możesz ustawić tryb bezpieczeństwa na Transport, gdy wymagany jest bezpieczny transport (np .: https).

<security mode="Transport"></security> 
+0

Próbowałem dodanie Nadwozie = WebMessageBodyStyle.Wrapped ale to nie działało. Nadal dostaję błąd 415. Usunąłem również wiele parametrów i utworzyłem nową klasę na podstawie Twojej sugestii, wolę w ten sposób, tak myślę, więc zaktualizowałem pytanie, aby pokazać te zmiany, ale to też nie działa i nadal widzę błąd 415. – beaumondo

+1

Po ponownym przejrzeniu plik konfiguracyjny, wygląda również jak błędna konfiguracja. Domyślne powiązanie dla WCF to "bassicHttpBinding", które zasadniczo używa SOAP 1.1. Ponieważ chcesz używać JSON i usługi RESTFul, będziesz musiał użyć 'webHttpBinding'. Zawarłem link do podstawowej konfiguracji, której używamy zawsze w naszych usługach RESTFul. :) Informacje: [link] (http://pastebin.com/Yj4bdrHp) – Xciles

Powiązane problemy