3

我创建了一个 API,它将文件作为输入并对其进行处理。样本是这样的...

[HttpPost]
    public string ProfileImagePost(HttpPostedFile HttpFile)
    {

      //rest of the code
     }

然后我创建了一个客户端来使用它,如下所示......

 string path = @"abc.csv";
        FileStream rdr = new FileStream(path, FileMode.Open, FileAccess.Read);
        byte[] inData = new byte[rdr.Length];
        rdr.Read(inData, 0, Convert.ToInt32(rdr.Length));

        HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://localhost/abc/../ProfileImagePost");
        req.KeepAlive = false;
        req.ContentType = "multipart/form-data"; 
        req.Method = "POST";
        req.ContentLength = rdr.Length;
        req.AllowWriteStreamBuffering = true;

        Stream reqStream = req.GetRequestStream();

        reqStream.Write(inData, 0, Convert.ToInt32(rdr.Length));
        reqStream.Close();
        HttpWebResponse TheResponse = (HttpWebResponse)req.GetResponse();
        string TheResponseString1 = new StreamReader(TheResponse.GetResponseStream(), Encoding.ASCII).ReadToEnd();
        TheResponse.Close();

但是我在客户端收到 500 错误。帮帮我吧伙计们。

提前谢谢...

4

4 回答 4

5

ASP.NET Web API 不适用于HttpPostedFile. 相反,您应该使用MultipartFormDataStreamProviderfollowing tutorial.

您的客户端调用也是错误的。您已将其设置为ContentTypemultipart/form-data但您根本不尊重此编码。您只是将文件写入请求流。

所以我们举个例子:

public class UploadController : ApiController
{
    public Task<HttpResponseMessage> Post()
    {
        if (!Request.Content.IsMimeMultipartContent())
        {
            throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
        }

        string root = HostingEnvironment.MapPath("~/App_Data");
        var provider = new MultipartFormDataStreamProvider(root);

        // Read the form data
        return Request.Content.ReadAsMultipartAsync(provider).ContinueWith(t =>
        {
            // This illustrates how to get the file names.
            foreach (MultipartFileData file in provider.FileData)
            {
                Trace.WriteLine(file.Headers.ContentDisposition.FileName);
                Trace.WriteLine("Server file path: " + file.LocalFileName);
            }
            return Request.CreateResponse(HttpStatusCode.OK);
        }, TaskScheduler.FromCurrentSynchronizationContext());
    }
}

然后你可以使用 anHttpClient来调用这个 API:

using System;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;

class Program
{
    static void Main(string[] args)
    {
        using (var client = new HttpClient())
        using (var content = new MultipartFormDataContent())
        {
            client.BaseAddress = new Uri("http://localhost:16724/");
            var fileContent = new ByteArrayContent(File.ReadAllBytes(@"c:\work\foo.txt"));
            fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
            {
                FileName = "Foo.txt"
            };
            content.Add(fileContent);
            var result = client.PostAsync("/api/upload", content).Result;
            Console.WriteLine(result.StatusCode);
        }
    }
}
于 2013-03-04T06:44:15.987 回答
1

而不是 HttpPostedFile ,直接从客户端发送文件作为流,并在服务器端读取文件作为流,如:

 //read uploaded csv file at server side
 Stream csvStream = HttpContext.Current.Request.Files[0].InputStream;

