0

Context

I used this tutorial to build a very basic WCF server and client and I am trying to get it running on an iOS device. I am able to build the application in Unity and in XCode and I am able to connect to the server in the Editor. But I am getting a Null Reference Exception when I actually try to connect the client to the server.

The stack trace shows that this error is being thrown by the System.ServiceModel class.

NullReferenceException: Object reference not set to an instance of an object
at System.ServiceModel.ChannelFactory`1[TChannel].CreateChannel () [0x00000] in <c9bd1c5fa2104489802ea2feced48e51>:0
at callService.Start () [0x0001a] in C:\Users\QA\Documents\Codebase\WCFTest\Assets\Scripts\callService.cs:16

Here is the proxy class that I generated with the svcutil.exe tool found in the Unity installation directory.

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:4.0.30319.42000
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
 
 
 
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(ConfigurationName="IService1")]
public interface IService1 {
 
    [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IService1/GetData", ReplyAction="http://tempuri.org/IService1/GetDataResponse")]
    string GetData(string name, int value);
}
 
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
public interface IService1Channel : IService1, System.ServiceModel.IClientChannel {
}
 
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
public partial class Service1Client : System.ServiceModel.ClientBase<IService1>, IService1 {
 
    public Service1Client() {
    }
 
    public Service1Client(string endpointConfigurationName) :
            base(endpointConfigurationName) {
    }
 
    public Service1Client(string endpointConfigurationName, string remoteAddress) :
            base(endpointConfigurationName, remoteAddress) {
    }
 
    public Service1Client(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) :
            base(endpointConfigurationName, remoteAddress) {
    }
 
    public Service1Client(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) :
            base(binding, remoteAddress) {
    }
 
    public string GetData(string name, int value) {
        return base.Channel.GetData(name, value);
    }
}

I have found a few threads online with related errors that have given me some hints as to why this System.ServiceModel library would be throwing a NullReferenceException at runtime. Including this page which indicates that some .NET libraries that might be referenced by System.ServiceModel are not compatible with iOS and thus might be stripped out somewhere in the build process. I have tried several things but have had no luck so far.

  • I have tried adding a linker file to make sure parts of the System.ServiceModel class are not being stripped out.
  • I have tried using different versions of the System.ServiceModel. I added these duplex versions of the library that were shared by a user on . I have also tried using the version of the library found in the Unity Installation path at: C:\Program Files\Unity\Hub\Editor\2020.3.17f1\Editor\Data\MonoBleedingEdge\lib\mono\2.0-api
  • I have tried overriding the CreateChannels() method which is often cited as necessary to avoid having code that uses dynamic code generation like in this post

1 Answers1

1

After many trial and error attempts at using different svcutil commands and System.ServiceModel DLLs from different places I found this page which indicated which version of System.ServiceModel was compatible with Xamarin.iOS (which I presumed would have similar compatibility limitations to Unity).

Since Windows Phone uses Silverlight and is built with Xamarin I used the System.ServiceModel and System.XML.Serialization that can be found in the Windows Phone SDK folder:

C:\Program Files (x86)\Microsoft SDKs\Windows Phone\v8.0\Tools\MDILXAPCompile\Framework

In order to get this folder I had to download an old .iso version of the Windows Phone sdk from this site and I had to generate a new proxy class using the SLSVCutil executable found in a nearby folder:

C:\Program Files (x86)\Microsoft SDKs\Windows Phone\v8.0\Tools

Using the silverlight versions of the library requires some minor changes to the client class in Unity as follows:

using System.ServiceModel;
using TMPro;
using UnityEngine;

public class CallService : MonoBehaviour
{

    [SerializeField] private TextMeshProUGUI display = null;
    void Start()
    {
        EndpointAddress endpoint = new EndpointAddress("http://192.168.1.15/WcfService/Service1.svc/WcfDemoService");
        BasicHttpBinding binding = new BasicHttpBinding();
        Service1Client client = new Service1Client(binding, endpoint);

        client.GetDataCompleted += PrintToScreen;
        client.GetDataAsync("brennan", 10);
    }

    private void PrintToScreen(object sender, GetDataCompletedEventArgs e)
    {
        string resultString = e.Result;
        Debug.LogWarning(resultString);
        display.text = resultString;
    }
}
sonnyb
  • 3,194
  • 2
  • 32
  • 42