2016-09-07 3 views
0

生のJSONと一緒にファイル(「.pdf」、「.jpg」または「.png」のみ)を送信できるかどうかは疑問でした。 これまでのすべてのエンドポイントでは未処理のJSON(フロントエンドがまだ存在しないため、私はPostman経由でテストしています)を送信しますが、フォームデータの送信はAngular Jsを使用して送信されます。私はまだAngular Jsを知らないので、これがどのように機能するか想像できません。生のJSONとファイルを同じweb api 2エンドポイントで送信する

問題になっているエンドポイントのシグネチャは次のようになります。

[Route("Post")] 
    [CustomAuthorize(Roles = "User, Admin")] 
    [ValidateJWT] 
    public async Task<IHttpActionResult> Post(HttpRequestMessage request, SalesOrderViewModel orderData) 

ビューモデルは、モデルバインダーは、JSONから変換文字列プロパティの負荷を持つだけでC#クラスです。

生のJSONとユーザーが選択するファイルをWeb API 2で同じエンドポイントで送信できるかどうかを知りたいですか。 それはありますか?

ありがとうございます。

答えて

1

あなたは、アプリケーション/ jsonとして投稿することはできませんが、データの値がJSONになる複数のフォームフィールド(フォームデータとして)、ファイル+データで行うことはできます。

私はこの方法を推奨するが、トリックをしていないよ:

public async Task<IHttpActionResult> Post() 
     { 
      if (!Request.Content.IsMimeMultipartContent()) 
      { 
       Request.CreateResponse(HttpStatusCode.UnsupportedMediaType); 
      } 

      //load in a memory stream or in azure blob storage 
      var uploadFolder = "~/App_Data/FileUploads"; // to demonstrate the upload so please don't comment about where I'm saving the file, don't recommend this under no circumstance 
      var root = HttpContext.Current.Server.MapPath(uploadFolder); 
      Directory.CreateDirectory(root); 
      var provider = new MultipartFormDataStreamProvider(root); 
      var result = await Request.Content.ReadAsMultipartAsync(provider); 

      if (result.FileData.FirstOrDefault() == null) 
      { 
       return BadRequest("No import file was attached"); 
      } 

      var uploadedFileInfo = new FileInfo(result.FileData.First().LocalFileName); 

      var model = result.FormData["model"]; 

      if (model == null) 
      { 
       return BadRequest("Model is missing"); 
      } 

      var parameters = JsonConvert.DeserializeObject<Coords>(model); 

      var byteArray = File.ReadAllBytes(uploadedFileInfo.FullName); 
      //..process the bytes 
      //..process json passed in headers 
} 

とモデル:

public class Coords 
    { 
     public Cord[] cords { get; set; } 
    } 

    public class Cord 
    { 
     public int x { get; set; } 
     public object y { get; set; } 
    } 

ポストマンコール:

enter image description here

1

編集:ちょうどあなたがtを持っていないことを確認o IEnumerable<byte>を使用します。 byte[]を使用すると正常に動作します。あなたはIEnumerable<byte>と宣言することでバイトを受信できるように


WEBAPIは、IEnumerable<T>にデシリアライズJSON配列をサポートしています。お使いのコントローラで

public class ImageModel 
{ 
    public string Name { get; set; } 
    public IEnumerable<byte> Bytes { get; set; } 
} 

次の例では、画像をアップロードする方法を示します。ディスクに画像を書き込む:

private string WriteImage(byte[] arr) 
{ 
    var filename = [email protected]"images\{DateTime.Now.Ticks}."; 

    using (var im = Image.FromStream(new MemoryStream(arr))) 
    { 
     ImageFormat frmt; 
     if (ImageFormat.Png.Equals(im.RawFormat)) 
     { 
      filename += "png"; 
      frmt = ImageFormat.Png; 
     } 
     else 
     { 
      filename += "jpg"; 
      frmt = ImageFormat.Jpeg; 
     } 
     string path = HttpContext.Current.Server.MapPath("~/") + filename; 
     im.Save(path, frmt); 
    } 

    return [email protected]"http:\\{Request.RequestUri.Host}\{filename}"; 
} 

HttpContext.Current.Server.MapPath("~/")は、サーバーの内部パスを実行します。 Request.RequestUri.Hostはホスト名を返します。 AngularJSのため

<input type="file" id="imageFile"/> 

アップロード方法:HTMLで

public IHttpActionResult UploadImage(ImageModel model) 
{ 
    var imgUrl = WriteImage(model.Bytes.ToArray()); 

    // Some code 
} 

$scope.upload = function() { 

    var file = document.getElementById("imageFile").files[0]; 
    var r = new FileReader(); 
    r.onloadend = function (e) { 


     var arr = Array.from(new Uint8Array(e.target.result)); 

     var uploadData = { 
      Name: "Name of Image", 
      Bytes: arr 
     } 
     console.log(uploadData); 

     $http.post('api/Uploader/UploadImage', uploadData) 
     .then(
     function (response) { 
      console.log(response); 
     }, 

     function (reason) { 

      console.log(reason); 
     }) 
    } 
    r.readAsArrayBuffer(file); 
} 
関連する問題