2012-05-03 10 views
12

Ich vermisse einen Trick mit dem neuen Webapi - Ich versuche, eine XML-Zeichenfolge durch eine Post-Anfrage zu übermitteln und nicht viel Glück.ASP.NET MVC4 WebAPI und XML-Daten schreiben

Das Frontend ist mit jQuery wie folgt aus:

$(document = function() { 
    $("#buttonTestAPI").click(function() { 

     var d = " <customer><customer_id>1234</customer_id></customer>"; 
     $.ajax({ 
      type: 'POST', 
      contentType: "text/xml", 
      url: "@Url.Content("~/api/Customer/")", 
      data: d, 
      success: function (result) { 
       var str = result; 
       $("#output").html(str); 
      } 
     }); 
    }); 
}); 

Mein Controller im Moment ziemlich einfach ist - nur der Standard für die Zeit nach Aktion - zurückzukehren versuchen, was in übergeben wurde:

public string Post(string value) 
    { 
     return value; 
    } 

"Wert" ist jedoch wiederholt Null. Das Seltsame ist, wenn ich meine Daten in der jquery ändern, so etwas zu sein:

d = "<customer_id>1234</customer_id>"; 

Dann bekomme ich „Wert“ in meinem Controller als 1234.

Wie kann ich Zugriff auf die mehr bekommen komplexe XML-Zeichenfolge in meinem Controller?

Antwort

13

Sie senden den Inhaltstyp text/xml, aber Sie haben Ihren Parameter als string definiert. Idealerweise sollte Ihr XML-Code einer Klasse zugeordnet sein, so dass es deserialised sein kann.

Also, wenn Sie benötigen rohe xml dann wird es noch nicht unterstützt. Die Web-API ist derzeit für MediaTypeFormatters mit Serialisierung und fehlende Formatierungen für einfache Typen eingerichtet, die jedoch leicht erstellt werden können.

Dieses ist ein minimal Implementierung eines solchen Formatierer Tragen in Ihrem Fall nur lesen und basierend auf Beta Installer (und nicht jede Nacht Quellcode, da es wesentlich geändert hat):

public class TextMediaTypeFormatter : MediaTypeFormatter 
{ 
    public TextMediaTypeFormatter() 
    { 
     SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/xml")); 
     SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/plain")); 
     SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/javascript")); 
    } 

    protected override bool CanReadType(Type type) 
    { 
     return type == typeof (string); 
    } 

    protected override System.Threading.Tasks.Task<object> OnReadFromStreamAsync(Type type, Stream stream, 
     HttpContentHeaders contentHeaders, 
     FormatterContext formatterContext) 
    { 
     var taskCompletionSource = new TaskCompletionSource<object>(); 
     try 
     { 
      var memoryStream = new MemoryStream(); 
      stream.CopyTo(memoryStream); 
      var s = System.Text.Encoding.UTF8.GetString(memoryStream.ToArray()); 
      taskCompletionSource.SetResult(s); 
     } 
     catch (Exception e) 
     { 
      taskCompletionSource.SetException(e);   
     } 
     return taskCompletionSource.Task; 
    } 
} 

Und verwenden sie es, fügen sie einfach es zu Formatierer Sammlung:

GlobalConfiguration.Configuration.Formatters.Insert(0, new TextMediaTypeFormatter()); 
+0

Sie können das Lesen des Streams mit '' 'var reader = new StreamReader (readStream) vereinfachen; var text = await.ReadToEndAsync();' '' –

6

Wer für eine aktualisierte Version von Aliostad Antwort suchen oben vom beta-Version zu der RC von asp.net mvc 4 web api (kleine Änderungen führten zu einer leichten Überarbeitung für mich).

public class TextMediaTypeFormatter : MediaTypeFormatter 
{ 

    public TextMediaTypeFormatter() 
    { 
     SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/xml")); 
     SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/plain")); 
     SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/javascript")); 
    } 

    public override bool CanReadType(Type type) 
    { 
     if (type == typeof(String)) 
      return true; 
     else 
      return false; 
    } 

    public override bool CanWriteType(Type type) 
    { 
     if (type == typeof(String)) 
      return true; 
     else 
      return false; 

    } 

    public override Task<object> ReadFromStreamAsync(Type type, Stream readStream, System.Net.Http.HttpContent content, IFormatterLogger formatterLogger) 
    { 
     var taskCompletionSource = new TaskCompletionSource<object>(); 
     try 
     { 
      var memoryStream = new MemoryStream(); 
      readStream.CopyTo(memoryStream); 
      var s = System.Text.Encoding.UTF8.GetString(memoryStream.ToArray()); 
      taskCompletionSource.SetResult(s); 
     } 
     catch (Exception e) 
     { 
      taskCompletionSource.SetException(e); 
     } 
     return taskCompletionSource.Task; 
    } 
} 
+0

kann ich mit Ihnen im Chat sprechen? – medBo

18

Im Folgenden können Sie über einen POST an einen Web-API-Methode eine rohe XML-Nachricht lesen:

public void PostRawXMLMessage(HttpRequestMessage request) 
{ 
    var xmlDoc = new XmlDocument(); 
    xmlDoc.Load(request.Content.ReadAsStreamAsync().Result); 
} 

Sie debuggen und den Körper, Kopf, usw. inspizieren können und die sehen Roh-XML veröffentlicht. Ich habe Fiddlers Composer verwendet, um einen HTTP-POST zu erstellen, und das funktioniert gut.

+0

Genau das, was ich gesucht habe! Danke vielmals !!! – MissRaphie

0

Was für mich das Problem gelöst wurde das Hinzufügen dieser:

static SubscriberController() 
{ 
    //Needed for xml deserialization to work 
    var xml = GlobalConfiguration.Configuration.Formatters.XmlFormatter; 
    xml.UseXmlSerializer = true; 
} 

(SubscriberController meine Klasse ist die ApiController erstreckt, und die oben ist ein statischer Konstruktor, so wird es laufen einmal).

Nicht sicher, ob es auch notwendig, aber ich hinzugefügt, um das [FromBody] Attribut auf meine Parameter, etwa so:

public async Task<HttpResponseMessage> SynchronizeImax([FromBody] SynchronizeRequest synchronizeRequest) 
{ 
    //... 
} 

Die große Sache über es auf diese Weise tun, ist, dass man sich nahtlos sowohl XML verarbeiten kann und JSON-Eingang .