Announcement

Collapse
No announcement yet.

PLEASE HELP: Massive problems due to boxing and type mess

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

    PLEASE HELP: Massive problems due to boxing and type mess

    Hi

    Upgrading from 15.7 to 16.1 has proven to be an absolute nightmare for us. I'm desperate and about ready to give up. Several fundamental things have changed which compromise the type compatibility between Bridge and JS. And unfortunately these changes do not seem to be documented anywhere as breaking changes. Most of the damage in my code comes from the new (and IMO unnecessary) boxing and unboxing of objects.

    Problem #1:
    The As<>() extension method doesn't to what it did before. Before it was intuitively clear to the developer that this method would treat a C# variable as another type in JS without actually checking the type in JS. As the method name suggested, it would simply treat the variable AS that type. However, since v16 the variable is constantly boxed and unboxed, so there's no way of treating it as "something else" explicitly. This could also lead to exceptions because the Bridge.unbox() method could fail without the developer expecting it at that point.

            object someDate = new DateTime();
            int month = someDate.As<DateTime>().Month;
            Console.WriteLine(month);
    ... now results in....

                var someDate = Bridge.box(System.DateTime.getDefaultValue(), System.DateTime, System.DateTime.format);
    var month = System.DateTime.getMonth(Bridge.unbox(someDate));
                System.Console.WriteLine(month);
    The sample above works OK, but in my much more complex code I have a few examples where the altered As<> method produces problems.

    Problem #2:
    While this may not seem like a big deal, the new boxing/unboxing leads to massive problems during serialization and deserialization, as well as during type checking. Consider the following Deck Examble... there you'll see that it has now become IMPOSSIBLE to detect a Guid during custom serialization:

    https://deck.net/959f650afa648c1506f4d98f5138910c

    This sample worked perfectly in v15.7, and I don't see a reason why it shouldn't work any more.

    The check for (value is Guid) in v16 will never be true, and there seems to be no way to get the original type back, since Bridge.NET silently decides to convert types when JSON.Stringify is called. This now leads to Guids and DateTimes being impossible to serialize .. unless I switch to your new implementation of Newtonsoft.Json, but that's too big of a change now considering my framework already worked fine before.

    Problem #3:
    Additionally, the new boxing/unboxing creates situations where object literals contain boxed versions of objects - for example a DateTime - and then third party libraries are unable to interpret those foreign types. They expect a regular JS Date object for databinding.
    See my other post on this problem, including samples:
    https://forums.bridge.net/forum/comm...boxing-problem

    I would be glad if you could give me some advice on how to handle these situations cleanly.... and even better would be to:

    A) Explain to developers WHY this boxing/unboxing was introduced (I don't see any benefit as of now)
    B) Provide a bridge.json switch to completely disable the boxing function.

    Also, I would like to mention that I'm absolutely willing to pay a yearly support subscription for Bridge.NET if we get informed in more detail about such groundbreaking changes and get priority help or patches when problems like this arise. Do you plan on offering commercial support?

    Thanks,
    Marco

    #2
    Hi Marco,
    Thanks for the comments and detailed feedback. We're reviewing your post in detail and will promptly respond back with some answers.

    Comment


      #3
      Hi,

      Problem 1
      You should use C# cast operation to unbox value from the object.

      object someDate = new DateTime();
      int month = (DateTime)someDate.Month;
      Console.WriteLine(month);
      Problem 2

      It is not related to box/unbox operations at all (there is no boxing operation in that sample).

      In v16, Guid is represented as a real class (not as a string like in the previous version). It is not recommended to use JSON.stringify for Bridge classes because its instances contain many service fields (there are a lot of discussions where we already mentioned that JSON.stringify should not use for Bridge instances).

      Each Bridge class has own toJSON implementation which returns a plain object without any members contain $ sign in own name. So, Guid toJSON implementation just returns plain object with fields are represented internal structure of GUID. That toJSON is used by JSON.stringify automatically.

      Problem 3

      You can use generic version of structures to avoid box/unbox operations (do not use object type, always try to narrow type)

      A) Explain to developers WHY this boxing/unboxing was introduced (I don't see any benefit as of now)
      Bridge tries to repeat .NET behaviour, therefore, box/unbox operations were introduced. It can help to handle such cases
      byte b = 1;
      object o = b;
      
      if (o is byte)
      {
          Console.WriteLine("You will not see this message without box operation");
      }
      B) Provide a bridge.json switch to completely disable the boxing function.
      We are reviewing to add such possibility.

      Thanks for your attention to Bridge.NET and good questions.
      Last edited by geoffrey.mcgill; 2017-08-22 @ 05:03 PM.

      Comment


        #4
        Hi Vladimir

        Thanks a lot for taking the time to respond. I disagree about your approach in #2: In 15.7. the Guid type was already a "real" object, not a string, and it handled both ToString() as well as all serializations and deserializations with builtin JS functions perfectly. I used it in my custom serializer via JsonReviver and custom JSON.Stringify() delegate, and it all worked like a charm. Do you have a 15.7 version of Deck somewhere, then I can demonstrate what I mean?

        As you explaioned,Bridge v16 passes down the reduced Guid representation (simple JSON object) that is not recognized as a "real" Guid any more. Therefore it also lacks the proper ToString() method which could be used for serialization in 15.7. I can't tell whether it's Bridge.box or toJSON which does the harm. In the end, it doesn't matter... it's something that worked which is now gone. I want to fix it, but I don't see the solution.

        I'm happy to adapt to the new way of v16, but my problem: How can I solve my serialization? Here's what I tried as a workaround:
        1. Added your Newtonsoft.Json package
        2. Replaced my JSON.Stringify with JsonConvert.SerializeObject(...)
        3. Bam! Exception thrown: "Cannot serialize object of type Nullable<Guid>". .
        4. OK, I thought I was smart: Implement a custom ContractResolver that can read and write nullable types...
        5. Bam! ContractResolver doesn't exist in Bridge's Newtonsoft implementation, and IContractResolver is an empty interface. One-way street!
        So I'm stuck once again. I cannot serialize nullable Guids, which also worked in v15.7 with JSON.Stringify. And I have no way of extending Newtonsoft's behavior withtout JsonConverters or ContractResolvers.

        Next step: I guess I have to write my own Json serializer and deserializer.

        It seems like I can't be the only want wanting to serialize and deserialize Guids and DateTimes in a WebAPI compatible way and pass the resulting JSON objects on to third party libs for databinding.

        Sorry, I don't mean to be obnoxious, but I've been wrapping my head around this problem for more than 20 hours now.

        Comment


          #5
          You can use the following code as workaround
          https://deck.net/947a19924376fe1e7fc6d107106488a1

          I will check Nullable<Guid> serialization

          Comment


            #6
            Hi Marco – We're working on some toJSON and GUID revisions that will help with json serialization. We expect to release today; at least that's the goal.

            Comment


              #7
              Wow, thanks a lot, also for the workaround. Looking forward to the updated version :-)

              Comment


                #8
                Hi Marco,

                Bridge 16.2.0 has been released and the json serialization within your project should be working better now.

                Please let us know if you run into any issues.

                Hope this helps.

                Comment

                Working...
                X