2012-05-03 37 views
12

Tôi đang thiếu một mẹo với webapi mới - Tôi đang cố gắng gửi chuỗi xml qua yêu cầu đăng và không có nhiều may mắn.ASP.NET MVC4 WebAPI và dữ liệu Đăng bài XML

Sự kết thúc phía trước đang sử dụng jQuery như thế này:

$(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); 
      } 
     }); 
    }); 
}); 

điều khiển của tôi là khá đơn giản vào lúc này - chỉ là mặc định cho bài hành động - cố gắng để trả lại những gì đã được thông qua:

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

Tuy nhiên, "giá trị" là nhiều lần null. Điều kỳ lạ là, khi tôi thay đổi dữ liệu của tôi trong jquery là một cái gì đó như thế này:

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

Sau đó, tôi nhận được "giá trị" trong bộ điều khiển của tôi như là 1234.

Làm thế nào tôi có thể nhận được quyền truy cập vào các chi tiết chuỗi xml phức tạp trong bộ điều khiển của tôi?

Trả lời

13

Bạn đang gửi loại nội dung là text/xml nhưng bạn đã xác định thông số của mình là string. Lý tưởng nhất là XML của bạn nên được ánh xạ tới một lớp sao cho nó có thể là deserialised.

Vì vậy, nếu bạn cần raw xml thì nó chưa được hỗ trợ. Web API hiện đang được thiết kế để serialization MediaTypeFormatters và thiếu định dạng kiểu đơn giản nhưng chúng có thể dễ dàng được xây dựng.

một Đây là một tối thiểu thực hiện định dạng như chỉ hỗ trợ đọc trong trường hợp của bạn và dựa trên beta cài đặt (và không phải mã nguồn hàng đêm vì nó đã thay đổi đáng kể):

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; 
    } 
} 

Và để sử dụng nó, chỉ cần thêm nó vào bộ sưu tập formatters:

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

Bạn có thể đơn giản hóa việc đọc luồng bằng '' 'var reader = new StreamReader (readStream); var text = await reader.ReadToEndAsync();' '' –

6

Bất cứ ai tìm kiếm một phiên bản cập nhật của câu trả lời của Aliostad ở trên từ bản phát hành beta đến RC của asp.net MVC 4 web api (thay đổi nhỏ dẫn đến một chút làm lại cho tôi).

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

Tôi có thể nói chuyện với bạn trong cuộc trò chuyện không? – medBo

18

Sau đây sẽ cho phép bạn đọc một thông điệp XML thô qua một POST đến một phương pháp Web API:

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

Bạn có thể gỡ lỗi và kiểm tra cơ thể, tiêu đề, vv và sẽ thấy XML thô được đăng. Tôi đã sử dụng Composer của Fiddler để tạo một HTTP POST và nó hoạt động tốt.

+0

Chính xác những gì tôi đang tìm kiếm! Cảm ơn rất nhiều !!! – MissRaphie

0

gì giải quyết vấn đề này đối với tôi là cách thêm này:

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

(SubscriberController là lớp học của tôi mà kéo dài ApiController, và ở trên là một constructor tĩnh, vì vậy nó sẽ chạy một lần).

Không chắc nếu nó cũng cần thiết, nhưng tôi đã thêm thuộc tính [FromBody] để tham số của tôi, như vậy:

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

Những điều tuyệt vời về làm nó theo cách này là bạn liên tục có thể xử lý cả XML và JSON đầu vào .

Các vấn đề liên quan