gpt4 book ai didi

wcf - 在 Windows Phone 7 上使用 WCF 的 System.UnsupportedException

转载 作者:行者123 更新时间:2023-12-04 23:10:18 26 4
gpt4 key购买 nike

有没有人能够在 Windows Phone Series 7 模拟器上使用 WCF 进行通信?

过去两天我一直在尝试,这对我来说正在发生。我可以让普通的 Silverlight 控件在 Silverlight 3 和 Silverlight 4 中工作,但不能在手机版本中工作。这是我尝试过的两个版本:

版本 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);

throw System.NotSupportedException .异常不是很具有描述性,调用堆栈同样不是很有帮助:
   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()   ....

Version 2 - Blocking WCF call

Here is the version that doesn't use the async pattern.

[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> 中崩溃构造函数。调用堆栈有点不同:

在 System.Reflection.MethodInfo.get_ReturnParameter()
在 System.ServiceModel.Description.ServiceReflector.HasNoDisposableParameters(MethodInfo methodInfo)
在 System.ServiceModel.Description.TypeLoader.CreateOperationDescription(ContractDescription contractDescription,MethodInfo methodInfo,MessageDirection 方向,ContractReflectionInfo reflectInfo,ContractDescription declaringContract)
在 System.ServiceModel.Description.TypeLoader.CreateOperationDescriptions(ContractDescription contractDescription,ContractReflectionInfo 反射信息,类型 contractToGetMethodsFrom,ContractDescription declaringContract,MessageDirection 方向)
在 System.ServiceModel.Description.TypeLoader.CreateContractDescription(ServiceContractAttribute contractAttr,类型 contractType,类型 serviceType,ContractReflectionInfo&reflectionInfo,对象 serviceImplementation)
在 System.ServiceModel.Description.TypeLoader.LoadContractDescriptionHelper(类型 contractType,类型 serviceType,对象 serviceImplementation)
在 System.ServiceModel.Description.TypeLoader.LoadContractDescription(类型 contractType)
在 System.ServiceModel.ChannelFactory 1.CreateDescription()
at System.ServiceModel.ChannelFactory.InitializeEndpoint(Binding binding, EndpointAddress address)
at System.ServiceModel.ChannelFactory
1..ctor(绑定(bind)绑定(bind),EndpointAddress remoteAddress)
在 System.ServiceModel.ClientBase 1..ctor(Binding binding, EndpointAddress remoteAddress)
at Wcf.WcfClientBase
1..ctor(字符串名称, bool 流)
在 Wcf.WcfClientBase`1..ctor(字符串名称)
在 Wcf.AuthenticationClient..ctor()
在 WindowsPhoneApplication2.MainPage.DoLogin()
...

有任何想法吗?

最佳答案

正如 scottmarlowe 指出的那样,自动生成的服务引用是有效的。我的任务是弄清楚为什么该死的 hell 它可以工作,而手动版本却不能。

我找到了罪魁祸首,它是ChannelFactory .出于某种原因new ChannelFactory<T>().CreateChannel()只是抛出一个异常。我找到的唯一解决方案是提供您自己的 channel 实现。这涉及:

  • 覆盖 ClientBase。 (选修的)。
  • 覆盖 ClientBase.CreateChannel。 (选修的)。
  • 使用 WCF 接口(interface)的特定实现子类 ChannelBase

  • 现在,ClientBase 已经通过 ChannelFactory 提供了一个 channel 工厂的实例。属性(property)。如果您只是调用 CreateChannel关闭你会得到同样的异常(exception)。您需要从 CreateChannel 中实例化您在步骤 3 中定义的 channel 。 .

    这是所有看起来如何组合在一起的基本线框。
    [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; 如果您想在 WP7 上使用您自己的 WCF 代码,您需要创建自己的 channel 类,而不是依赖 ChannelFactory .

    关于wcf - 在 Windows Phone 7 上使用 WCF 的 System.UnsupportedException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2474759/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com