在Windows Phone 7上使用WCF的System.UnsupportedException
有没有人能够在
Windows Phone Series 7模拟器上使用WCF进行通信?
在过去的两天里我一直在努力,而这正好适合我.我可以在Silverlight 3和Silverlight 4中使用普通的Silverlight控件,但不能使用手机版本.这是我尝试过的两个版本: 版本1 – 使用异步模式 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.例外情况不是很具描述性,而且callstack同样不是很有用: at System.ServiceModel.DiagnosticUtility.ExceptionUtility.BuildMessage(Exception x) at System.ServiceModel.DiagnosticUtility.ExceptionUtility.LogException(Exception x) at System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(Exception e) at System.ServiceModel.ChannelFactory`1.CreateChannel(EndpointAddress address) at WindowsPhoneApplication2.MainPage.DoLogin() .... 版本2 – 阻止WCF调用 这是不使用异步模式的版本. [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>中崩溃.构造函数.调用堆栈有点不同: at System.Reflection.MethodInfo.get_ReturnParameter() at System.ServiceModel.Description.ServiceReflector.HasNoDisposableParameters(MethodInfo methodInfo) at System.ServiceModel.Description.TypeLoader.CreateOperationDescription(ContractDescription contractDescription,MethodInfo methodInfo,MessageDirection direction,ContractReflectionInfo reflectionInfo,ContractDescription declaringContract) at System.ServiceModel.Description.TypeLoader.CreateOperationDescriptions(ContractDescription contractDescription,Type contractToGetMethodsFrom,ContractDescription declaringContract,MessageDirection direction) at System.ServiceModel.Description.TypeLoader.CreateContractDescription(ServiceContractAttribute contractAttr,Type contractType,Type serviceType,ContractReflectionInfo& reflectionInfo,Object serviceImplementation) at System.ServiceModel.Description.TypeLoader.LoadContractDescriptionHelper(Type contractType,Object serviceImplementation) at System.ServiceModel.Description.TypeLoader.LoadContractDescription(Type contractType) at System.ServiceModel.ChannelFactory1..ctor(Binding binding,EndpointAddress remoteAddress) at System.ServiceModel.ClientBase1..ctor(String name,Boolean streaming) at Wcf.WcfClientBase`1..ctor(String name) at Wcf.AuthenticationClient..ctor() at WindowsPhoneApplication2.MainPage.DoLogin() ... 1.CreateDescription() at System.ServiceModel.ChannelFactory.InitializeEndpoint(Binding binding,EndpointAddress address) at System.ServiceModel.ChannelFactory1..ctor(Binding binding,EndpointAddress remoteAddress) at Wcf.WcfClientBase 有任何想法吗? 解决方法
正如scottmarlowe指出的那样,自动生成的服务引用才起作用.我已经开始着手解决为什么它的血腥地狱和手动版本没有.
我找到了罪魁祸首,它是ChannelFactory.出于某种原因,新的ChannelFactory< T>().CreateChannel()只会引发异常.我找到的唯一解决方案是提供您自己的频道实现.这包括: >覆盖ClientBase. (可选的). 现在,ClientBase已经通过ChannelFactory属性提供了通道工厂的实例.如果您只是调用CreateChannel,则会得到相同的异常.您需要在CreateChannel中实例化您在步骤3中定义的通道. 这是它们如何组合在一起的基本线框. [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,object asyncState) { return base.Channel.BeginLogin(user,password,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,System.AsyncCallback callback,object asyncState) { object[] _args = new object[2]; _args[0] = user; _args[1] = password; System.IAsyncResult _result = base.BeginInvoke("Login",_args,asyncState); return _result; } public AuthenticationResponse EndLogin(System.IAsyncResult result) { object[] _args = new object[0]; AuthenticationResponse _result = ((AuthenticationResponse)(base.EndInvoke("Login",result))); return _result; } } } TLDR;如果您想在WP7上使用自己的WCF代码,则需要创建自己的通道类,而不是依赖ChannelFactory. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- 如何在Windows XP下监控Windows服务的状态变化?
- windows-server-2008 – Active Directory用户和组策略
- windows – 有谁知道powershell证书提供程序路径如何映射到
- windows-server-2008 – 将AD DS Server 2003迁移到Server
- linuxRedhat7 windows物理机与虚拟机设置共享目录
- windows-server-2012 – Server 2012陷入重启循环 – lsass
- Office Online Server 在线编辑Office文档,安装部署
- 在Windows上进行Qt dll部署
- windows-7 – Windows 7上的慢速网络文件复制
- Windows server2016 w3wp.exe占用内存过高
- 仅允许与Windows Azure VM的本地网络连接?
- 如何在Windows上安装PyGI(Python Gobject Intros
- 批处理文件 – 在Windows bat文件中设置JAVA_HOM
- windows – LDIFde.exe和CSVde.exe之间的区别
- geopandas安装问题记录:ImportError,DLL load
- Windows Phone 7 – 使用OpenID与PhoneGap和Wind
- winforms – 有更简单的方法来合并Windows Forms
- WPF窗口关闭后会发生什么?
- .net – 分析进程中加载??的本机DLL和程序集的内
- win7系统关闭445端口