[英]Create byte array in JavaScript
Is there a way to create a byte array from a file in JavaScript (or Typescript) that will be sent to a C# WebApi service, and consumable by the C# byte array method parameter? 有没有一种方法可以从JavaScript(或Typescript)文件中创建字节数组,该文件将发送到C#WebApi服务,并由C#字节数组方法参数使用? If so, can you provide an example of the JavaScript? 如果是这样,您可以提供一个JavaScript示例吗?
I should mention, this is an Angular 4+ application that will be posting to the service. 我应该提到,这是一个将发布到该服务的Angular 4+应用程序。
I need to upload Word documents, PDFs and images to a C# service, and this is the way the C# service is currently built. 我需要将Word文档,PDF和图像上载到C#服务,这是当前构建C#服务的方式。 It expects a byte array of the file being uploaded. 期望要上传的文件的字节数组。
This is the request object of the C# service: 这是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;
}
And this is the AttachmentLookupInformation class: 这是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;
}
This is so I can upload the file and additional data to the service. 这样我就可以将文件和其他数据上传到服务。
EDIT: including failed Angular code that I used: 编辑:包括我使用的失败的Angular代码:
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);
}
});
};
Well, you have: 好吧,你有:
that.contractsService
.save(request, 'attachment/saveattachment')
But your class you're showing is SaveAttachmentRequest
, with public byte[] Attachment
inside that. 但是您要显示的类是SaveAttachmentRequest
,其中包含public byte[] Attachment
。 You don't have a function showing in your question called saveattachment
inside a class called attachment
, which is what should be processing the transferring of the data to the byte[], I would think, unless you're somehow just setting it directly into the parameter. 我认为,您的问题中没有一个函数称为saveattachment
,该类称为attachment
,这是应该处理的数据传输到byte []的过程,除非您以某种方式直接将其设置为参数。 Assuming you have such an attachment
class, it should be where you'd have an entry point called saveattachment
that does all the work. 假设您具有此类attachment
类,则应该在其中有一个名为saveattachment
的入口点可以完成所有工作。 But say that it is failing because you are passing in your JS model and mapping it directly to the .NET one. 但是要说这是失败的,因为您正在传递JS模型并将其直接映射到.NET。 So then create a string parameter that can accept your binary string, then save it over to your byte[]
one. 因此,创建一个可以接受您的二进制字符串的字符串参数,然后将其保存到您的byte[]
。
[DataMember(IsRequired = true)] public string strAttachment { get; set; } = null;
and in your JS, 在你的JS里
request.Attachment = binary;
becomes 变成
request.strAttachment = binary;
Then you'd need: 然后,您需要:
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.
}
}
That's just one way of converting a binary string to byte[]. 那只是将二进制字符串转换为byte []的一种方法。 Plenty of other ways here . 这里还有很多其他方式。
Or, have you tried just sending it as a string, making this: 或者,您是否尝试过仅将其作为字符串发送,因此:
[DataMember(IsRequired = true)] public byte[] Attachment { get; set; } = null;
turn into this: 变成这个:
[DataMember(IsRequired = true)] public string Attachment { get; set; } = null;
in the first place? 首先?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.