2013-03-25 31 views
5

Tôi có một hành động WebApi hiện có, mà tôi muốn chuyển từ HttpPost sang HttpGet. Nó hiện đang mất một đối tượng phức tạp duy nhất làm tham số.MVC WebApi HttpGet với đối tượng phức tạp

Mô hình:

public class BarRequest 
{ 
    [JsonProperty("catid")] 
    public int CategoryId { get; set; } 
} 

Bộ điều khiển:

public class FooController : ApiController 
{ 
    //[HttpPost] 
    [HttpGet] 
    [ActionName("bar")] 
    public void Bar([FromUri] BarRequest request) 
    { 
     if (request != null) 
     { 
      // CategoryId should be 123, not 0 
      Debug.WriteLine("Category ID :: {0}", request.CategoryId); 
     } 
    } 
} 

Bây giờ khi tôi gửi yêu cầu sau đây, mọi thứ hoạt động như mong đợi.

GET /foo/bar?CategoryId=123 

Ngoài ra, yêu cầu POST cũ đã hoạt động như mong đợi.

POST /foo/bar {"catid":123} 

Nhưng bây giờ tôi cần những yêu cầu sau đây để làm việc:

GET /foo/bar?catid=123 

Làm thế nào tôi có thể thực hiện điều này?

+0

Tại sao không chỉ sử dụng CategoryID để thực hiện việc này? Hoặc tại sao không sử dụng CatID làm tên thuộc tính hoặc sử dụng CATID làm tham số cho phương thức? –

+0

Mô hình thực tế có nhiều tính chất hơn. Không thể thay đổi việc đặt tên thuộc tính (đặt tên hướng dẫn ở mỗi bên - máy chủ/C# và máy khách/js). –

Trả lời

11

Cảm ơn bạn đã đề xuất, nhưng giải pháp duy nhất phù hợp với tôi, là như sau.

Trước:

var data = { 
    catid: 123, 
    // <snip> 
}; 
var json = JSON.stringify(data); 
$.post('/foo/bar', json, callback); 
public class FooController : ApiController 
{ 
    [HttpPost, ActionName("bar")] 
    public void Bar(BarRequest request) 
    { 
     // use request.Category to process request 
    } 
} 

Sau:

var data = { 
    catid: 123, 
    // <snip> 
}; 
var json = JSON.stringify(data); 
$.get('/foo/bar?data=' + encodeURIComponent(json), callback); 
public class FooController : ApiController 
{ 
    [HttpGet, ActionName("bar")] 
    public void Bar(string data) 
    { 
     var request = JsonConvert.DeserializeObject<BarRequest>(data); 
     // use request.Category to process request 
    } 
} 

Bằng cách này tôi không cần phải chạm vào bất kỳ mô hình, validator , vv trên máy khách hoặc máy chủ. Ngoài ra, mọi giải pháp khác đều yêu cầu tôi thay đổi quy ước đặt tên trên máy chủ hoặc phía máy khách.

+0

Cảm ơn bạn, đây là _exactly_ câu trả lời tôi đang tìm kiếm vì tôi muốn đạt được kết quả rất giống nhau. – staticboy

+0

Hãy nhớ rằng với phương pháp này bạn bị mất các chức năng như xác nhận thuộc tính. –

1

bạn có thể làm điều đó bằng cách sử dụng DataContracts và DataMember thuộc tính:

http://msdn.microsoft.com/en-us/library/ms733127.aspx

[DataContract] 
public class BarRequest{ 

    [DataMember(Name="catid")] 
    public int CategoryId { get; set; } 
} 

nếu đó là một phương pháp bài

nhưng với phương pháp get đây là một ví dụ về cấu trúc cho các đối tượng phức tạp:

api/Bar?request.CategoryId =1&request.AnotherProp=foo 
+0

Đã thử nó, nhưng nó là kết quả tương tự như với JsonProperty; CategoryId vẫn là 0 (giá trị mặc định). –

+1

bạn áp dụng phương pháp này: 'JsonConvert.DeserializeObject (json);'? –

+0

Ý của bạn là gì? Khách hàng có nên gửi json qua GET không? –

0

Có phương pháp mở rộng trên URI trong System.Net.Http.UriExtensions sẽ thực hiện chính xác những gì bạn muốn: TryReadQueryAs<T>(out T model). Bạn có thể nhận được URI từ yêu cầu của bạn trong một ApiController: Request.RequestUri. Dưới đây là hình thức của nó:

public class FooController : ApiController 
{ 
    //[HttpPost] 
    [HttpGet] 
    [ActionName("bar")] 
    public void Bar() 
    { 
     BarRequest request; 
     if (Request.RequestUri.TryReadQueryAs(out model)) 
     { 
      // CategoryId should be 123, not 0 
      Debug.WriteLine("Category ID :: {0}", request.CategoryId); 
     } 
    } 
} 

Điều này chỉ có thể hoạt động nếu bạn chỉ định [DataContract] như được đề xuất.Tuy nhiên, hãy chú ý rằng chuỗi truy vấn trống sẽ phân tích cú pháp, vì vậy nếu bạn đã từng làm điều gì đó khác nhau tùy thuộc vào việc dữ liệu đã được POST chỉnh sửa hay chưa, bạn sẽ cần phải kiểm tra tính hợp lệ của mô hình của mình. Hy vọng bạn đã làm điều đó dù sao.

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