25

リリース候補ビットを使用して再構築したベータ ビットを使用した Web API サービスがあり、現在この問題が発生しています。

唯一のパラメータとして複雑なオプションを取る POST アクションがあります。json 形式の本文でリクエストを送信すると、オブジェクトは期待どおりに逆シリアル化されますが、代わりに XML を送信すると、パラメーターは null になります。

ベータ版では、Carlos Figueira のブログ投稿Disabling model binding on ASP.NET Web APIs Betaで説明されているように、モデル バインディングを無効にすることでこれを回避しました。

ただし、RC では、このメソッドが実装していた IRequestContentReadPolicy を削除しました。

私の行動:

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

私のモデル:

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

Fiddler を使用してサービスにリクエストを送信するテストを行っています。

これは機能し、期待される結果を返します。

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

requestValues パラメータが 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>
4

2 に答える 2

26

Global.asax.csのApplicationStart()メソッドに次の行を追加すると、元のXMLリクエストが機能するはずです。

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

デフォルトでは、Web APIはDataContractSerializerクラスを使用します。これは、XML要求に追加情報を必要とします。

XmlSerializerは、各XMLリクエストにモデルの名前を追加する必要がないため、よりスムーズに機能するようです。

もう一度、Mike Wassonの記事で私の情報を見つけました:http ://www.asp.net/web-api/overview/formats-and-model-binding/json-and-xml-serialization#xml_media_type_formatter

于 2012-06-27T17:38:36.440 に答える
5

私はあなたと同じ問題を抱えていましたが、ここで説明されているようにXmlMediaTypeFormatterを使用してオブジェクトをシリアル化することで解決策を見つけました:http ://www.asp.net/web-api/overview/formats-and-model-binding/json-および-xml-serialization#testing_object_serialization。記事の下部にある「オブジェクトのシリアル化のテスト」セクションのコードを使用し、彼のPersonオブジェクトを私のモデルに置き換えました。

オブジェクトをシリアル化すると、次の属性がルートノードに追加されていることに気付きました。

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

このようにこれらの属性をxmlに追加する場合、コントローラーは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>
于 2012-06-27T15:31:48.313 に答える