2014-06-20 13 views
6

Wirklich mit etwas zu kämpfen Ich hoffe, dass die Leute hier helfen können. Ich schreibe eine RESTful API in Web API 2. Immer wenn ich eine Anfrage an diesen Service sende, wird die Antwort durchgehend mit einer Content-Type von text/plain gesendet. Offensichtlich ist das nicht gut, meine Antwort muss Content-Type von application/json sein. Ich habe ein paar Vorschläge aus Google ausprobiert, aber ich glaube nicht, dass ich das ganze Bild verstehe.Web API 2 Text/einfache Antworten

Gibt es etwas Besonderes, was ich tun muss, damit mein Webservice mit application/json Inhalt antwortet? Beachten Sie, dass dies global für die gesamte App funktionieren soll. Daher bin ich nicht auf der Suche nach einer Möglichkeit, eine bestimmte Antwort zu ändern und ihren Inhaltstyp festzulegen. Ich möchte, dass dies ein Standardverhalten für den gesamten Webdienst ist: Wenn eine Anfrage enthält Ein Accept Header für application/json Ich möchte, dass mein Web-Service Content-Type anstelle von text/plain zurückgibt.

bearbeiten zu klären:

Meine Antwort enthält ein Objekt „response“ genannt, die in JSON serialisiert werden sollen und in dem Körper aufgenommen. Ich bin derzeit dabei meine Antwort wie folgt zusammen:

HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK, responseData); 
return response; 

responseData ein POCO ist. Dieser wird korrekt als JSON serialisiert und in der Antwort zurückgegeben - der einzige fehlende Teil ist der Inhaltstyp, der falsch auf "text/plain" eingestellt ist. Ich könnte das bei jeder einzelnen Antwort manuell ändern, aber ich möchte dies auf globaler Ebene konfigurieren.

+0

Gibt die fragliche API eine 'Zeichenfolge' mit JSON-Inhalt zurück, den Sie selbst erstellt haben? – Corey

+0

Überprüfen Sie diese http://www.asp.net/web-api/overview/formats-and-model-binding/content-newtiation, http://msdn.microsoft.com/en-us/magazine/dn574797.aspx , http: //blogs.msdn.com/b/henrikn/archive/2012/04/22/asp-net-web-api-content-newegotiation-and-accept-charset.aspx, – malkam

+0

@Corey derzeit die Antwort ist auf diese Weise erzeugt: 'HttpResponseMessage response = Request.CreateResponse (HttpStatusCode.OK, responseData);' und dann gebe ich einfach 'response' in meiner Aktion zurück. Der Inhalt von responseData wird gut in JSON serialisiert, aber der eigentliche Inhaltstyp-Header ist immer noch auf text/plain gesetzt :( –

Antwort

7

OK, vorausgesetzt, dass Ihre responseData eine Zeichenfolge ist, wird die Content-type Kopfzeile text/plain sein, wenn Sie die HttpResponseMessage erstellen. Es spielt keine Rolle, was der Inhalt der Zeichenfolge ist, da kein Versuch unternommen wird, dies festzustellen.

Die Lösung ist das entsprechende Content-Objekt für Ihre Nachricht zu erstellen, mit dem Typ Medien initialisiert Sie Rückkehr:

HttpResponseMessage response = new HttpResponseMessage() 
    { 
     Content = new StringContent(
       responseData, 
       Encoding.UTF8, 
       "application/json" 
      ) 
    }; 

Es gibt andere Methoden, die Menge zu einem bestimmten Objekttyp zurückkehrt und lassen die API Bibliotheken serialisieren nach Bedarf für Sie JSON oder XML. Ich ziehe es vor, das Framework die Arbeit für mich tun zu lassen, wo es möglich ist, aber so würde man es mit einer selbst erstellten Zeichenkette erreichen.


Für ein strenges JSON-only Ergebnis, die XML-Formatierer aus der WebAPI Konfiguration entfernen und Ihre POCO zurückzukehren.

In App_Start\WebApiConfig.cs, fügen Sie folgendes zu der WebApiConfig.Register Methode:

config.Formatters.Remove(config.Formatters.XmlFormatter); 

Und für Ihre API:

public class MyObject 
{ 
    public bool result; 
    public string reason; 
} 

public class TestController : ApiController 
{ 
    public MyObject GetData() 
    { 
     MyObject result = new MyObject { result = "true", reason = "Testing POCO return" }; 
     return result; 
    } 
} 

ich dies lief und bat /api/Test von Chrome, die nicht einmal erwähnen application/json in der Accept Kopfzeile.Hier sind die Response-Header, bis es Content-Type hits:

HTTP/1.1 200 OK 
Cache-Control: no-cache 
Pragma: no-cache 
Content-Type: application/json; charset=utf-8 

und der Körper:

{"result":true,"reason":"Testing POCO return"} 

Da ich deaktiviert XML es zu JSON Verzug geraten.

+0

Wie in meiner Frage erwähnt, versuche ich einen globalen Weg zu finden Stellen Sie das auf, anstatt den Inhaltstyp für jede Antwort, die ich erstelle, explizit zu definieren. Meine Formulierung war vielleicht etwas unklar - ich habe mein OP bearbeitet, um hoffentlich ein paar Punkte zu klären. –

+0

Haben Sie versucht, das Objekt selbst zurückzugeben? "HttpResponseMessage" ist in Ordnung, wenn Sie mehr Kontrolle über individuelle Rückgaben haben wollen, aber Sie können ein POCO zurückgeben und die Bibliotheken für die Serialisierung für Sie sorgen lassen - JSON oder XML, abhängig von der "Accept" h Eader in der Anfrage. – Corey

+0

Ich nehme an, das Problem ist, dass ich immer noch 404 oder 500 usw. zurückgeben muss, wenn etwas schief geht - ist das mit dem beschriebenen Ansatz noch möglich? –

0

Fügen Sie der Global.asax-Datei Folgendes hinzu.

protected void Application_Start() 
{ 

JsonSerializerSettings serializerSettings = new JsonSerializerSettings(); 
serializerSettings.Converters.Add(new IsoDateTimeConverter()); 
var jsonFormatter = new JsonNetFormatter(serializerSettings); 
jsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html")); 
GlobalConfiguration.Configuration.Formatters.Insert(0, jsonFormatter); 

} 
+0

Das geht davon aus, dass jemand einen JsonNetFormatter irgendeiner Art gebaut hat und ohne dieses Verständnis oder mehr Detail nicht funktioniert. – Suamere

0

Eine weitere mögliche Ursache des Problems beschrieben ist, dass es eine Zulassung im Spiel umgeleitet werden kann, wie der Fall für uns war, als einer der Ingenieure gedacht, wieder zu verwenden, die Benutzerauthentifizierung für eine api.

Das bedeutet, dass eingehende Anforderungen an eine Anmeldeseite umgeleitet wurden, bei der es sich um die text/html-Antwort handelte, die nicht von ReadAsync<> analysiert werden konnte. Ein dummer Fehler, um sicher zu sein, aber nicht leicht zu erkennen.

Die Lösung in diesem Fall war, die Benutzerauthentifizierung zu entfernen und HMAC-basierte Authentifizierung für die API zu implementieren.