Search Unity

Invalid IL code when consuming webservices

Discussion in 'Editor & General Support' started by PedroGV, Feb 5, 2015.

  1. PedroGV

    PedroGV

    Joined:
    Nov 1, 2010
    Posts:
    415
    Hi,

    I'm trying to consume php webservices within a Unity 4.6.x project. Although I have followed all the steps indicated on the wiki and also copy+paste the dll System.ServiceModel to my project's plugin folder, everytime I try to call a web service, an exception like the following is thrown:

    InvalidProgramException: Invalid IL code in System.ServiceModel.ClientBase`1:get_Channel (): IL_0000: ret

    So, lines like: "return base.Channel.Status();" cannot execute the getter for Channel properly (something similar happens with the getter for InnerChannel).

    Is this a known issue with Unity? Has anyone faced such a situation? If so, any solution? (or is it related to the version of Mono pre-Unity 5 editios is using?)

    If this is a known bug -that cannot be fixed for v4.6.x, is it fixed for Unity 5?

    Thanks

    Note: needless to say that all php webservices do work correctly and can be consumed from within any standard C# project -like a console test project- in VS or Xamarin Studio.
     
  2. Graham-Dunnett

    Graham-Dunnett

    Administrator

    Joined:
    Jun 2, 2009
    Posts:
    4,287
    Would imagine the .Net DLLs are incompatible with Mono. (The wiki content is 2 years old.)
     
  3. PedroGV

    PedroGV

    Joined:
    Nov 1, 2010
    Posts:
    415
    Even if the wiki's that old if it really worked at that time it should still work, given that Unity 4.6 uses the same Mono bindings on its projects.

    So any workaround/fix for this?
     
  4. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    Not necessarily? Is it the same version of System.ServiceModel that was used in the wiki? Does it work in the editor? What version of unity are you using and what platform are you targeting?
     
  5. PedroGV

    PedroGV

    Joined:
    Nov 1, 2010
    Posts:
    415
    What version of System.ServiceModel should I use (= paste to the plugins folder) to make it work on Unity 4.6's editor? (and then on iOS and Android)
     
  6. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    Not sure... but it needs to be .NET 3.5 (not 4.0+)
     
  7. PedroGV

    PedroGV

    Joined:
    Nov 1, 2010
    Posts:
    415
    This is the one I'm using:

    Name: System.ServiceModel
    Created by: MONO development team
    Version: 3.0.0.0
    File Version: 3.0.4506.648

    ... which is the one allowed for Unity's VS project (it can be found on the folder: C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v3.5\Profile\Unity Full v3.5)
     
  8. PedroGV

    PedroGV

    Joined:
    Nov 1, 2010
    Posts:
    415
    Anyone? (any help to solve this will be much appreciated)
     
  9. PedroGV

    PedroGV

    Joined:
    Nov 1, 2010
    Posts:
    415
    Does anyone have a working example on how to consume webservices with c# on a Unity 4.6.+ project?
     
  10. PedroGV

    PedroGV

    Joined:
    Nov 1, 2010
    Posts:
    415
    Hope you guys run the example code on the bug report I sent.
     
  11. Graham-Dunnett

    Graham-Dunnett

    Administrator

    Joined:
    Jun 2, 2009
    Posts:
    4,287
    I've told the QA team about it.
     
  12. PedroGV

    PedroGV

    Joined:
    Nov 1, 2010
    Posts:
    415
    Thanks :)
     
  13. PedroGV

    PedroGV

    Joined:
    Nov 1, 2010
    Posts:
    415
    Not opened yet.
     
  14. PedroGV

    PedroGV

    Joined:
    Nov 1, 2010
    Posts:
    415
    Is there any change for getting an update on the issue from the QA Team?
     
  15. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    Did you file a bug report? Even if @Graham Dunnett told them, you need to submit a bug report with a repro so you can get an update when it's fixed (or if it's an issue)
     
  16. PedroGV

    PedroGV

    Joined:
    Nov 1, 2010
    Posts:
    415
    Yes, on February (#674737)
     
  17. PedroGV

    PedroGV

    Joined:
    Nov 1, 2010
    Posts:
    415
    ... and still no reply.
     
  18. Dave-Hampson

    Dave-Hampson

    Unity Technologies

    Joined:
    Jan 2, 2014
    Posts:
    150
    Hi Pedro,

    Looks like QA haven't processed that bug yet.
    Your issue is that you need to ship a game soon and the code you are using is from quite an old example (presumably for Unity 3.5 or 4.0) submitted by a user "Steego" to the Unify Wiki.

    Given that the bug has not been reproduced by QA yet, and that it hasn't gone to the scripting team yet you will probably have to look at other options than using this DLL. It's entirely possible that the scripting team will reply that the problem is within the DLL and not a Unity issue. And even then you are looking at quite a long resolution time.

    In your bug report you say "I really need to use webservices this way (without WWW)." can you elaborate on why? I see quite a lot of other options if I google: https://www.google.co.uk/search?q=RESTful+Unity

    Dave
     
  19. PedroGV

    PedroGV

    Joined:
    Nov 1, 2010
    Posts:
    415
    Hi Dave, thanks for your response.

    I don't know exactly to which dll you are referring to but the web services work well on any standard c# app (even a console one), and also, the game as well as the example provided both compile ok (the exception IL occurs at runtime). As you may know, Unity has its own version of System.ServiceModel.dll so, imvho, it is either a problem with that custom dll itself you guys provide and or the old version of the Mono compiler being used by the current version of Unity to compile the scripts. In either way, I do think it's a Unity issue, and if not, I hope the scripting team provides a way to consume the web services as intended (that is, following .NET standards).

    Now, regarding why I want to avoid the use of WWW:
    1) For starters, because the web services were developed by a third party company, so any eventual changes to the services in order to be properly consumed via WWW would require dealing with that third party to get them modify the services to be in line with Unity's way (which could lead to additional costs and time). And taking as an example how long it does take for you guys to get back to me with an status update, you can see how difficult things may turn out to be to persuade a third party to modify/fix its code,
    2) In order to reach that company, I must contact my client (the one who hired them to develop the remote back end) and explain the tech situation in a way it understands (= avoid any situation where he might claim I picked the wrong tech to develop the game),
    3) We are in the final phase of development, fine tuning the game, so having to deal with a workaround for something that should work as is from square one, would thus introduce delays,
    4) As far as I can tell from what I could read (also by googling it), and please correct me if I'm wrong, functionality of WWW is somewhat limited, it is sometimes buggy (specially for mobile) and it feels cumbersome (the more complex the data structures you use), and last but not least,
    5) Because webservice contracts is the standard way to consume webservices in .NET nowadays, and in particular, c#, which in turn it ends up being way easier to debug than with WWW (and now that MSFT has announced better integration with Unity, one may expect that Unity in return will better integrate with .NET/C#, don't you think?).

    Pedro
     
  20. PedroGV

    PedroGV

    Joined:
    Nov 1, 2010
    Posts:
    415
    Well, one step at a time, I have finally found how to avoid the IL exception. According to wiki two dlls have to be added to the assets folder (which of course I added):

    * System.Runtime.Serialization.dll
    * System.ServiceModel.dll

    Luckily, I've just happened to find this blogpost: https://stpdev.wordpress.com/2011/07/14/consuming-a-wcf-service-from-unity3d/

    In it, a third dll is mentioned, System.Security. So after, copying this dll that exception is gone (thanks to the author of that blog!).

    Therefore, and it would be great if this is ammended in the wiki, not two but three dlls have to be imported to the assets folder of the Unity project:

    * System.Runtime.Serialization.dll
    * System.ServiceModel.dll
    * System.Security.dll

    Now, not everything is happiness since a new issue is here:

    NullReferenceException: Object reference not set to an instance of an object
    __clientproxy_Testing_ServicePortType.Status ()
    WebServices.Testing_ServicePortTypeClient.Status () (at Assets/Webservice/Testing_ServicePortTypeClient.cs:59)
    WebServices.WebServiceHandler.get_IsServerOnline () (at Assets/Webservice/WebServiceHandler.cs:146)
    UnityEngine.Debug:LogException(Exception)
    WebServices.WebServiceHandler:get_IsServerOnline() (at Assets/Webservice/WebServiceHandler.cs:150)
    TestScript:OnPress() (at Assets/TestScript.cs:22)
    UnityEngine.EventSystems.EventSystem:Update()

    Again, the service is working ok (tested on a console .NET project), and no reference appears to be null on the example Unity project, so I'll have to investigate what is going wrong now. I'll add an update to the reported issue.
     
  21. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    What type of service are you trying to consume? Judging by the calls, it looks like it's most likely a WCF service (which also explains your probable need for ServiceModel).
     
  22. PedroGV

    PedroGV

    Joined:
    Nov 1, 2010
    Posts:
    415
  23. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    Oh sorry, I had forgotten. :/ Ok, so does it worth from within the editor? Can you get a debug build of the DLL with the debug symbols and debug it via Visual Studio when running in Unity?

    Judging by the exception, it appears as though the Channel isn't being created... it'd be nice to know exactly which object is actually Null so we can find out what's going on. How is it resolving the URL for your service?
     
  24. PedroGV

    PedroGV

    Joined:
    Nov 1, 2010
    Posts:
    415
    It's ok :)

    This is the way I'm creating the channel:
    Code (CSharp):
    1. var binding = new BasicHttpBinding(BasicHttpSecurityMode.None);
    2. binding.MessageEncoding = WSMessageEncoding.Text;
    3. binding.TextEncoding = System.Text.Encoding.UTF8;
    4.  
    5. var endpoint = new EndpointAddress("http://.../ws/status.php");
    6.  
    7. this.wscStatusCheck = new Testing_ServicePortTypeClient(binding, endpoint);
    8. this.wscStatusCheck.InnerChannel.OperationTimeout = Class.DefaultTimeOutTime;
    And it works ok; the issue seems to be within Mono's XML parser for the soap message. How can I assume that? Because if I change the text encoding to Unicode (UTF16) the following exception occurs:

    XmlException: Text node cannot appear in this state. Line 1, position 1.
    Mono.Xml2.XmlTextReader.ReadText (Boolean notWhitespace)

    And if I use another wrong encoding format, like, UTF32, then the exception is:

    WebException: There was an error on processing web request: Status code 500(InternalServerError): Internal Server Error
    System.ServiceModel.Channels.HttpRequestChannel+HttpChannelRequestAsyncResult.WaitEnd ()

    So, given that the correct format of the message is UTF8, it seems to me that this could be a problem of BOM, which is optional in such encoding format (I mean, UTF8). So perhaps the parser (in the version of Mono being used) is waiting for such BOM, when there is none and therefore, the exception occurs:

    NullReferenceException: Object reference not set to an instance of an object
    __clientproxy_Testing_ServicePortType.Status ().

    Can anyone confirm this?
     
    Last edited: Apr 24, 2015
  25. PedroGV

    PedroGV

    Joined:
    Nov 1, 2010
    Posts:
    415
    I finally managed to get it right. It had nothing to do with BOM; actually, it was the structure of the Soap messages sent by the PHP webservices. Fixed the structure, it works fine now.

    The problem that I'm currently facing is that even though the project compiles and runs ok on the editor (PC and Mac) and on Android devices, I'm getting the following exceptions when attempting to compile same project for iOS with Mono as the scripting backend:

    1. Cross compilation job Mono.WebBrowser.dll failed.
    UnityEngine.UnityException: Failed AOT cross compiler: \Applications\Unity\Editor\Data\PlaybackEngines\iossupport\Tools/Win/mono-xcompiler.exe --aot=full,asmonly,nodebug,ficall,static,outfile="Mono.WebBrowser.dll.s" "Mono.WebBrowser.dll" current dir : \Users\...\Temp/StagingArea/Data/Managed
    result file exists: False. Timed out: False

    2. UnityException: Cross compilation failed.
    UnityEditor.iOS.PostProcessiPhonePlayer.PostProcess (UnityEditor.iOS.iOSBuildPostprocessor pp, BuildTarget target, System.String stagingAreaData, System.String stagingArea, System.String stagingAreaDataManaged, System.String playerPackage, System.String installPath, System.String companyName, System.String productName, BuildOptions options, UnityEditor.RuntimeClassRegistry usedClassRegistry)
    UnityEditor.iOS.iOSBuildPostprocessor.PostProcess (BuildPostProcessArgs args)
    UnityEditor.PostprocessBuildPlayer.Postprocess (BuildTarget target, System.String installPath, System.String companyName, System.String productName, Int32 width, Int32 height, System.String downloadWebplayerUrl, System.String manualDownloadWebplayerUrl, BuildOptions options, UnityEditor.RuntimeClassRegistry usedClassRegistry) (at /Users/builduser/buildslave/unity/build/Editor/Mono/BuildPipeline/PostprocessBuildPlayer.cs:316)
    UnityEditor.HostView:OnGUI()

    3. Error building Player: UnityException: Cross compilation failed.

    If I open the project with MonoDevelop, it compiles OK. The exceptions are thrown when generating the output for iOS.

    Any help here will be much appreciated.
     
  26. PedroGV

    PedroGV

    Joined:
    Nov 1, 2010
    Posts:
    415
    Note: with IL2CPP it compiles ok, but as soon as it gets to a webservice call, a Not-Supported-Exception is thrown.

    Why is WCF services supported on all devices except iOS-based ones?
     
  27. PedroGV

    PedroGV

    Joined:
    Nov 1, 2010
    Posts:
    415
    Anyone on the Unity team?