【问题标题】:c# webrequest post image to web apic# webrequest 将图像发布到 web api
【发布时间】:2017-01-24 19:05:27
【问题描述】:

我在将图像上传到正在运行的 Web API 时遇到问题。使用 GET 请求时,我可以从 Web API 检索数据,但在使用 POST 请求时遇到问题。我需要将 BMP 图片上传到 Web API,然后发回一个 json 字符串。

[HttpPost]
public IHttpActionResult TestByte()
{
    Log("TestByte function entered");
    //test to see if i get anything, not sure how to do this
    byte[] data = Request.Content.ReadAsByteArrayAsync().Result;
    byte[] test = Convert.FromBase64String(payload);

    if(test == null || test.Length <= 0)
    {
        Log("No Payload");
        return NotFound();
    }

    if (data == null || data.Length <= 0)
    {
        Log("No payload");
        return NotFound();
    }

    Log("Payload received");
    return Ok();

}

发送图像的 MVC 端如下所示:

// Create a request using a URL that can receive a post. 
WebRequest request = WebRequest.Create(url);
// Set the Method property of the request to POST.
request.Method = "POST";

// Create POST data and convert it to a byte array.
byte[] byteArray = GetImageData(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, content, barcodeUri));
string base64String = Convert.ToBase64String(byteArray);
byte[] dataArray = Encoding.Default.GetBytes(base64String);

// Set the ContentType property of the WebRequest.
request.ContentType = "multipart/form-data";
// Set the ContentLength property of the WebRequest.
request.ContentLength = dataArray.Length;

// Get the request stream.
Stream dataStream = request.GetRequestStream();
// Write the data to the request stream.
dataStream.Write(dataArray, 0, dataArray.Length);
// Close the Stream object.
dataStream.Close();

// Get the response.
WebResponse response = request.GetResponse();
// Get the stream containing content returned by the server.
dataStream = response.GetResponseStream();
// Open the stream using a StreamReader for easy access.
StreamReader reader = new StreamReader(dataStream);
// Read the content.
string responseFromServer = reader.ReadToEnd();
// Clean up the streams.
reader.Close();
dataStream.Close();
response.Close();

出于某种原因,我总是收到 404 WebException

WebResponse response = request.GetResponse();

我已检查该 URL 是否正确。是我如何格式化帖子的 URL 还是我犯了其他错误?

编辑,添加 webconfig 路由:

public static void Register(HttpConfiguration config)
{
    // Web API configuration and services

    // Web API routes
    config.MapHttpAttributeRoutes();

    config.Routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: "api/{controller}/{action}/{id}",
        defaults: new { id = RouteParameter.Optional }
    );
}

【问题讨论】:

标签: c# asp.net-mvc asp.net-web-api


【解决方案1】:

您可以使用multipart/form-data 来传输文件。下面是一个示例,说明如何在 Web API 操作中读取上传文件的内容:

[HttpPost]
[Route("api/upload")]
public async Task<IHttpActionResult> Upload()
{
    if (!Request.Content.IsMimeMultipartContent())
    {
        return this.StatusCode(HttpStatusCode.UnsupportedMediaType);
    }

    var filesProvider = await Request.Content.ReadAsMultipartAsync();
    var fileContents = filesProvider.Contents.FirstOrDefault();
    if (fileContents == null)
    {
        return this.BadRequest("Missing file");
    }

    byte[] payload = await fileContents.ReadAsByteArrayAsync();
    // TODO: do something with the payload.
    // note that this method is reading the uploaded file in memory
    // which might not be optimal for large files. If you just want to
    // save the file to disk or stream it to another system over HTTP
    // you should work directly with the fileContents.ReadAsStreamAsync() stream

    return this.Ok(new
    {
        Result = "file uploaded successfully",
    });
}

现在使用HttpClient编写客户端是一项微不足道的任务:

class Program
{
    private static readonly HttpClient client = new HttpClient();

    static void Main()
    {
        string responsePayload = Upload().GetAwaiter().GetResult();
        Console.WriteLine(responsePayload);
    }

    private static async Task<string> Upload()
    {
        var request = new HttpRequestMessage(HttpMethod.Post, "http://localhost:8180/api/upload");
        var content = new MultipartFormDataContent();

        byte[] byteArray = ... get your image payload from somewhere
        content.Add(new ByteArrayContent(byteArray), "file", "file.jpg");
        request.Content = content;

        var response = await client.SendAsync(request);
        response.EnsureSuccessStatusCode();

        return await response.Content.ReadAsStringAsync();
    }
}

【讨论】:

  • 出于某种原因,我在response.EnsureSuccessStatusCode(); 上收到了 404。我调用的 URL 是http://localhost:49289/api/upload,我可以看到 localhost:49289 在 IIS express 中运行。我基本上复制了你的代码,不知道为什么我无法访问我的 Web API 中的函数。
  • 您是否在 Web API 上使用基于属性的路由?在我的示例中,我这样做了,但这假设您已正确配置它。如果您使用全局路由,请根据您的场景调整代码,不要只是盲目地复制粘贴。
  • 我在 Web API 中启用了基于属性的路由,我编辑了原始问题以显示我的 WebApiConfig
  • 尝试从您的配置中删除全局路由。您不应该将属性与全局路由混用。
  • 我删除了全局路由,但它仍然无法正常工作。我仍然得到一个 404,但是当我从浏览器调用 URL 作为 GET 请求时,我得到{"Message":"The requested resource does not support http method 'GET'."},它看起来就在那里。
【解决方案2】:

从 TestByte 方法中删除 string payload 参数。它会导致错误。您正在通过Request.Content.ReadAsByteArrayAsync 方法获取数据。您不需要有效负载对象。 如果你的路由是正确的,它必须像这样工作。

编辑: 你可以这样更改 routeTemplate 吗?

routeTemplate: "api/{controller}/{id}"

【讨论】:

  • 您对有效载荷参数是正确的,我添加它是为了测试它是否会改变某些东西,我再次将其删除。我正在使用Request.Content.ReadAsByteArrayAsync,但我认为我的路由有问题。我不确定在路由中寻找什么来解决问题。它应该可以工作,但是在发布数据时我得到一个 404。
猜你喜欢
  • 2014-03-11
  • 1970-01-01
  • 1970-01-01
  • 2013-01-15
  • 1970-01-01
  • 2014-03-20
  • 1970-01-01
  • 2013-05-04
  • 1970-01-01
相关资源
最近更新 更多