2016-12-28 82 views
0

我有一个Angular应用程序,用Typescript编写,带有一个ASP.Net Web Api后端。我正尝试使用ng-file-upload(请参阅此link以获取详细信息)指令来上传图像文件。预期结束MIME多部分流。 MIME多部分邮件不完整

我在网页API Post方法收到异常:

“ MIME多流意外结束MIME多信息是不完整的。”

我已经完成了我的研究并发现了类似的问题here - 我试图实施Landuber Kassa的答案,但没有成功。

this虽然我的项目是不是MVC,并在任何情况下它不起作用。

我很新鲜的想法,并会欣赏社区的想法。如果我能指出正确的方向,我很乐意考虑其他选择。

我的.Net Post方法(实施Landuber卡萨的想法):

[RoutePrefix("BeaufortAppStore/api/Image")] 
public class ImageController : ApiController 
{ 

    #region Methods 

    #region Posts 

    [Route("UploadImage")] 
    [HttpPost] 
    public async Task<IHttpActionResult> UploadImage() 
    { 
     if (!Request.Content.IsMimeMultipartContent()) 
     { 
      throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType); 
     } 

     var provider = new MultipartMemoryStreamProvider(); 

     Stream reqStream = Request.Content.ReadAsStreamAsync().Result; 
     MemoryStream tempStream = new MemoryStream(); 
     reqStream.CopyTo(tempStream); 

     tempStream.Seek(0, SeekOrigin.End); 
     StreamWriter writer = new StreamWriter(tempStream); 
     writer.WriteLine(); 
     writer.Flush(); 
     tempStream.Position = 0; 

     StreamContent streamContent = new StreamContent(tempStream); 
     foreach (var header in Request.Content.Headers) 
     { 
      streamContent.Headers.Add(header.Key, header.Value); 
     } 

     // Read the form data and return an async task. 
     await streamContent.ReadAsMultipartAsync(provider); // FAILS AT THIS POINT 
     foreach (var file in provider.Contents) 
     { 
      var filename = file.Headers.ContentDisposition.FileName.Trim('\"'); 
      var buffer = await file.ReadAsByteArrayAsync(); 
      //Do whatever you want with filename and its binary data. 
     } 
     return Ok(); 
    } 

    #endregion 

    #endregion 

我的角度控制器的方法:

public upload(): void { 
     //Create config used in ng-file-upload 
     var config: IFileUploadConfigFile = { 
      data: this.file, url: "BeaufortAppStore/api/Image/UploadImage/", method: "POST" }; 
     this._dataService.uploadImage(config).then((result: any) => { 
      this.thumbnail = result.data; 
     }); 
    } 

我的角视图(为一个指令局部视图) :

<div class="form-group"> 
<label for="file" class="control-label col-xs-2">Choose a file</label> 
<input id="file" type="file" name="file" class="form-control" ngf-select ngf-pattern="'image/*'" 
     ng-model="vm.file" /> 
<img style="width:100px;" ngf-thumbnail="thumbnail || '/thumb.jpg'" /> 
<button type="submit" ng-click="vm.upload()">Upload</button> 

回答

0

试试这个在C#:

[HttpPost] 
    [Route("Profile/Image")] 
    public Task<HttpResponseMessage> UploadImgProfile() 
      { 
       try 
       { 
        if (!ModelState.IsValid) return null; 

        var currentUser = _userUtils.GetCurrentUser(User); 
        if (currentUser == null) return null; 

        HttpRequestMessage request = this.Request; 
        if (!request.Content.IsMimeMultipartContent()) 
         throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.UnsupportedMediaType)); 

        string root = HttpContext.Current.Server.MapPath("~" + Constant.Application.User_Image_Directory); 

        bool exists = Directory.Exists(root); 
        if (!exists) 
         Directory.CreateDirectory(root); 

        var provider = new MultipartFormDataStreamProvider(root); 





    var task = request.Content.ReadAsMultipartAsync(provider). 
        ContinueWith<HttpResponseMessage>(o => 
        { 
         var finfo = new  FileInfo(provider.FileData.First().LocalFileName); 

      string guid = Guid.NewGuid().ToString(); 

      var fileName = guid + "_" + currentUser.IdOwin + ".jpg"; 

         File.Move(finfo.FullName, Path.Combine(root, fileName)); 

         return new HttpResponseMessage() 
         { 
          Content = new StringContent(Path.Combine(Constant.Application.User_Image_Directory, fileName)) 
         }; 
         } 
         ); 
        return task; 
       } 
       catch (Exception ex) 
       { 
        _logger.LogException(ex); 
        return null; 
       } 
      } 

