Protobuf : WebApi -> JS - Decoded object is empty
Asked Answered
W

1

7

I would like to send an object from a WebApi controller to an Html page through an Ajax Request.

When I receive the object in JS, it's empty. But server-side the object isn't empty because when I look at the byte[].length it's greater than 0.

  • Server-side, I use the dll provided by Google.
  • JS side, I use the ProtobufJS library. This is my .proto file :

    syntax="proto3";
    
    message Container {
        repeated TestModel2 Models = 1;
    }
    
    message TestModel2 {
        string Property1 = 1;
        bool Property2 = 2;
        double Property3 = 3;
    }
    
    • Server code :

      var container = new Container();
      
      var model = new TestModel2
      {
          Property1 = "Test",
          Property2 = true,
          Property3 = 3.14
      };
      

      container.Models.Add(model);

    • Base64 data :

    ChEKBFRlc3QQARkfhetRuB4JQA==

    • JS decoding :

      var ProtoBuf = dcodeIO.ProtoBuf;
      var xhr = ProtoBuf.Util.XHR();
      xhr.open(
          /* method */ "GET",
          /* file */ "/XXXX/Protobuf/GetProtoData",
          /* async */ true
      );
      xhr.responseType = "arraybuffer";
      xhr.onload = function (evt) {
          var testModelBuilder = ProtoBuf.loadProtoFile(
              "URL_TO_PROTO_FILE",
              "Container.proto").build("Container");
          var msg = testModelBuilder.decode64(xhr.response); 
          console.log(JSON.stringify(msg, null, 4)); // Correctly decoded
      }
      xhr.send(null);
      
    • Result object in JS console :

      {
          "Models": []
      }
      
    • bytebuffer.js

    • protobuf.js v5.0.1
Wafd answered 23/3, 2016 at 9:9 Comment(6)
So your request is successful, only - the Object you receive is empty? Try running the request directly in the browser and seeing the output and then share your output with us :)Motivate
It seems that when the JS decode the message, the object is or empty or the decoding process can't succeed so i get the default state object What do you mean by "running the request directly in the browser" ?Wafd
Okay if you're unsure if it is just empty or the decoding process isn't completing - remove the decoding process and just console.log the response. If its not empty there then we can go through the decoding process. We need to see error's because we can't debug for you. & I assumed that you're not authenticating headers on requests with keys so if so, you should be able to directly request it through the URL as see the absolute response your AJAX request would be getting - then work from there. That's assuming this API was built by you also.Motivate
When I console.log the response I obtain this ArrayBuffer {} So I suppose that the response is empty. But server-side, when I serialize my object in byte[], the length is > 0 and I am able to deserialize it and its not empty. Plus, in the Chrome console the ajax response is ChEKBFRlc3QQARkfhetRuB4JQA==Wafd
I voted up so your question will be seen, I don't specialise in JavaScript so any client-side code, I'm useless. As long as you're receiving your Object and it contains something, I'm sure you'll get a solution if they take a look at these comments also. Good luck, you may want to bounty it because it is a in-depth question which most scan read. But again, I hope you find a solution!Motivate
Ok I understand. I suppose a dumb mistake in my code but can't figure out where. Anyway, thank you for your help !Wafd
W
2

Finally i solved the problem by myself.

It was the client-side which was in fault.

  • In fact the xhr.response is JSON format so it was between double quotes "ChEKBFRlc3QQARkfhetRuB4JQA==". I had to JSON.parse my response.enter code here
  • I removed the xhr.responseType = "arraybuffer";

Here is my code now :

var ProtoBuf = dcodeIO.ProtoBuf;
var xhr = ProtoBuf.Util.XHR();
xhr.open(
    /* method */ "GET",
    /* file */ "/XXXX/Protobuf/GetProtoData",
    /* async */ true
);
// xhr.responseType = "arraybuffer"; <--- Removed
xhr.onload = function (evt) {
    var testModelBuilder = ProtoBuf.loadProtoFile(
        "URL_TO_PROTO_FILE",
        "Container.proto").build("Container");
    var msg = testModelBuilder.decode64(JSON.parse(xhr.response)); <-- Parse the response in JSON format
    console.log(msg); // Correctly decoded
}
xhr.send(null);
Wafd answered 29/3, 2016 at 13:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.