12

新しい webapi にはトリックがありません。ポスト リクエストを介して xml 文字列を送信しようとしていますが、うまくいきません。

フロント エンドでは、次のように jQuery を使用しています。

    $(document = function () {
    $("#buttonTestAPI").click(function () {

        var d = " <customer><customer_id>1234</customer_id></customer>";
        $.ajax({
            type: 'POST',
            contentType: "text/xml",
            url: "@Url.Content("~/api/Customer/")",
            data: d,
            success: function (result) {
                var str = result;
                $("#output").html(str);
            }
        });
    });
});

私のコントローラーは現時点では非常に単純です-ポストアクションのデフォルトにすぎません-渡されたものを返そうとしています:

    public string Post(string value)
    {
        return value;
    }

ただし、「値」は繰り返し null です。奇妙なことに、jquery のデータを次のように変更すると、次のようになります。

d = "<customer_id>1234</customer_id>";

次に、コントローラーで「値」を1234として取得します。

コントローラーでより複雑な xml 文字列にアクセスするにはどうすればよいですか?

4

4 に答える 4

18

以下では、Web API メソッドへの POST を介して生の XML メッセージを読み取ることができます。

public void PostRawXMLMessage(HttpRequestMessage request)
{
   var xmlDoc = new XmlDocument();
   xmlDoc.Load(request.Content.ReadAsStreamAsync().Result);   
}

本文、ヘッダーなどをデバッグおよび検査すると、投稿された生の XML が表示されます。Fiddler の Composer を使用して HTTP POST を作成しましたが、これはうまく機能します。

于 2013-01-11T21:56:46.257 に答える
13

のコンテンツ タイプを送信してtext/xmlいますが、パラメータを として定義していますstring。理想的には、XML をクラスにマップして、デシリアライズできるようにする必要があります。

そのため、生の xmlが必要な場合は、まだサポートされていません。Web API は現在、シリアライゼーション MediaTypeFormatters と不足している単純型フォーマッタに対応していますが、簡単に構築できます。

これは、あなたのケースで読み取りのみをサポートし、ベータインストーラーに基づいたそのようなフォーマッターの最小限の実装です(大幅に変更されたため、夜間のソースコードではありません):

public class TextMediaTypeFormatter : MediaTypeFormatter
{
    public TextMediaTypeFormatter()
    {
        SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/xml"));
        SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/plain"));
        SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/javascript"));
    }

    protected override bool CanReadType(Type type)
    {
        return type == typeof (string);
    }

    protected override System.Threading.Tasks.Task<object> OnReadFromStreamAsync(Type type, Stream stream, 
        HttpContentHeaders contentHeaders, 
        FormatterContext formatterContext)
    {
        var taskCompletionSource = new TaskCompletionSource<object>();
        try
        {
            var memoryStream = new MemoryStream();
            stream.CopyTo(memoryStream);
            var s = System.Text.Encoding.UTF8.GetString(memoryStream.ToArray());
            taskCompletionSource.SetResult(s);
        }
        catch (Exception e)
        {
            taskCompletionSource.SetException(e);           
        }
        return taskCompletionSource.Task;
    }
}

それを使用するには、フォーマッタ コレクションに追加するだけです。

GlobalConfiguration.Configuration.Formatters.Insert(0, new TextMediaTypeFormatter());
于 2012-05-03T10:42:04.490 に答える
6

ベータリリースからasp.netmvc4 web apiのRCまでの上記のAliostadの回答の更新バージョンを探している人は誰でも(マイナーな変更は私にとってわずかな手直しをもたらしました)。

public class TextMediaTypeFormatter : MediaTypeFormatter
{

    public TextMediaTypeFormatter()
    {
        SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/xml"));
        SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/plain"));
        SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/javascript"));
    }

    public override bool CanReadType(Type type)
    {
        if (type == typeof(String))
            return true;
        else
            return false;
    }

    public override bool CanWriteType(Type type)
    {
        if (type == typeof(String))
            return true;
        else
            return false;

    }

    public override Task<object> ReadFromStreamAsync(Type type, Stream readStream, System.Net.Http.HttpContent content, IFormatterLogger formatterLogger)
    {
        var taskCompletionSource = new TaskCompletionSource<object>();
        try
        {
            var memoryStream = new MemoryStream();
            readStream.CopyTo(memoryStream);
            var s = System.Text.Encoding.UTF8.GetString(memoryStream.ToArray());
            taskCompletionSource.SetResult(s);
        }
        catch (Exception e)
        {
            taskCompletionSource.SetException(e);
        }
        return taskCompletionSource.Task;
    }
}
于 2012-08-31T16:07:49.307 に答える
0

私にとって問題を解決したのは、これを追加することでした:

static SubscriberController()
{
    //Needed for xml deserialization to work
    var xml = GlobalConfiguration.Configuration.Formatters.XmlFormatter;
    xml.UseXmlSerializer = true;
}

(SubscriberControllerを拡張する私のクラスでApiControllerあり、上記は静的コンストラクターであるため、一度実行されます)。

それも必要かどうかはわかりませんが[FromBody]、次のように属性をパラメーターに追加しました。

public async Task<HttpResponseMessage> SynchronizeImax( [FromBody] SynchronizeRequest synchronizeRequest )
{
    //...
}

この方法の優れた点は、XML 入力と JSON 入力の両方をシームレスに処理できることです。

于 2016-01-28T06:15:18.947 に答える