使用ember-upload上传文件,如何使用servicestack的附加数据填写请求?

时间:2014-11-26 14:37:37

标签: javascript c# rest ember.js servicestack

为了介绍,我在通过REST用ember.js写的servicestack和应用程序之间的通信有问题,我使用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”的Request对象(在屏幕上标记)?

add watch screen shoot

1 个答案:

答案 0 :(得分:2)

处理原始请求流

当您使用IRequiresRequestStream时,您说要take over deserializing the Request并将原始输入HTTP请求正文作为流访问。因此,ServiceStack不会尝试从Request主体读取而是注入HTTP Request流 - 在这种情况下,它能够填充的唯一Request 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-urlencodedmultipart/form-data),那么您不太可能将其视为原始请求流,而是访问{{1}已张贴的{}或Request.FormData

处理文件上传示例

根据您的屏幕截图,HTTP请求内容类型Request.Files,在这种情况下,您很可能会access any uploaded files using Request.Files

Live Demos

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

Imgur - Save uploaded files to a MemoryStream

multipart/form-data

Rest Files - Save to FileSystem

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("/");
}

HTTP Benchmarks - Handle multiple and .zip uploaded files

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);
    }
}