在.NET中使用JSON Web服务并使用多部分POST请求数据的最佳方法

时间:2011-07-15 06:35:38

标签: .net web-services post

我正在开发一个需要使用Web服务的应用程序。

Web服务正在远程服务器上运行,它接受POST请求并返回JSON数据

以下是使用“curl”消费服务的示例

curl -F "api_key=ABCDEFGHIJKL" -F "query=@json_string.json" "http://serv/api/v4/song/identify"

带有Content-Type“multipart / form-data”的HTTP POST请求,其中所有参数都在帖子正文中,查询位于帖子“files”的“query”参数中

那么我怎样才能实现客户端来使用.NET中的服务

1 个答案:

答案 0 :(得分:2)

您可以使用WCF REST serviceparse the multipart/form-data


更新:

抱歉,我误解了你的问题。您正在寻找如何编写客户端。在我的blog post中,我建议了一个示例类,它允许将多个文件与参数一起上传到multipart/form-data启用的服务。它是这样的:

public class UploadFile
{
    public UploadFile()
    {
        ContentType = "application/octet-stream";
    }
    public string Name { get; set; }
    public string Filename { get; set; }
    public string ContentType { get; set; }
    public Stream Stream { get; set; }
}

然后是一个完成工作的方法:

public byte[] UploadFiles(string address, IEnumerable<UploadFile> files, NameValueCollection values)
{
    var request = WebRequest.Create(address);
    request.Method = "POST";
    var boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x", NumberFormatInfo.InvariantInfo);
    request.ContentType = "multipart/form-data; boundary=" + boundary;
    boundary = "--" + boundary;

    using (var requestStream = request.GetRequestStream())
    {
        // Write the values
        foreach (string name in values.Keys)
        {
            var buffer = Encoding.ASCII.GetBytes(boundary + Environment.NewLine);
            requestStream.Write(buffer, 0, buffer.Length);
            buffer = Encoding.ASCII.GetBytes(string.Format("Content-Disposition: form-data; name=\"{0}\"{1}{1}", name, Environment.NewLine));
            requestStream.Write(buffer, 0, buffer.Length);
            buffer = Encoding.UTF8.GetBytes(values[name] + Environment.NewLine);
            requestStream.Write(buffer, 0, buffer.Length);
        }

        // Write the files
        foreach (var file in files)
        {
            var buffer = Encoding.ASCII.GetBytes(boundary + Environment.NewLine);
            requestStream.Write(buffer, 0, buffer.Length);
            buffer = Encoding.UTF8.GetBytes(string.Format("Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"{2}", file.Name, file.Filename, Environment.NewLine));
            requestStream.Write(buffer, 0, buffer.Length);
            buffer = Encoding.ASCII.GetBytes(string.Format("Content-Type: {0}{1}{1}", file.ContentType, Environment.NewLine));
            requestStream.Write(buffer, 0, buffer.Length);
            file.Stream.CopyTo(requestStream);
            buffer = Encoding.ASCII.GetBytes(Environment.NewLine);
            requestStream.Write(buffer, 0, buffer.Length);
        }

        var boundaryBuffer = Encoding.ASCII.GetBytes(boundary + "--");
        requestStream.Write(boundaryBuffer, 0, boundaryBuffer.Length);
    }

    using (var response = request.GetResponse())
    using (var responseStream = response.GetResponseStream())
    using (var stream = new MemoryStream())
    {
        responseStream.CopyTo(stream);
        return stream.ToArray();
    }
}

最后是客户:

using (var stream1 = File.Open("test.txt", FileMode.Open))
using (var stream2 = File.Open("test.xml", FileMode.Open))
using (var stream3 = File.Open("test.pdf", FileMode.Open))
{
    var files = new[] 
    {
        new UploadFile
        {
            Name = "file",
            Filename = "test.txt",
            ContentType = "text/plain",
            Stream = stream1
        },
        new UploadFile
        {
            Name = "file",
            Filename = "test.xml",
            ContentType = "text/xml",
            Stream = stream2
        },
        new UploadFile
        {
            Name = "file",
            Filename = "test.pdf",
            ContentType = "application/pdf",
            Stream = stream3
        }
    };

    var values = new NameValueCollection
    {
        { "key1", "value1" },
        { "key2", "value2" },
        { "key3", "value3" },
    };

    byte[] result = UploadFiles("http://localhost:1234/upload", files, values);
    // TODO: process the result
}