How to decode protobuf base64 string to js object - javascript

I'm try to decode protobuf message from server side (base64 string) to javascript object. Use for decode protobuf.js.
As doc suggest :
var builder = ProtoBuf.newBuilder({ convertFieldsToCamelCase: true });
var YourMessage = builder.build("YourMessage");
var buffer = ...; // E.g. a buffer received on a WebSocket
var myMessage = YourMessage.decode(buffer);
...
var b64str = ...; // E.g. a string fetched via AJAX
var myMessage = YourMessage.decode64(b64str);
This is how I try to do it (data - base64 string) :
var proto = dcodeIO.ProtoBuf;
var buffer = dcodeIO.ByteBuffer;
var b = buffer.wrap(data,"binary");
var builder = proto.newBuilder({ convertFieldsToCamelCase: true });
builder.define("Events");
var message = builder.build("Events");
var result = message.decode(b); //also try to decode base64 string - message.decode64(data);
I get error
decode/decode64 undefined

Missing the line to import the proto definition as below (where tests/example1.proto is your file name)
ProtoBuf.loadProtoFile("tests/example1.proto", builder);
or if loading from proto string
ProtoBuf.loadProto(...protoString..., "example1.proto");
without this the builder will say undefined because there is nothing for it to build its definition with

Related

Send a byte array to WCF service

I am trying to send a pdf file from javascript to a rest wcf service.
The service expects an array of byte with the following signature
The trick is in the byte array parameter, all the others are working fine
[OperationContract]
[WebInvoke(UriTemplate = "rest/{sessionToken}/ImportNewTemplate?commit={commit}&createApplication={createApplication}&templateName={templateName}&option={option}")]
[CloudMethod(Group = "02. Templates", Description = "Import a new template in the platform.", HelpFile = "ListPaperTemplate.aspx")]
[CloudParameter(Name = "sessionToken", Description = "session token", HelpFile = "ServiceAPIDoc.aspx?q=sessionToken")]
[CloudParameter(Name = "createApplication", Description = "Create a standalone application linked to this template.")]
[CloudParameter(Name = "commit", Description = "Commit the upload ? if true, the template will be imported, else the return just allow you to preview template description.")]
[CloudParameter(Name = "templateName", Description = "Name of the new template. Only valid for single pdf upload. If the files are zipped, the file name in the zip will be used instead")]
[CloudParameter(Name = "templateFile", Description = "Can be a PDF file, or a zip file containing a flat pdf + xml definition", HelpFile = "ServiceAPIDoc.aspx?q=templateFile")]
CloudObjects.TemplateImportation ImportNewTemplate(string sessionToken, bool commit, bool createApplication, byte[] templateFile, string templateName, string option);
this is what I use from the javascript end to send the pdf file
const file = e.target.files[0];
// Encode the file using the FileReader API
const reader = new FileReader();
var fileByteArray = [];
reader.onloadend = async (e) => {
const arrayBuffer = e.target.result,
array = new Uint8Array(arrayBuffer);
for (const a of array) {
console.log(a);
fileByteArray.push(a);
}
let ret = await dispatch('createTemplate', {name: this.newForm.name, pdf:fileByteArray, save:false});
await this.$store.dispatch('hideLoadingScreen')
// Logs data:<type>;base64,wL2dvYWwgbW9yZ...
};
reader.onerror = async () => {
await this.$store.dispatch('hideLoadingScreen')
}
reader.onabort = async () => {
await this.$store.dispatch('hideLoadingScreen')
}
await this.$store.dispatch('showLoadingScreen');
reader.readAsArrayBuffer(file);
And here is the code to send it to the rest service
let url = `${getters.getServiceUrl}ImportNewTemplate?templateName=${name}&commit=${save || true}`
const xhr = new XMLHttpRequest;
xhr.open("POST", url, false);
xhr.setRequestHeader('Content-Type', 'application/json');
let response = await xhr.send(pdf);
However every time I get an error from the service when it tries to deserialise the byte array.
The exception message is 'There was an error deserializing the object of type System.Byte[]. End element 'root' from namespace '' expected.
I have tried a lot of alternatives but nothing works.
Any suggestions are welcome !
Thanks
For those interested, the trick was to add JSON.stringify to the returned array.
So: xhr.send(JSON.stringify(pdf))
would do the trick

