2017-01-23 13 views
0

私が実行しているWeb APIに画像をアップロードできません。 GETリクエストを使用するとWeb APIからデータを取得できますが、POSTリクエストに問題があります。私はBMPイメージをWeb APIにアップロードしてからjson文字列を返す必要があります。c#webrequest画像をweb apiに送信

[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(); 

何らかの理由で、私はいつも、私はURLがなければならないことを確認している

WebResponse response = request.GetResponse(); 

に404 WebExceptionを取得します右。投稿の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 } 
    ); 
} 
+0

は[こちら](http://stackoverflow.com/questions/10320232/how-to-accept-a-file-post-asp-net-mvc-4-webapi) –

+0

あなた」見てくださいコンテンツをmultipart/form-dataとして設定しますが、ストリームはマルチパートとしてエンコードされていませんので、これを確認してください:http://stackoverflow.com/questions/566462/upload-files-with-httpwebrequest-multipart-form-data – Gusman

答えて

1

あなたは、ファイルを送信するためにmultipart/form-dataを使用することができます。

[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を使用して簡単な作業である:ここでは、あなたのWeb APIアクションでアップロードされたファイルの内容を読み取ることができる方法の例です

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(); 
    } 
} 
+0

何らかの理由で私は 'response.EnsureSuccessStatusCode();'に404を取得しています。私が呼び出すURLは 'http:// localhost:49289/api/upload'です。私はIISで動作しているlocalhost:49289を見ることができます。私は基本的にあなたのコードをコピーしました。なぜ私のWeb APIの機能にアクセスできないのでしょうか? – steuf

+0

Web APIで属性ベースルーティングを使用していますか?私の例では私がしましたが、これはあなたが正しく構成していることを前提としています。グローバルルーティングを使用している場合は、コードをシナリオに適用して、盲目的にコピー貼り付けするだけではありません。 –

+0

Web APIで属性ベースのルーティングが有効になっています。元の質問を編集してWebApiConfigを表示しました – steuf

0

string payloadパラメータを削除します。 TestByteメソッドから取得します。エラーが発生します。あなたはRequest.Content.ReadAsByteArrayAsyncメソッドによってデータを取得しています。あなたはペイロードオブジェクトを必要としません。 ルーティングが正しい場合は、このように動作する必要があります。

編集: routeTemplateを次のように変更できますか?

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

あなたはペイロードのパラメータについて正しいですが、何かを変更するかどうかテストするために追加しました。私は 'Request.Content.ReadAsByteArrayAsync'を使っていますが、ルーティングに問題があると思います。問題を解決するためにルーティングで探すべきものがわからない。それはうまくいくはずですが、データを投稿するときに404が表示されます。 – steuf

+0

私はrouteTemplateの値を編集しました。 –

関連する問題