2012-06-21 19 views
23

Tôi có dịch vụ api web ban đầu sử dụng các bit beta mà tôi đã xây dựng lại bằng cách sử dụng bit ứng cử viên phát hành và hiện tôi đang gặp sự cố này.Tham số POST của AspNet WebApi là null khi gửi XML

Tôi có một hành động POST có tùy chọn phức tạp làm thông số duy nhất. Khi tôi gửi yêu cầu với cơ thể trong định dạng json, đối tượng được deserialised như mong đợi, nhưng nếu tôi gửi XML thay vì tham số là null.

Trong các phiên bản beta tôi đã làm việc này bằng cách vô hiệu hóa ràng buộc như được mô tả trong bài viết trên blog Carlos Figueira của Disabling model binding on ASP.NET Web APIs Beta

Trong RC tuy nhiên họ đã gỡ bỏ các IRequestContentReadPolicy rằng phương pháp này đã được thực hiện mô hình.

hành động của tôi:

public List<Models.Payload> Post([FromBody]Models.AimiRequest requestValues) 
{ 
    try 
    { 
    if (requestValues == null) 
    { 
     var errorResponse = new HttpResponseMessage(); 
     errorResponse.StatusCode = HttpStatusCode.NotFound; 
     errorResponse.Content = new StringContent("parameter 'request' is null"); 
     throw new HttpResponseException(errorResponse); 
    } 
    var metadataParams = new List<KeyValuePair<string, string>>(); 
    foreach (Models.MetadataQueryParameter param in requestValues.Metadata) 
    { 
     metadataParams.Add(new KeyValuePair<string, string>(param.Name, param.Value)); 
    } 
    List<Core.Data.Payload> data = _payloadService.FindPayloads(metadataParams, requestValues.ContentType, requestValues.RuleTypes); 
    var retVal = AutoMapper.Mapper.Map<List<Core.Data.Payload>, List<Models.Payload>>(data); 
    return retVal; // new HttpResponseMessage<List<Models.Payload>>(retVal); 
    } 
    catch (System.Exception ex) 
    { 
    _logger.RaiseError(ex); 
    throw; 
    } 
} 

mô hình của tôi:

public class AimiRequest 
{ 
    public MetadataQueryParameter[] Metadata { get; set; } 
    public string ContentType { get; set; } 
    public string RuleTypes { get; set; } 
} 

public class MetadataQueryParameter 
{ 
    public string Name { get; set; } 
    public string Value { get; set; } 
} 

Tôi đang thử nghiệm sử dụng Fiddler để gửi yêu cầu đến dịch vụ.

Tác phẩm này sẽ trả về kết quả mong đợi.

POST http://localhost:51657/api/search HTTP/1.1 
User-Agent: Fiddler 
Content-Type: application/json; charset=utf-8 
Accept: application/json 
Host: localhost:51657 
Content-Length: 219 

{ 
    "ContentType":null, 
    "RuleTypes":null, 
    "Metadata":[ 
    { 
    "Name":"ClientName", 
    "Value":"Client One" 
    }, 
    { 
    "Name":"ClientName", 
    "Value":"Client Two" 
    } 
    ] 
} 

này sai vì các tham số requestValues ​​là null

POST http://localhost:51657/api/search HTTP/1.1 
User-Agent: Fiddler 
Content-Type: application/xml; charset=utf-8 
Accept: application/xml 
Host: localhost:51657 
Content-Length: 213 

<AimiRequest> 
    <ContentType /> 
    <RuleTypes /> 
    <Metadata> 
    <MetadataQueryParameter> 
     <Name>ClientName</Name> 
     <Value>Client One</Value> 
    </MetadataQueryParameter> 
    <MetadataQueryParameter> 
     <Name>ClientName</Name> 
     <Value>Client Two</Value> 
    </MetadataQueryParameter> 
    </Metadata> 
</AimiRequest> 
+0

Xem chi tiết tại đây [câu hỏi] [1] ... [1]: http://stackoverflow.com/questions/14068288/model-always-null-on-xml-post – barrypicker

Trả lời

24

Bằng cách thêm các dòng sau vào phương pháp ApplicationStart() trong Global.asax.cs của bạn, yêu cầu XML ban đầu của bạn nên làm việc:

var xml = GlobalConfiguration.Configuration.Formatters.XmlFormatter; 
xml.UseXmlSerializer = true; 

Theo mặc định, API Web sử dụng lớp DataContractSerializer, yêu cầu thông tin bổ sung trong yêu cầu XML.

Trình XmlSerializer dường như hoạt động trơn tru hơn cho tôi, vì tôi không phải thêm tên mẫu của mô hình vào mỗi yêu cầu XML.

Một lần nữa, tôi tìm thấy thông tin của tôi trong bài viết Mike Wasson của: http://www.asp.net/web-api/overview/formats-and-model-binding/json-and-xml-serialization#xml_media_type_formatter

+0

đây là giải pháp tôi đang tìm kiếm.Tôi đã có cùng một vấn đề mà json sẽ làm việc tốt, nhưng đối tượng sẽ luôn luôn là null khi sử dụng xml –

+0

không làm việc cho tôi. bây giờ ứng dụng đang quay trở lại "Ứng dụng loại phương tiện của yêu cầu '/ xml' không được hỗ trợ cho tài nguyên này". – gkon

5

Tôi đã gặp vấn đề tương tự như bạn, và tìm thấy các giải pháp bằng cách tuần tự các đối tượng sử dụng XmlMediaTypeFormatter như đã mô tả ở đây: http://www.asp.net/web-api/overview/formats-and-model-binding/json-and-xml-serialization#testing_object_serialization. Tôi đã sử dụng mã trong phần "Kiểm tra đối tượng tuần tự hóa" ở cuối bài viết và thay thế đối tượng Person của mình bằng mô hình của tôi.

Khi tôi đăng đối tượng của tôi, tôi nhận thấy rằng các thuộc tính sau đây đã được bổ sung vào nút gốc:

xmlns:i="http://www.w3.org/2001/XMLSchema-instance" 
xmlns="http://schemas.datacontract.org/2004/07/NAMESPACE.OF.YOUR.MODEL" 

Nếu bạn thêm các thuộc tính để xml của bạn như vậy, điều khiển của bạn một cách chính xác nên serialize đối tượng các requestValues:

<AimiRequest xmlns:i="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns="http://schemas.datacontract.org/2004/07/NAMESPACE.OF.YOUR.MODEL"> 
    <ContentType /> 
    <RuleTypes /> 
    <Metadata> 
    <MetadataQueryParameter> 
     <Name>ClientName</Name> 
     <Value>Client One</Value> 
    </MetadataQueryParameter> 
    <MetadataQueryParameter> 
     <Name>ClientName</Name> 
     <Value>Client Two</Value> 
    </MetadataQueryParameter> 
    </Metadata> 
</AimiRequest> 
Các vấn đề liên quan