Error Converting Base64 data to File using JavaScript on Internet Explorer(0x800a01bd - JavaScript runtime error: Object doesn't support this action)

I am trying to convert base64 data to file using javascript on asp.net, but i am getting( 0x800a01bd - JavaScript runtime error: Object doesn't support this action) error on final stage while converting blob to file at final stage.
Here is my code:
function dataBaseURLtoFile(str) {
// extract content type and base64 payload from original string
var pos = str.indexOf(';base64,');
var type = str.substring(5, pos);
var b64 = str.substr(pos + 8);
// decode base64
var imageContent = atob(b64);
// create an ArrayBuffer and a view (as unsigned 8-bit)
var buffer = new ArrayBuffer(imageContent.length);
var view = new Uint8Array(buffer);
// fill the view, using the decoded base64
for (var n = 0; n < imageContent.length; n++) {
view[n] = imageContent.charCodeAt(n);
}
// convert ArrayBuffer to Blob
var blob = new Blob([buffer], { type: type });
//convert blob to file
var file = new File([blob], "name", { type: "image/jpeg", });
return file;
}
I try to check your code and found that issue is on line below.
var file = new File([blob], "name", { type: "image/jpeg", });
IE and Edge browser does not supports the File() constructor.
File.File() constructor
For IE and Edge browser you need to use any alternative way.
You can try to refer thread below may give you some helpful information about alternative ways.
Is there an alternative for File() constructor for Safari and IE?

image to base64 in javascript and c# (frontend and backend) is different

I am trying to convert an image to base64 to upload it on sharepoint site but it is throwing 400:bad request error. when i checked properly then i found out that the base64 i am sending is endcoded by javascript and it is different than what is expected by sharepoint. I have attached 2 images here describing the difference. Can anyone help me to get the proper encoded data using javascript ?
javascript encoded base64
c# encoded base64
var files = $("#myfile").get(0).files;
var reader = new FileReader();
reader.readAsDataURL(files[0]);
reader.onload = function () {
console.log(reader.result);
}
Could try : reader.result.split("base64,")[1]
Removes the "base64," start of the string.
Please try this , i am using this in my project , its working for me
if (file.ContentType.Contains("image"))
{
string theFileName = Path.GetFileName(file.FileName);
byte[] thePictureAsBytes = new byte[file.ContentLength];
using (BinaryReader theReader = new BinaryReader(file.InputStream))
{
thePictureAsBytes = theReader.ReadBytes(file.ContentLength);
}
string thePictureDataAsString = Convert.ToBase64String(thePictureAsBytes);
}
"thePictureDataAsString " variable got Base64 string
.........................................................................
i am getting file like this in my project
public ActionResult SaveMake(string inputMakeName, HttpPostedFileBase file)
{
MakeModel objMakeModel = new MakeModel();
if (file.ContentType.Contains("image"))
{
string theFileName = Path.GetFileName(file.FileName);
byte[] thePictureAsBytes = new byte[file.ContentLength];
using (BinaryReader theReader = new BinaryReader(file.InputStream))
{
thePictureAsBytes = theReader.ReadBytes(file.ContentLength);
}
string thePictureDataAsString = Convert.ToBase64String(thePictureAsBytes);
objMakeModel.ImageBase64 = thePictureDataAsString;
objMakeModel.Make1 = inputMakeName;
}
string response = _apiHelper.ConvertIntoReturnStringPostRequest<MakeModel>(objMakeModel, "api/Transaction/SaveMakes/");
// string response = _apiHelper.SaveMake(objMakeModel, "api/Transaction/SaveMakes/");
return RedirectToAction("AddVehicleMaintenance");
}

Encrypt parameters to JWT(JSON web token) using JS in HTML page

I want to generate JWT using JavaScript on HTML page.
I looked at Online JWT service Click Here, but can't get proper idea.
So is there any solution to generate JWT using JavaScript in HTML page.
I've encode and decode method in c# code. but i want to encode parameter from java script and will decode in c# code.
My c# Code look like:
public static string Encode(object payload, byte[] key, JwtHashAlgorithm algorithm)
{
var segments = new List<string>();
var header = new { typ = "JWT", alg = algorithm.ToString() };
byte[] headerBytes = Encoding.UTF8.GetBytes(jsonSerializer.Serialize(header));
byte[] payloadBytes = Encoding.UTF8.GetBytes(jsonSerializer.Serialize(payload));
segments.Add(Base64UrlEncode(headerBytes));
segments.Add(Base64UrlEncode(payloadBytes));
var stringToSign = string.Join(".", segments.ToArray());
var bytesToSign = Encoding.UTF8.GetBytes(stringToSign);
byte[] signature = HashAlgorithms[algorithm](key, bytesToSign);
segments.Add(Base64UrlEncode(signature));
return string.Join(".", segments.ToArray());
}
public static string Decode(string token, byte[] key, bool verify = true)
{
var parts = token.Split('.');
var header = parts[0];
var payload = parts[1];
byte[] crypto = Base64UrlDecode(parts[2]);
var headerJson = Encoding.UTF8.GetString(Base64UrlDecode(header));
var headerData = jsonSerializer.Deserialize<Dictionary<string, object>>(headerJson);
var payloadJson = Encoding.UTF8.GetString(Base64UrlDecode(payload));
if (verify)
{
var bytesToSign = Encoding.UTF8.GetBytes(string.Concat(header, ".", payload));
var keyBytes = key;
var algorithm = (string)headerData["alg"];
var signature = HashAlgorithms[GetHashAlgorithm(algorithm)](keyBytes, bytesToSign);
var decodedCrypto = Convert.ToBase64String(crypto);
var decodedSignature = Convert.ToBase64String(signature);
if (decodedCrypto != decodedSignature)
{
throw new SignatureVerificationException(string.Format("Invalid signature. Expected {0} got {1}", decodedCrypto, decodedSignature));
}
}
return payloadJson;
}
Your answer will appreciable.
Thanks,
Hardik

send a multipart request from a device to server in node.js

I am receiving a video bytes from a device, and it should be a multipart request. Its a post api which is created in node.js. How can I recieve a multipart request in post api in node.js. Below is the code which is currently saving video bytes.
app.js
app.post('/saveVideo',service.saveVideo);
routes.js(class service method saveVideo)
var video_byte_string = req.param('videoByteStr');
var writeStream = gfs.createWriteStream({mode:'w',content_type: 'video/mov'});
var buffer = new Buffer(video_byte_string).toString('base64');
var response = streamifier.createReadStream(buffer).pipe(writeStream);
You need to append a separator after video bye string like following
if byte string are - 'abcdefghijklmnopqrstuvwxyz';
then you need to append any separator(#####) like this to identify end of complete string
now your request string will be like this - 'abcdefghijklmnopqrstuvwxyz'+'#####';
Now your request string having a end separator(#####) from which you can identify your complete chunks
var video_byte_string = req.param('videoByteStr');
isCorrectString = false;
data_stream += video_byte_string;
var n = data_stream.lastIndexOf("#####");
if (n === -1) {
var steamArr= data_stream.split("#####");
var completeByteString = steamArr[0];
isCorrectString = true;
}
if(isCorrectString) {
var writeStream = gfs.createWriteStream({mode:'w',content_type: 'video/mov'});
var buffer = new Buffer(completeByteString).toString('base64');
var response = streamifier.createReadStream(buffer).pipe(writeStream);
}
Thanks

Categories