WCF DataServices (CTP2): There is a type mismatch between the client and the service

前端 未结 5 1307
半阙折子戏
半阙折子戏 2021-01-13 17:06

I\'m using WCF Dataservices CTP2 with Entity Framework 4.1. Now then I\'m trying to get any data through my datacontext I get this exception:

System.R

5条回答
  •  不要未来只要你来
    2021-01-13 17:36

    Did you try implementing delegates for DataServiceContext.ResolveName and DataServiceContext.ResolveType? Those 2 delegates, if provided, can be used to fixup the mapping between odata namespaces + names, and the types that are serialized and deserialized on the client.

    Here is a simple example:

    internal class CustomDataServiceContext : DataServiceContext
    {
        public CustomDataServiceContext(Uri serviceRoot)
        : base(serviceRoot, DataServiceProtocolVersion.V3)
        {
            this.ResolveName = ResolveNameFromType;
            this.ResolveType = ResolveTypeFromName;
        }
    
        protected string ResolveNameFromType(Type clientType)
        {
            if (clientType.Namespace.Equals("ODataClient.MSProducts", StringComparison.Ordinal))
            {
                return string.Concat("ODataService.Models.", clientType.Name);
            }
            return clientType.FullName;
        }
    
        protected Type ResolveTypeFromName(string typeName)
        {
            if (typeName.StartsWith("ODataService.Models", StringComparison.Ordinal))
            {
                return this.GetType().Assembly.GetType(string.Concat("ODataClient.MSProducts", typeName.Substring(19)), false);
            }
            return null;
        }
    }
    

    I had to do something like this (but I made it flexible instead of hard-coded) in order to make my entity classes work in the WCF Data Services client;

    But even after doing this, I had this error:

    System.InvalidOperationException : There is a type mismatch between the client and the service. Type WorkItem' is not an entity type, but the type in the response payload represents an entity type. Please ensure that types defined on the client match the data model of the service, or update the service reference on the client.

    I found two fixes that worked for this:

    1. Add a [DataServiceKey("Id")] attribute to your entity class. or
    2. Rename your ~Id property so that it ends with ID

    I figured out #2 the hard way - looking at the decompiled IL (this is for WCF Data Services 5.2.0). After reviewing ClientEdmModel and ClientTypeUtil, I came across this method in ClientTypeUtil:

    private static ClientTypeUtil.KeyKind IsKeyProperty(PropertyInfo propertyInfo, DataServiceKeyAttribute dataServiceKeyAttribute)
    {
      string name1 = propertyInfo.Name;
      ClientTypeUtil.KeyKind keyKind = ClientTypeUtil.KeyKind.NotKey;
      if (dataServiceKeyAttribute != null && dataServiceKeyAttribute.KeyNames.Contains(name1))
        keyKind = ClientTypeUtil.KeyKind.AttributedKey;
      else if (name1.EndsWith("ID", StringComparison.Ordinal))
      {
        string name2 = propertyInfo.DeclaringType.Name;
        if (name1.Length == name2.Length + 2 && name1.StartsWith(name2, StringComparison.Ordinal))
          keyKind = ClientTypeUtil.KeyKind.TypeNameId;
        else if (2 == name1.Length)
          keyKind = ClientTypeUtil.KeyKind.Id;
      }
      return keyKind;
    }
    

    It's that name1.EndsWith("ID" that is the key when using your POCOs on the client side of WCF Data Services.

    Hope that helps.

提交回复
热议问题