KnownTypeAttribute在服务客户端上定义但仍然不知道类型

时间:2016-06-03 06:49:51

标签: c# wcf xamarin.forms

我正在尝试使用Xamarin.Forms从WCF服务获取引用类型,但是当我从服务器获取数据时出现异常。

  

System.Runtime.Serialization.SerializationException:第1行位置错误326.元素“http://tempuri.orgtGetRecordResult”包含“http://schemas.datacontract.org/2004/07/Adapt.Model.Security:User”数据合约的数据。反序列化器不知道映射到此契约的任何类型。

我的代码

[KnownType(typeof(User))]
public partial class DataAccessServiceClient : ClientBase<IDataAccessService>, IDataAccessService, IServiceClient
{
    public DataAccessServiceClient(Binding binding, EndpointAddress endpointAddress) : base(binding, endpointAddress)
    {

    }

    public virtual async Task OpenAsync()
    {
        await Task.Factory.FromAsync(((System.ServiceModel.ICommunicationObject)(this)).BeginOpen(null, null), new System.Action<System.IAsyncResult>(((System.ServiceModel.ICommunicationObject)(this)).EndOpen));
    }

    public virtual Task CloseAsync()
    {
        return Task.Factory.FromAsync(((System.ServiceModel.ICommunicationObject)(this)).BeginClose(null, null), new System.Action<System.IAsyncResult>(((System.ServiceModel.ICommunicationObject)(this)).EndClose));
    }

    public string Authenticate(string username, string password)
    {
        return Channel.Authenticate(username, password);
    }

    public IRecord GetRecord(string ObjectTypeName, object primaryKeyValue, ConnectionInfo connectionInfo)
    {
        return Channel.GetRecord(ObjectTypeName, primaryKeyValue, connectionInfo);
    }
}

[ServiceContract()]
public interface IDataAccessService
{
    [OperationContract()]
    string Authenticate(string username, string password);

    [OperationContract()]
    IRecord GetRecord(string ObjectTypeName, object primaryKeyValue, ConnectionInfo connectionInfo);

}

public static async Task<IDataAccessService> GetDataAccessServiceProxy()
{
    var binding = GetBinding();
    var proxy = new DataAccessServiceClient(binding, new EndpointAddress($"http://10.0.2.152/helpdeskservices/DataAccessService.svc"));
    await proxy.OpenAsync();
    return proxy;
}

private async Task DisplayTask()
{
    try
    {
        var proxy = await App.GetDataAccessServiceProxy();
        var record = proxy.GetRecord(typeof(User).FullName, 1, new Adapt.Model.Data.ConnectionInfo { AuthToken = _AuthToken });
        await DisplayAlert("info", "user details = " + (record as User)?.UserName, "test complete");
    }
    catch (Exception ex)
    {
        await DisplayAlert("error", ex.ToString() + "\n\n\n" + ex.InnerException?.ToString() ?? "No inner exception", "retry");
        await DisplayTask();
    }
}

调用Authenticate工作正常,我假设因为它是一个值类型但是获取User对象有这个问题。

1 个答案:

答案 0 :(得分:1)

您不能将对象用作GetRecord中某个参数的类型(另请参阅this SO问题)。所以你必须改变你的GetRecord合同。一种选择是为您必须使用的所有类型定义基类,并在GetRecord中使用该类。然后在所有派生类的基类上放置KnownType声明。使用Person(基类)和Student / Teacher(派生类)查看this示例。你有与返回值IRecord相同的问题。在某些时候,您必须告诉WCF如何序列化/反序列化由IRecord表示的对象。请参阅this了解如何动态添加KnownType。