System.UnsupportedException باستخدام WCF على Windows Phone 7
-
21-09-2019 - |
سؤال
هل تمكن أي شخص من التواصل باستخدام WCF على محاكي Windows Phone Series 7؟
الإصدار 1 - باستخدام نمط Async
BasicHttpBinding basicHttpBinding = new BasicHttpBinding();
EndpointAddress endpointAddress = new EndpointAddress("http://localhost/wcf/Authentication.svc");
Wcf.IAuthentication auth1 = new ChannelFactory<Wcf.IAuthentication>(basicHttpBinding, endpointAddress).CreateChannel(endpointAddress);
AsyncCallback callback = (result) =>
{
Action<string> write = (str) =>
{
this.Dispatcher.BeginInvoke(delegate
{
//Display something
});
};
try
{
Wcf.IAuthentication auth = result.AsyncState as Wcf.IAuthentication;
Wcf.AuthenticationResponse response = auth.EndLogin(result);
write(response.Success.ToString());
}
catch (Exception ex)
{
write(ex.Message);
System.Diagnostics.Debug.WriteLine(ex.Message);
}
};
auth1.BeginLogin("user0", "test0", callback, auth1);
هذا الإصدار يكسر على هذا الخط:
Wcf.IAuthentication auth1 = new ChannelFactory<Wcf.IAuthentication>(basicHttpBinding, endpointAddress).CreateChannel(endpointAddress);
رمي System.NotSupportedException
. The exception is not very descriptive and the callstack is equally not very helpful:
في system.servicemodel.diagnosticutility.exceptionutility.buildMessage (استثناء X) في system.servicemodel.diagnosticutilitily.ExceptionUtility.logexception (استثناء e system.ServicEmodel.diagnostil .Createchannel (عنوان EndpointAddress) في WindowsPhoneApplication2.mainpage.dologin () ....
الإصدار 2 - حظر مكالمة WCF
فيما يلي الإصدار الذي لا يستخدم نمط Async.
[System.ServiceModel.ServiceContract]
public interface IAuthentication
{
[System.ServiceModel.OperationContract]
AuthenticationResponse Login(string user, string password);
}
public class WcfClientBase<TChannel> : System.ServiceModel.ClientBase<TChannel> where TChannel : class {
public WcfClientBase(string name, bool streaming)
: base(GetBinding(streaming), GetEndpoint(name)) {
ClientCredentials.UserName.UserName = WcfConfig.UserName;
ClientCredentials.UserName.Password = WcfConfig.Password;
}
public WcfClientBase(string name) : this(name, false) {}
private static System.ServiceModel.Channels.Binding GetBinding(bool streaming) {
System.ServiceModel.BasicHttpBinding binding = new System.ServiceModel.BasicHttpBinding();
binding.MaxReceivedMessageSize = 1073741824;
if(streaming) {
//binding.TransferMode = System.ServiceModel.TransferMode.Streamed;
}
/*if(XXXURLXXX.StartsWith("https")) {
binding.Security.Mode = BasicHttpSecurityMode.Transport;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
}*/
return binding;
}
private static System.ServiceModel.EndpointAddress GetEndpoint(string name) {
return new System.ServiceModel.EndpointAddress(WcfConfig.Endpoint + name + ".svc");
}
protected override TChannel CreateChannel()
{
throw new System.NotImplementedException();
}
}
auth.Login("test0", "password0");
هذا الإصدار يتعطل في System.ServiceModel.ClientBase<TChannel>
البناء. مكدس المكالمات مختلف بعض الشيء:
1.CreateDescription() at System.ServiceModel.ChannelFactory.InitializeEndpoint(Binding binding, EndpointAddress address) at System.ServiceModel.ChannelFactory
1..CTOR (ربط الربط ، endpointaddress remoteaddress) في system.servicemodel.clientbase1..ctor(Binding binding, EndpointAddress remoteAddress) at Wcf.WcfClientBase
أيه أفكار؟
المحلول
كما أشار Scottmarlowe ، تعمل الخدمة التي تم إنشاؤها التلقائيًا. لقد بدأت في مهمة العمل فقط لماذا يعمل الجحيم الدموي والنسخة اليدوية.
لقد وجدت الجاني وهو كذلك ChannelFactory
. لسبب ما new ChannelFactory<T>().CreateChannel()
فقط يلقي استثناء. الحل الوحيد الذي وجدته هو توفير تنفيذ القناة الخاصة بك. وهذا ينطوي:
- تجاوز قاعدة العميل. (اختياري).
- تجاوز clientbase.createchannel. (اختياري).
- قاعدة قناة الفئة الفرعية مع تنفيذ محدد لواجهة WCF الخاصة بك
الآن ، توفر Clientbase بالفعل مثيلًا لمصنع القناة من خلال ChannelFactory
منشأه. إذا قمت ببساطة بالاتصال CreateChannel
ستحصل على نفس الاستثناء. تحتاج إلى إنشاء إنشاء قناة تحددها في الخطوة 3 من الداخل CreateChannel
.
هذا هو الإطار السلكي الأساسي لكيفية ظهور كل شيء معًا.
[DataContractAttribute]
public partial class AuthenticationResponse {
[DataMemberAttribute]
public bool Success {
get; set;
}
[System.ServiceModel.ServiceContract]
public interface IAuthentication
{
[System.ServiceModel.OperationContract(AsyncPattern = true)]
IAsyncResult BeginLogin(string user, string password, AsyncCallback callback, object state);
AuthenticationResponse EndLogin(IAsyncResult result);
}
public class AuthenticationClient : ClientBase<IAuthentication>, IAuthentication {
public AuthenticationClient(System.ServiceModel.Channels.Binding b, EndpointAddress ea):base(b,ea)
{
}
public IAsyncResult BeginLogin(string user, string password, AsyncCallback callback, object asyncState)
{
return base.Channel.BeginLogin(user, password, callback, asyncState);
}
public AuthenticationResponse EndLogin(IAsyncResult result)
{
return Channel.EndLogin(result: result);
}
protected override IAuthentication CreateChannel()
{
return new AuthenticationChannel(this);
}
private class AuthenticationChannel : ChannelBase<IAuthentication>, IAuthentication
{
public AuthenticationChannel(System.ServiceModel.ClientBase<IAuthentication> client)
: base(client)
{
}
public System.IAsyncResult BeginLogin(string user, string password, System.AsyncCallback callback, object asyncState)
{
object[] _args = new object[2];
_args[0] = user;
_args[1] = password;
System.IAsyncResult _result = base.BeginInvoke("Login", _args, callback, asyncState);
return _result;
}
public AuthenticationResponse EndLogin(System.IAsyncResult result)
{
object[] _args = new object[0];
AuthenticationResponse _result = ((AuthenticationResponse)(base.EndInvoke("Login", _args, result)));
return _result;
}
}
}
TLDR ؛ ChannelFactory
.
نصائح أخرى
لا يتم دعم إنشاء الوكيل الديناميكي باستخدام channelfactory.createchannel () على Windows Phone. تم توثيق هذا هنا - http://msdn.microsoft.com/en-us/library/ff426930(vs.96).aspx
سيكون استهلاك خدمة باستخدام آلية "إضافة خدمة مرجعية" في نمط ASYNC هو الطريقة الصحيحة للقيام بها.
وضعت منشور مدونة معًا في هذا الموضوع بالذات: http://blogs.msdn.com/b/andypennell/archive/2010/09/20/using-wcf-on-windows-phone-7-walk-through.aspx