ASP.NET MVC4 WebAPI和发布XML数据

Tho*_*mas 12 xml asp.net-mvc asp.net-mvc-4 asp.net-web-api

我错过了一个新的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);
            }
        });
    });
});
Run Code Online (Sandbox Code Playgroud)

我的控制器目前非常简单 - 只是后期操作的默认设置 - 尝试返回传入的内容:

    public string Post(string value)
    {
        return value;
    }
Run Code Online (Sandbox Code Playgroud)

但是,"值"重复为空.奇怪的是,当我在jquery中更改我的数据时,就像这样:

d = "<customer_id>1234</customer_id>";
Run Code Online (Sandbox Code Playgroud)

然后我在控制器中得到"值"为1234.

如何访问控制器中更复杂的xml字符串?

atc*_*way 18

以下内容允许您通过POST将原始XML消息读取到Web API方法:

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

您可以调试和检查正文,标题等,并会看到发布的原始XML.我使用Fiddler的Composer进行HTTP POST,这很有效.


Ali*_*tad 13

您正在发送内容类型,text/xml但您已将参数定义为string.理想情况下,您的XML应该映射到一个类,以便可以反序列化.

因此,如果您需要原始xml,那么它还不受支持.Web API目前已准备好用于序列化MediaTypeFormatters和缺少简单类型格式化程序,但它们可以轻松构建.

这个是这种格式化程序的最小实现,只支持在你的情况下读取并基于beta安装程序(而不是夜间源代码,因为它已经发生了实质性的改变):

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

要使用它,只需将其添加到格式化程序集合:

GlobalConfiguration.Configuration.Formatters.Insert(0, new TextMediaTypeFormatter());
Run Code Online (Sandbox Code Playgroud)


BMa*_*Mac 6

任何人都在寻找更新版本的Aliostad上面的答案,从测试版发布到asp.net mvc 4 web api的RC(微小的变化导致我的轻微修改).

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;
    }
}
Run Code Online (Sandbox Code Playgroud)