Error trying to use WCF in MonoDroid
I am creating a poof of concept Android App using MonoDroid for C#. So far it is look pretty good. I have however hit a snag when using WCF.
The concept is simple, Create a WCF service with a single method called "Ping" that returns a string "Pong". Wrote a WPF app hit the service and its working fine. But the android app gives me a strange error when try's to hit the service.
First the error that I get
System.TypeLoadException: Could not load type '__clientproxy_IService1' from assembly 'dummy, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.
at System.MonoType.GetMethodImpl (System.String name, BindingFlags bindingAttr, System.Reflection.Binder binder, CallingConventions callConvention, System.Type[] types, System.Reflection.ParameterModifier[] modifiers) [0x00000] in <filename unknown>:0
at System.Type.GetMethod (System.String name, BindingFlags bindingAttr, System.Reflection.Binder binder, CallingConventions callConvention, System.Type[] types, System.Reflection.ParameterM开发者_如何转开发odifier[] modifiers) [0x00000] in <filename unknown>:0
at System.Type.GetMethod (System.String name, System.Type[] types) [0x00000] in <filename unknown>:0
at Mono.CodeGeneration.CodeMethod.UpdateMethodBase (System.Type type) [0x00000] in <filename unknown>:0
at Mono.CodeGeneration.CodeClass.CreateType () [0x00000] in <filename unknown>:0
at System.ServiceModel.ProxyGeneratorBase.CreateProxyTypeOperations (System.Type crtype, Mono.CodeGeneration.CodeClass c, System.ServiceModel.Description.ContractDescription cd) [0x00000] in <filename unknown>:0
at System.ServiceModel.ClientProxyGenerator.CreateProxyType (System.Type requestedType, System.ServiceModel.Description.ContractDescription cd, Boolean duplex) [0x00000] in <filename unknown>:0
at System.ServiceModel.ChannelFactory`1[HelloMonoDroid.IService1].CreateChannel (System.ServiceModel.EndpointAddress address, System.Uri via) [0x00000] in <filename unknown>:0
at System.ServiceModel.ChannelFactory`1[HelloMonoDroid.IService1].CreateChannel (System.ServiceModel.EndpointAddress address) [0x00000] in <filename unknown>:0
at System.ServiceModel.ChannelFactory`1[HelloMonoDroid.IService1].CreateChannel () [0x00000] in <filename unknown>:0
at System.ServiceModel.ClientBase`1[HelloMonoDroid.IService1].CreateChannel () [0x00000] in <filename unknown>:0
at System.ServiceModel.ClientBase`1[HelloMonoDroid.IService1].get_InnerChannel () [0x00000] in <filename unknown>:0
at System.ServiceModel.ClientBase`1[HelloMonoDroid.IService1].get_Channel () [0x00000] in <filename unknown>:0
at HelloMonoDroid.ClientTest.BeginPing (System.AsyncCallback callback, System.Object asyncState) [0x00000] in <filename unknown>:0
at HelloMonoDroid.Activity1.button_Click (System.Object sender, System.EventArgs e) [0x00000] in <filename unknown>:0
This is the interface on the server side
[ServiceContract]
public interface IService1
{
[OperationContract]
string Ping();
}
This is the server side class
public class Service1 : IService1
{
public string Ping()
{
return "Pong";
}
}
The server side works fine as my test WPF app hits it fine.
The Android client side interface uses the asynchronous pattern, but it gave the same error when using a direct synchronous call to the service.
[ServiceContract]
public interface IService1
{
[OperationContract]
string Ping();
[OperationContract(AsyncPattern = true)]
IAsyncResult BeginPing(AsyncCallback callback, object asyncState);
string EndPing(IAsyncResult result);
}
This is the client "proxy" class
class ClientTest : ClientBase<IService1>, IService1
{
public ClientTest(Binding binding, EndpointAddress address)
: base(binding, address)
{
}
public string Ping()
{
return Channel.Ping();
}
public IAsyncResult BeginPing(AsyncCallback callback, object asyncState)
{
return Channel.BeginPing(callback, asyncState);
}
public string EndPing(IAsyncResult result)
{
return Channel.EndPing(result);
}
}
This is the code that does the call.
void CallServer(object sender, EventArgs e)
{
var myBinding = new BasicHttpBinding();
var myEndpointAddress = new EndpointAddress("http://mycomputername:8732/Android/");
_proxy = new ClientTest(myBinding, myEndpointAddress);
_proxy.BeginPing(OnCompletion, null);
}
void OnCompletion(IAsyncResult result)
{
string str = _proxy.EndPing(result);
textbox.Text = "Result is: " + str;
result.AsyncWaitHandle.Close();
}
I'm hoping someone will know a solution or can maybe give me a different approach.
If you can expose your service as a .Net 2.0 style Web Service, those are much better supported by Mono (and thus MonoDroid).
精彩评论