HttpPost and webapi

本文关键字:webapi and HttpPost | 更新日期: 2023-09-27 18:02:16

我创建了一个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个错误。帮我一把,伙计们。

HttpPost and webapi

. NET Web API不能与HttpPostedFile一起工作。相反,您应该使用MultipartFormDataStreamProvider,如following tutorial所示。

你的客户端调用也是错误的。您已经将ContentType设置为multipart/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());
    }
}

,然后你可以使用HttpClient来调用这个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);
        }
    }
}

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

你应该坚持webapi路由命名约定,以节省一些麻烦。

所有名为PostSomething()的方法将被接受为HttpPost。它们的参数签名将区分你是否需要两个同名的。

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

在WebApi中路由基础设置错误是HTTP/500的根本原因,并将导致你的异常

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

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