//Send file from client 
 public static void PostFile()
 {
       string[] files = { @"C:\Test.csv" };

        string url = "http://localhost/abc/../test.xml";
        long length = 0;
        string boundary = "----------------------------" +
        DateTime.Now.Ticks.ToString("x");

        HttpWebRequest httpWebRequest2 = (HttpWebRequest)WebRequest.Create(url);
        httpWebRequest2.ContentType = "multipart/form-data; boundary=" +
        boundary;
        httpWebRequest2.Method = "POST";
        httpWebRequest2.KeepAlive = true;
        httpWebRequest2.Credentials =
        System.Net.CredentialCache.DefaultCredentials;

        Stream memStream = new System.IO.MemoryStream();
        byte[] boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" +
        boundary + "\r\n");

        string formdataTemplate = "\r\n--" + boundary +
        "\r\nContent-Disposition: form-data; name=\"{0}\";\r\n\r\n{1}";

        memStream.Write(boundarybytes, 0, boundarybytes.Length);

        string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\n Content-Type: application/octet-stream\r\n\r\n";

        for (int i = 0; i < files.Length; i++)
        {
            //string header = string.Format(headerTemplate, "file" + i, files[i]);
            string header = string.Format(headerTemplate, "uplTheFile", files[i]);

            byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header);

            memStream.Write(headerbytes, 0, headerbytes.Length);

            FileStream fileStream = new FileStream(files[i], FileMode.Open,
            FileAccess.Read);
            byte[] buffer = new byte[1024];

            int bytesRead = 0;

            while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
            {
                memStream.Write(buffer, 0, bytesRead);
            }

            memStream.Write(boundarybytes, 0, boundarybytes.Length);
            fileStream.Close();
        }

        httpWebRequest2.ContentLength = memStream.Length;
        Stream requestStream = httpWebRequest2.GetRequestStream();

        memStream.Position = 0;
        byte[] tempBuffer = new byte[memStream.Length];
        memStream.Read(tempBuffer, 0, tempBuffer.Length);
        memStream.Close();
        requestStream.Write(tempBuffer, 0, tempBuffer.Length);
        requestStream.Close();

        WebResponse webResponse2 = httpWebRequest2.GetResponse();

        Stream stream2 = webResponse2.GetResponseStream();
        StreamReader reader2 = new StreamReader(stream2);

        webResponse2.Close();
        httpWebRequest2 = null;
        webResponse2 = null;
    }
于 2013-03-04T06:56:22.000 回答
0

这是我在客户端发布屏幕截图的代码

    public void PostMethod()
    {
    ImageConverter converter = new ImageConverter();
    var bytes = (byte[])converter.ConvertTo(bmpScreenshot, typeof(byte[]));
    StringConverter s = new StringConverter();

    string uri = "http://localhost:3844/api/upload";

    byte[] postBytes = bytes;
    string str = Properties.Settings.Default.token.ToString(); //after login user receives a response token, it is stored in the application settings. All Posts save in db with a this token

    byte[] bA = ASCIIEncoding.ASCII.GetBytes(str);

    MultipartFormDataContent multiPartData = new MultipartFormDataContent();

    ByteArrayContent byteArrayContent = new ByteArrayContent(postBytes);
    ByteArrayContent bAC = new ByteArrayContent(bA);
    multiPartData.Add(bAC, "token");
    multiPartData.Add(byteArrayContent,"picture");

    HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Post, uri);
    requestMessage.Content = multiPartData;

    HttpClient httpClient = new HttpClient();
    Task<HttpResponseMessage> httpRequest = httpClient.SendAsync(requestMessage);
    HttpResponseMessage httpResponse = httpRequest.Result;
    HttpContent responseContent = httpResponse.Content;
}

服务器端

public class UploadController : ApiController
    {
public masterEntities context = new masterEntities();
public ImgEntitySet imgEntity = new ImgEntitySet();
public async Task<HttpResponseMessage> PostRawBufferManual()
{
MultipartFormDataStreamProvider streamProvider = new MultipartFormDataStreamProvider("~/App_Data");
MultipartFileStreamProvider dataContent = await Request.Content.ReadAsMultipartAsync(streamProvider);
            foreach (HttpContent data in dataContent.Contents)
            {
                string fileName = data.Headers.ContentDisposition.Name;
                byte[] n = await data.ReadAsByteArrayAsync();
                string m = Encoding.ASCII.GetString(n);
                int z = int.Parse(m);
                imgEntity.UID = z;
                break;
            }
            foreach (HttpContent data in dataContent.Contents)
            {
                string fileNamePicture = data.Headers.ContentDisposition.Name;
                if (fileNamePicture == "picture")
                {
                    byte[] b = await data.ReadAsByteArrayAsync();
                    imgEntity.Image = b;
                }
            }

            context.ImgEntitySet.Add(imgEntity);
            context.SaveChanges();
            return Request.CreateResponse(HttpStatusCode.OK );
        }
}
于 2014-10-29T13:09:13.737 回答
0

您应该坚持使用 webapi 路由命名约定以节省一些麻烦。

所有名为 PostSomething() 的方法都将被接受为 HttpPost。他们的参数签名会告诉他们你需要两个同名的。

因此,调用您的 WebApi 方法 PostProfileImage(HttpPostedFile 文件),然后您可以将文件作为数据发布到 http:///api//。

在 WebApi 中弄错路由基础是 HTTP/500 的根本原因,并且会导致异常。

于 2014-07-13T08:05:05.390 回答