角控制器:

//Upload Func 
      $scope.upload = function (files) { 
       if (files && files.length) { 
        for (var i = 0; i < files.length; i++) { 
         var file = files[i]; 
         $scope.uploading = true; 
         // $scope.imageName = file.name; 
         $upload.upload({ 
          url: enviroment.apiUrl + '/api/CurrentUser/Profile/Image', 
          //fields: { 'username': $scope.username }, 
          file: file 
         }).progress(function (evt) { 
          $scope.uploading = true; 
          var progressPercentage = parseInt(100.0 * evt.loaded/evt.total); 
          console.log('progress: ' + progressPercentage + '% ' + evt.config.file.name); 
          $scope.progress = progressPercentage; 
         }).success(function (data, status, headers, config) { 
          console.log('file ' + config.file.name + 'uploaded. Response: ' + data); 
          $scope.imageName = data; 
          $scope.uploading = false; 
          $scope.loadSuccess = true; 
          vm.uploadImage = false; 
          //AR 
          var reader = new FileReader(); 
          reader.onload = function (evt) { 
           $scope.$apply(function ($scope) { 
            $scope.myImage = evt.currentTarget.result; 
           }); 
          }; 
          reader.readAsDataURL(files[0]); 
          //END AR 
         }); 
        } 
       } 
      }; 


    // Stay on Listen upload file 
    $scope.$watch('files', function (evt) { 
     $scope.upload($scope.files); 
    }); 

HTML:

<div class="row"> 
           <!--UPLOAD--> 
           <div class="up-buttons"> 

            <div class="clearfix visible-xs-block"></div> 
            <div class="col-md-12 col-lg-12 col-sm-12 col-xs-12 text-center box-upload-image" data-ng-show="profileCtrl.uploadImage"> 
             <br /> 
             <div id="imgDragDrop" ng-file-drop ng-model="files" 
              drag-over-class="dragover" 
              accept="image/*"> 

              <div class="cropArea-bkg"> 
               <h4> 
                <span class="mdi mdi-account mdi-48px"></span> 
                <br /><br /> 
                Carica immagine profilo 
               </h4> 

               <p>Trascina qui la tua immagine, oppure</p> 

               <div ng-file-select="" ng-model="files" class="btn btn-secondary" ng-accept="'*.pdf,*.jpg,*.png'" tabindex="0"> 
                Sfoglia sul tuo computer 
               </div><br> 
              </div> 
             </div> 
             <div ng-no-file-drop class="well bg-danger">File Drag/Drop non è supportato da questo browser</div> 
             <br /> 
             <div class="text-center"> 
              <div class="progress" ng-show="uploading"> 
               <div class="progress-bar progress-bar-striped" role="progressbar" aria-valuenow="{{ ::progress }}" aria-valuemin="0" aria-valuemax="100" style="width: {{::progress}}% "> 
                <span class="sr-only">{{ ::progress }}% Complete</span> 
               </div> 
              </div> 
             </div> 

            </div> 

            <!--END UPLOAD--> 

           </div> 
          </div> 
+0

感谢您的快速答复。在我尝试之前,你能解释一下这种方法的不同之处。 –

+0

基本上它是一种经过测试的方式来从角度上传中检索多部分上传内容......它从this.Request中采用正确的格式,并使用异步任务生成一个名称(使用随机指导不覆盖或如果有人上传同名的其他图片,请进入例外状态) –

+0

我会告诉你控制器(Angular)和html,如果你需要它的话。确保你的post方法(在chrome控制台上检查它) ..if格式是正确的..如果它不尝试覆盖请求的标题) –

相关问题