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
Priya
  • 1,359
  • 6
  • 21
  • 41
Guillaume
  • 844
  • 7
  • 25
  • 1
    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 :) – Jaquarh Mar 23 '16 at 09:43
  • 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" ? – Guillaume Mar 23 '16 at 10:33
  • 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. – Jaquarh Mar 23 '16 at 11:06
  • 2
    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==` – Guillaume Mar 23 '16 at 13:43
  • 1
    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! – Jaquarh Mar 23 '16 at 15:02
  • 1
    Ok I understand. I suppose a dumb mistake in my code but can't figure out where. Anyway, thank you for your help ! – Guillaume Mar 23 '16 at 16:05

1 Answers1

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);
Guillaume
  • 844
  • 7
  • 25