2012-06-21 9 views
23

Ich habe einen Web-API-Service ursprünglich mit Beta-Bits, die ich mit den Release-Kandidaten-Bits umgebaut habe und ich habe jetzt dieses Problem.AspNet WebApi POST-Parameter ist Null beim Senden von XML

Ich habe eine POST-Aktion, die eine komplexe Option als einzigen Parameter verwendet. Wenn ich die Anfrage mit dem Body im JSON-Format sende, wird das Objekt wie erwartet deserialisiert, aber wenn ich stattdessen XML sende, ist der Parameter null.

In der Beta-I-Bindung durch die Deaktivierung Modell um das funktionierte wie in Carlos Figueira Blogbeitrag beschrieben Disabling model binding on ASP.NET Web APIs Beta

Im RC aber sie IRequestContentReadPolicy entfernt haben, dass diese Methode wurde implementiert.

Meine Aktion:

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

Mein Modell:

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

Ich teste Fiddler mit Anfragen an den Dienst zu senden.

Dies funktioniert und gibt mir die erwarteten Ergebnisse zurück.

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" 
    } 
    ] 
} 

Dies schlägt fehl, da der requestValues ​​Parameter

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

Details sehen in dieser [Frage] [1] ... [1]: http://stackoverflow.com/questions/14068288/model-always-null-on-xml-post – barrypicker

Antwort

24

Durch das Hinzufügen der folgenden Zeilen an den ApplicationStart() -Methode in Ihrem Global.asax.cs, Ihre ursprüngliche XML-Anforderung sollte funktionieren:

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

Standardmäßig verwendet die Web-API die DataContractSerializer-Klasse, die zusätzliche Informationen in der XML-Anforderung erfordert.

Der XmlSerializer scheint für mich reibungsloser zu arbeiten, da ich die XML-Anforderung des Modells nicht jedem XML-Request hinzufügen muss.

Wieder einmal fand ich meine Informationen in Mike Wassons Artikel: http://www.asp.net/web-api/overview/formats-and-model-binding/json-and-xml-serialization#xml_media_type_formatter

+0

das war die lösung, nach der ich gesucht habe.Ich hatte das gleiche Problem, wo Json würde gut funktionieren, aber Objekt wäre immer Null, wenn XML –

+0

nicht für mich arbeiten. Jetzt gibt die App zurück "Der Medientyp der Anforderungs-Entität 'application/xml' wird für diese Ressource nicht unterstützt.". – gkon

5

null ist, ich wurde, wie Sie das gleiche Problem, und fand die Lösung durch das Objekt Serialisierung der XmlMediaTypeFormatter mit wie hier beschrieben: http://www.asp.net/web-api/overview/formats-and-model-binding/json-and-xml-serialization#testing_object_serialization. Ich habe den Code im Abschnitt "Testing Object Serialization" am Ende des Artikels verwendet und sein Person-Objekt durch mein Modell ersetzt.

Wenn ich mein Objekt serialisiert, bemerkte ich, dass die folgenden Attribute zu dem Wurzelknoten hinzugefügt wurden:

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

Wenn Sie diese Attribute zu Ihrem xml hinzufügen wie so, Ihr Controller sollte richtig die requestValues ​​serialisiert Objekt:

<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> 
Verwandte Themen