【问题标题】:File upload with ember-upload, how to fill request with additional data for servicestack?使用 ember-upload 上传文件,如何用 servicestack 的附加数据填充请求?
【发布时间】:2014-11-26 14:37:36
【问题描述】:

作为介绍,我在通过 REST 用 ember.js 编写的服务堆栈和应用程序之间的通信存在问题,我正在使用 ember-uploader 组件将文件上传到服务堆栈。

查看hbs:

<table class="table table-bordered table-hover">
{{file-upload}}
</table>

咖啡脚本中的组件

  ABC.FileUploadComponent = Ember.FileField.extend(
  url: "/api/upload"
  filesDidChange: (->
    uploadUrl = @get("url")
    console.log uploadUrl
    files = @get("files")
    test = { fileName: "test" }
    uploader = Ember.Uploader.create(
        url: uploadUrl
    )

    uploader.upload(files[0],test) unless Ember.isEmpty(files)
    console.log files
    return
  ).observes("files")
)

javascript 中的组件

ABC.FileUploadComponent = Ember.FileField.extend({
  url: "/api/upload",
  filesDidChange: (function() {
    var files, test, uploadUrl, uploader;
    uploadUrl = this.get("url");
    console.log(uploadUrl);
    files = this.get("files");
    test = {
      fileName: "test"
    };
    uploader = Ember.Uploader.create({
      url: uploadUrl,
      data: test
    });
    if (!Ember.isEmpty(files)) {
      uploader.upload(files[0], test);
    }
    console.log(files);
  }).observes("files")
});

我的服务模式:

namespace ABC.Service.ServiceModel
{
    public class Upload
    {

        [Route("/upload")]
        public class UploadRequest : IRequiresRequestStream
        {
            public System.IO.Stream RequestStream { set; get; }

            public object FileName { set; get; }

        }

        public class UploadResponse
        {
            public int Successed { set; get; }

        }
    }
}

我的服务方式

namespace ABC.Service.Service
{
    public class UploadService : ServiceBase // Service base inherites from ServiceStack.Service
    {
        public Upload.UploadResponse Post(Upload.UploadRequest request)
        {
            var req = base.Request;
            var reqThatIwant = request.FileName;

            return new Upload.UploadResponse() { Successed = 1 };
        }

    }
}

这是手表的屏幕:

所以我的问题是,我必须如何更改代码以将标记为“2”的数据转换为标记为“1”的请求对象(在屏幕上标记)?

【问题讨论】:

    标签: javascript c# rest ember.js servicestack


    【解决方案1】:

    处理原始请求流

    当您使用IRequiresRequestStream 时,您是在说您想要take over deserializing the Request 并以流的形式访问原始输入HTTP 请求正文。因此,ServiceStack 不会尝试从请求正文中读取,而是注入 HTTP 请求流 - 在这种情况下,它能够填充的唯一请求 DTO 参数是 /pathinfo 或 ?QueryString 上的参数,例如:

    [Route("/upload/{FileName}")]
    public class Upload : IRequiresRequestStream
    {
        public Stream RequestStream { set; get; }
    
        public string FileName { set; get; }
    }
    

    访问 FormData HTTP POST

    但是,如果 JavaScript 组件向您发送 HTTP POST FormData(即application/x-www-form-urlencoded 或 multipart/form-data),那么您不太可能希望将其视为原始请求流,而是访问 Request.FormData 或 Request.Files已发布。

    处理文件上传示例

    根据您的屏幕截图,HTTP 请求 Content-Type 是 multipart/form-data,在这种情况下您很可能能够使用 access any uploaded files using Request.Files。

    Live Demos 中提供了一些访问 HTTP 上传文件的示例:

    Imgur - Save uploaded files to a MemoryStream

    public object Post(Upload request)
    {
        foreach (var uploadedFile in Request.Files
           .Where(uploadedFile => uploadedFile.ContentLength > 0))
        {
            using (var ms = new MemoryStream())
            {
                uploadedFile.WriteTo(ms);
                WriteImage(ms);
            }
        }
        return HttpResult.Redirect("/");
    }
    

    Rest Files - Save to FileSystem

    public void Post(Files request)
    {
        var targetDir = GetPath(request);
    
        var isExistingFile = targetDir.Exists
            && (targetDir.Attributes & FileAttributes.Directory) != FileAttributes.Directory;
    
        if (isExistingFile)
            throw new NotSupportedException(
            "POST only supports uploading new files. Use PUT to replace contents of an existing file");
    
        if (!Directory.Exists(targetDir.FullName))
            Directory.CreateDirectory(targetDir.FullName);
    
        foreach (var uploadedFile in base.Request.Files)
        {
            var newFilePath = Path.Combine(targetDir.FullName, uploadedFile.FileName);
            uploadedFile.SaveTo(newFilePath);
        }
    }
    

    HTTP Benchmarks - Handle multiple and .zip uploaded files

    public object Post(UploadTestResults request)
    {
        //...
        foreach (var httpFile in base.Request.Files)
        {
            if (httpFile.FileName.ToLower().EndsWith(".zip"))
            {
                using (var zip = ZipFile.Read(httpFile.InputStream))
                {
                    var zipResults = new List<TestResult>();
                    foreach (var zipEntry in zip)
                    {
                        using (var ms = new MemoryStream())
                        {
                            zipEntry.Extract(ms);
                            var bytes = ms.ToArray();
    
                            var result = new MemoryStream(bytes).ToTestResult();
                            zipResults.Add(result);
                        }
                    }
                    newResults.AddRange(zipResults);
                }
            }
            else
            {
                var result = httpFile.InputStream.ToTestResult();
                newResults.Add(result);
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2012-12-04
      • 2016-06-17
      • 1970-01-01
      • 1970-01-01
      • 2018-08-28
      • 2014-02-14
      • 2018-05-04
      • 1970-01-01
      • 2014-04-29
      相关资源
      最近更新 更多