在JavaScript中创建字节数组

时间:2018-01-30 18:17:57

标签: javascript c# angular upload

有没有办法从JavaScript(或Typescript)中的文件创建一个字节数组,该文件将被发送到C#WebApi服务,并由C#字节数组方法参数消耗?如果是这样,你能提供一个JavaScript的例子吗?

我应该提一下,这是一个将发布到服务的Angular 4+应用程序。

我需要将Word文档,PDF和图像上传到C#服务,这就是当前构建C#服务的方式。它期望文件的字节数组被上传。

这是C#服务的请求对象:

[DataContract]
public class SaveAttachmentRequest : BaseRequest
{
    [RestUrlParameter(Mode = UrlParameterMode.Inline)]
    [DataMember(IsRequired = true)] public AttachmentLookupInformation LookupInformation { get; set; } = new AttachmentLookupInformation();
    [DataMember(IsRequired = true)] public byte[] Attachment { get; set; } = null;
}

这是AttachmentLookupInformation类:

[DataContract]
public class AttachmentLookupInformation
{
    [DataMember(IsRequired = true)] public Guid Id { get; set; } = Guid.Empty;
    [DataMember(IsRequired = true)] public Guid LinkedToId { get; set; } = Guid.Empty;
    ///<summary>Not including the path- just the file name and extension.</summary>
    [DataMember(IsRequired = true)] public string FileName { get; set; } = string.Empty;
    [DataMember(IsRequired = true)] public int FileSizeInBytes { get; set; } = 0;
    ///<summary>MIME type.</summary>
    [DataMember(IsRequired = true)] public string ContentType { get; set; } = string.Empty;
    [DataMember(IsRequired = true)] public AttachmentCategories AttachmentCategory { get; set; } = AttachmentCategories.Unknown;
    [DataMember(IsRequired = true)] public string DownloadUrl { get; set; } = string.Empty;
    [DataMember(IsRequired = true)] public string CreatedBy { get; set; } = string.Empty;
    [DataMember(IsRequired = true)] public DateTimeOffset CreatedTimestamp { get; set; } = DateTimeOffset.MinValue;
}

这样我就可以将文件和其他数据上传到服务中。

编辑:包括我使用的失败的角色代码:

const lookupInfo = new AttachmentLookupInformation();
lookupInfo.Id = Helpers.emptyGuid;
lookupInfo.LinkedToId = this.contractId;
lookupInfo.AttachmentCategory = 10;

const request = new SaveAttachmentRequest();

const reader = new FileReader();
reader.onload = function() {
  const buffer = reader.result;
  let binary = '';
  const bytes = new Uint8Array(buffer);
  const length = bytes.byteLength;
  for (let i = 0; i < length; i++) {
    binary += String.fromCharCode(bytes[i]);
  }

  request.Attachment = binary;
  lookupInfo.ContentType = files[0].type;
  lookupInfo.FileName = files[0].name;
  lookupInfo.FileSizeInBytes = length;
};
reader.readAsArrayBuffer(files[0]);
reader.onloadend = function() {
  request.LookupInformation = lookupInfo;

  console.log('request: ', request);

  that.contractsService
    .save(request, 'attachment/saveattachment')
    .subscribe(res => {
      if (res.Success) {
        console.log('upload response: ', res);
      }
    });

};

2 个答案:

答案 0 :(得分:1)

嗯,你有:

that.contractsService
    .save(request, 'attachment/saveattachment')

但是,您正在展示的课程是SaveAttachmentRequest,其中包含public byte[] Attachment。你不会在名为saveattachment的类中显示一个名为attachment的问题中的函数,这应该是处理将数据传输到byte []的问题,我想,除非您以某种方式将其直接设置到参数中。假设你有这样一个attachment类,它应该是你有一个名为saveattachment的入口点完成所有工作的地方。但是说它 失败了,因为你传递了你的JS模型并将它直接映射到.NET模型。然后创建一个可以接受二进制字符串的字符串参数,然后将其保存到byte[]字符串。

[DataMember(IsRequired = true)] public string strAttachment { get; set; } = null;

并在你的JS中,

request.Attachment = binary;

变为

request.strAttachment = binary;

然后你需要:

public class attachment : ApiController
{
    [System.Web.Http.HttpPost]
    public JsonResult saveattachment(SaveAttachmentRequest sar, AttachmentLookupInformation ali)
    {          
        //string bits = "000011110000001000";
        string bits = sar.strAttachment;
        int numOfBytes = (int)Math.Ceiling(bits.Length / 8m);
        byte[] bytes = new byte[numOfBytes];
        int chunkSize = 8;

        for (int i = 1; i <= numOfBytes; i++)
        {
            int startIndex = bits.Length - 8 * i;
            if (startIndex < 0)
            {
                chunkSize = 8 + startIndex;
                startIndex = 0;
            }
            bytes[numOfBytes - i] = Convert.ToByte(bits.Substring(startIndex, chunkSize), 2);
        }

        sar.attachment = bytes;

        // ... do your other stuff for saving your model objects to the DB
        // using Entity Framework's data context, etc.
    }
}

这只是将二进制字符串转换为byte []的一种方法。许多其他方式here

或者,您是否尝试过将其作为字符串发送,请执行以下操作:

[DataMember(IsRequired = true)] public byte[] Attachment { get; set; } = null;

变成这个:

[DataMember(IsRequired = true)] public string Attachment { get; set; } = null;

首先?

答案 1 :(得分:-1)

在文件类型输入更改事件中,您可以获取字节数组。 This可以帮助你。