2012-08-02 46 views
8

Tôi có một số dữ liệu "Foo" mà tôi muốn chuyển từ trình duyệt tới máy chủ và truy xuất số liệu thống kê được dự đoán dựa trên thông tin chứa trong foo.Làm cách nào để truyền mô hình phức tạp từ máy khách đến máy chủ?

$.ajax({ 
     type: 'GET', 
     url: "/api/predictedStats/", 
     data: "foo=" + ko.toJSON(foo, fooProperties), 
     contentType: 'application/json; charset=utf-8', 
     dataType: 'json', 
     success: function(data) { 
     return _this.viewModel.setPredictedStats(data); 
     }, 
     error: function(jqXHR, statusText, errorText) { 
     return _this.viewModel.setErrorValues(jqXHR, errorText); 
     } 
    }); 

Tôi đã tạo bộ điều khiển thống kê được dự đoán và lấy phương pháp lấy đối số của Foo.

public class PredictedStatsController : ApiController 
{ 
    public PredictedStats Get(Foo foo) 
    { 
     return statsService.GetPredictedStats(foo); 
    } 
} 

Gắn một điểm ngắt trên phương thức Nhận tôi thấy đối tượng Foo luôn là rỗng. Không có lỗi nào được ném từ ghi nhật ký theo dõi webapi chỉ bằng các dòng sau.

WEBAPI: opr[FormatterParameterBinding] opn[ExecuteBindingAsync] msg[Binding parameter 'foo'] status[0] 
WEBAPI: opr[JsonMediaTypeFormatter] opn[ReadFromStreamAsync] msg[Type='foo', content-type='application/json; charset=utf-8'] status[0] 
WEBAPI: opr[JsonMediaTypeFormatter] opn[ReadFromStreamAsync] msg[Value read='null'] status[0] 

Tôi đã không có vấn đề gửi dữ liệu thông qua một đường bưu điện đến bộ điều khiển Foo để tạo ra các đối tượng Foo trên máy chủ để tôi có thể nói không có gì sai với json tạo clientside là.

Nhìn vào fiddler kết quả Nhận được như sau, nơi jsondata là đối tượng foo.

GET /api/predictedStats?foo={jsondata} HTTP/1.1 

Điều này thậm chí có thể xảy ra hoặc tôi có hoàn toàn sai không?

Cảm ơn Neil


EDIT: tôi cảm thấy như tôi gần như đã làm việc này như sau

public PredictedStats Get([FromUri]Foo foo) 
{ 
    return statsService.GetPredictedStats(foo); 
} 

Đối tượng foo được quay trở lại tốt nhưng không có tính chất của Foo đã được dân cư đúng.


Trong thời gian đó, tôi đã sử dụng POST với dữ liệu gần giống hệt nhau chỉ cần bỏ "foo =" và điều này hoạt động tốt.

Tôi không chắc liệu POST hoặc GET có nên được sử dụng trong trường hợp này hay không nhưng điều đó sẽ rất thú vị để biết.


Tôi cũng thấy http://bugs.jquery.com/ticket/8961 này mà dường như đề nghị bạn không thể đính kèm một cơ thể để một yêu cầu GET với jquery để POST có lẽ là lựa chọn hợp lý chỉ

Trả lời

6

Bạn gần như đã có :)

Khi bạn sử dụng [FromUri] (bạn phải sử dụng cho các đối tượng 'phức tạp' bởi vì Web API mặc định không 'liên kết' các đối tượng phức tạp, nó luôn tìm cách loại bỏ chúng khỏi cơ thể) bạn không cần phải vượt qua param= trong Uri - bạn chỉ cần chuyển các thành viên của giá trị dưới dạng tham số chuỗi truy vấn. Đó là 'member1=value&member2=value' - trong đó member1member2 là thành viên của Foo.

Lưu ý không có 'lỗi' trong jQuery - trong khi thông số HTTP không cấm cơ thể yêu cầu, có khả năng trình duyệt sẽ làm (và nếu trường hợp đó, jQuery không thể gửi), và nhiều khả năng là một máy chủ sẽ không bao giờ đọc nó. Nó không được chấp nhận. Nó cũng có các vấn đề thú vị với bộ nhớ đệm có khả năng, trong đó một trình duyệt sẽ không lưu trữ một POST, PUT, DELETE vv, nhưng sẽ cache một GET nếu các tiêu đề phản hồi không cấm nó - có thể có các tác dụng phụ nghiêm trọng cho một ứng dụng khách.Tôi khuyên bạn nên xem SO này: HTTP GET with request body để biết thêm thông tin và một số liên kết hữu ích về chủ đề này.

Tương tự, khi sử dụng jQuery - bạn không cần chuyển đổi đối tượng thành JSON - chỉ cần chuyển đối tượng javascript trong thành viên data của các tùy chọn và jQuery biến nó thành định dạng đúng.

Hoặc nên có, Web API hiểu định dạng mà jQuery chuyển nó thành.

+1

Cảm ơn, tôi đã gãi đầu vì sao một tham số 'đối tượng phức tạp' không được điền mặc dù tôi đã trang trí nó bằng '[FromUri]'. Tôi đã cố gắng để vượt qua trong json ví dụ ? param = {Tên: Foo} không hoạt động, tôi phải đổi tên thành? Name = Foo như bạn đã nói. Lưu ý rằng nếu bạn có nhiều tham số đối tượng phức tạp '[FromUri]', bạn cần đảm bảo rằng chúng không có các thuộc tính có cùng tên - hoặc bạn sẽ kết thúc với cùng một giá trị thuộc tính được gán cho cả hai cá thể. –

+2

Xin lưu ý rằng một 'chuỗi thành viên công cộng1;' đơn giản sẽ không hoạt động và 'member1' vẫn sẽ là' null'. Biến chúng thành ** thuộc tính ** và nó sẽ hoạt động tốt. – Thomas

+0

về họ phải là tài sản ... tại sao tôi không đọc điều này 4 giờ trước. nói về cảm giác ngu ngốc, cảm ơn Thomas vì lời bình luận đơn giản nhưng tuyệt vời này. –

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