繁体   English   中英

WCF DataServices(CTP2):客户端和服务之间存在类型不匹配

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

我正在使用WCF Dataservices CTP2和Entity Framework 4.1。 现在,我试图通过我的datacontext获取任何数据,我得到了这个异常:

System.Reflection.TargetInvocationException:调用目标抛出了异常。 ---> System.InvalidOperationException:客户端和服务之间存在类型不匹配。 类型“Crm.Objects.Segmentation”不是实体类型,但响应有效内容中的类型表示实体类型。 请确保客户端上定义的类型与服务的数据模型匹配,或更新客户端上的服务引用。 在System.Data.Services.Client的System.Data.Services.AtomMaterializer.MaterializeResolvedEntry(AtomEntry条目,布尔包含链接)处于System.Data.Services.Client.AtomMaterializer.Materialize(AtomEntry条目,类型expectedEntryType,Boolean includeLinks)处。 System.Data.Services.Client.ProjectPlan.Run上的System.Data.Services.Client.AtomMaterializerInvoker.DirectMaterializePlan(Object materializer,Object entry,Type expectedEntryType)中的AtomMaterializer.DirectMaterializePlan(AtomMaterializer materializer,AtomEntry条目,类型expectedEntryType)(AtomMaterializer materializer) ,AtomEntry条目,类型expectedType)位于System.Data.Services.Client.MaterializeAtom.MoveNextInternal()的System.Data.Services.Client.AtomMaterializer.Read()处于System.Data.Services.Client.MaterializeAtom.MoveNext()at System.Linq.Enumerable.d_ b1 1.MoveNext() at System.Collections.Generic.List MangoCrm.M的1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable 1 source)的1.MoveNext() at System.Collections.Generic.List 1..ctor(IEnumerable 1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable 在MangoCrm.Modules.Replication.ReplicaBuilder.BeginReplication()MangoCrm.Modules.Replication.ReplicationWindowControl.b _0()---内部异常堆栈跟踪结束时的odules.Replication.ReplicaBuilder.GetItems [T](IEnumerable`1查询) ---在System.RuntimeMethodHandle.InvokeMethodFast(IRuntimeMethodInfo方法,Object target,Object []参数,SignatureStruct&sig,MethodAttributes methodAttributes,RuntimeType typeOwner)处于System.RuntimeMethodHandle.InvokeMethodFast(IRuntimeMethodInfo方法,Object target,Object []参数,Signature sig) System.Reflection.RuntimeMethodInfo.Invoke(Object obj,BindingFlags invokeAttr,Binder binder,Object []参数,CultureInfo文化,布尔值skipVisibilityChecks),System.Delegate.DynamicInvokeImpl(Object [] args)at System,MethodAttributes methodAttributes,RuntimeType typeOwner) MS.Internal.Threading.ExceptionFilterHelper.TryCatchWh中的.Windows.Threading.ExceptionWrapper.InternalRealCall(委托回调,Object args,Int32 numArgs) en(对象源,委托方法,对象args,Int32 numArgs,Delegate catchHandler)

这是我的代码:

            var uri = new Uri(webServiceUrl);
            var service = new DataServiceContext(uri);
            MessageBox.Show(service.CreateQuery<Segmentation>("DbSegmentations").ToList().Count.ToString());

有帮助吗?

更新现在好了,我发现我的WCF响应包含一个修改过的实体对象。 这里是:

<?xml version="1.0" encoding="iso-8859-1" standalone="yes"?>
<entry xml:base="http://localhost:99/Services/CrmDataService.svc/"
       xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"
       xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
       xmlns="http://www.w3.org/2005/Atom">
  <id>http://localhost:99/Services/CrmDataService.svc/DbSegmentations(guid'e9854210-85d1-4822-ba70-7e1d3d29cf62')</id>
  <title type="text"></title>
  <updated>2011-06-16T15:07:48Z</updated>
  <author>
    <name />
  </author>
  <link rel="edit" title="Segmentation" href="DbSegmentations(guid'e9854210-85d1-4822-ba70-7e1d3d29cf62')" />
  <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/Companies"
        type="application/atom+xml;type=feed"
        title="Companies"
        href="DbSegmentations(guid'e9854210-85d1-4822-ba70-7e1d3d29cf62')/Companies" />
  <category term="Crm.Data.Segmentation" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
  <content type="application/xml">
    <m:properties>
      <d:Id m:type="Edm.Guid">e9854210-85d1-4822-ba70-7e1d3d29cf62</d:Id>
      <d:Name>Promoter</d:Name>
      <d:Description m:null="true" />
      <d:ReplicaInfo m:type="Crm.Data.ReplicaInfo">
        <d:CreateDate m:type="Edm.DateTime">2011-06-09T20:35:22.29</d:CreateDate>
        <d:ModifyDate m:type="Edm.DateTime">2011-06-09T20:35:22.29</d:ModifyDate>
        <d:CreatedById m:type="Edm.Guid">00000000-0000-0000-0000-000000000000</d:CreatedById>
        <d:ModifiedById m:type="Edm.Guid">00000000-0000-0000-0000-000000000000</d:ModifiedById>
        <d:IsDeleted m:type="Edm.Boolean">false</d:IsDeleted>
      </d:ReplicaInfo>
    </m:properties>
  </content>
</entry>

这是一个问题

 <category
 term="Crm.Data.Segmentation"
 scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"
 />

所以问题是为什么我的Crm.Objects.Segmentation成为Crm.Data.Segmentation? 何要改回来?

UPDATE2我认为问题出在我的数据环境中。 数据上下文具有名称空间Crm.Data。 我的实体在Crm.Objects中。 然后我使用4.0.0 WCF一切都很好,但后来切换到CTP2我的实体获取Crm.Data命名空间而不是正确的Crm.Objects

您是否尝试为DataServiceContext.ResolveNameDataServiceContext.ResolveType实现委托? 这两个代理(如果提供)可用于修复odata名称空间+名称之间的映射,以及在客户端上序列化和反序列化的类型。

这是一个简单的例子:

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;
    }
}

为了使我的实体类在WCF数据服务客户端中工作,我必须做这样的事情(但我使它变得灵活而不是硬编码);

但即使这样做,我也有这个错误:

System.InvalidOperationException:客户端和服务之间存在类型不匹配。 Type WorkItem'不是实体类型,但响应有效内容中的类型表示实体类型。 请确保客户端上定义的类型与服务的数据模型匹配,或更新客户端上的服务引用。

我找到了两个适用于此的修复:

  1. [DataServiceKey("Id")]属性添加到您的实体类。 要么
  2. 重命名您的~Id属性,使其以ID结尾

我很难找到#2 - 看看反编译的IL(这是针对WCF数据服务5.2.0)。 审查后ClientEdmModelClientTypeUtil ,我碰到这个方法来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;
}

这就是name1.EndsWith("ID" ,它是在WCF数据服务的客户端使用POCO时的关键。

希望有所帮助。

刚刚遇到相同的错误消息并将其修复到我的最后。 原来我在服务和客户端之间混合了程序集。 一个是使用Microsoft.Data.Services,另一个是使用System.Data.Services。

我要说你引用的是Segmentation类的另一个实现,而不是服务的实现。 检查出的命名空间SegmentationCreateQuery<>()调用和的命名空间Segmentation类服务。

好的,我认为这是一个新的WCF CTP2的错误。 然后我添加了System.Data.Services 4.0.0引用我在我的数据服务中获得了正确的命名空间。 但后来我使用v4.99.2.0我在我的ds中得到了错误的命名空间。

我有类似的问题,不知道它是否能解决你的问题。

我必须做的是覆盖“CreateDataSource”方法并关闭svc.cs文件中的代理创建。

这是代码:

    protected override DataServiceContext CreateDataSource()
    {
        var db = base.CreateDataSource();
        db.Configuration.ProxyCreationEnabled = false;

        return db;
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM