Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/extjs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在WCF中将共享数据类型用作数据协定_C#_Wcf - Fatal编程技术网

C# 在WCF中将共享数据类型用作数据协定

C# 在WCF中将共享数据类型用作数据协定,c#,wcf,C#,Wcf,从我所看到的,我必须为我想要通过WCF传输的每种数据创建一个“特殊”数据类型,所以如果我有一个像 public class District { public long Id { get; set; } public string Name { get; set; } } 我想使用WCF发送一个District对象,我必须创建一个datacontract,因此我必须创建一个新的WCF类 [DataContract] public class WCFDistrict {

从我所看到的,我必须为我想要通过WCF传输的每种数据创建一个“特殊”数据类型,所以如果我有一个像

public class District
{
    public long Id { get; set; }
    public string Name { get; set; }
}
我想使用WCF发送一个District对象,我必须创建一个datacontract,因此我必须创建一个新的WCF类

[DataContract]
public class WCFDistrict
{
    [DataMember]
    public long Id { get; set; }

    [DataMember]
    public string Name { get; set; }
}
然后,当我在实现中的WCF服务中使用它时,我必须将数据从一个对象解析到另一个对象

public WCFDistrict GetDistrict(long id)
{
    var district = _districtRepository.GetDistrict(id);
    return new WCFDistrict {Id = district.Id, Name = district.Name};
}

有没有办法将共享类作为DataContract重用,而不在其上添加这些属性?或者我应该在他们可以共享的类上创建一个接口,这样我就可以在他们之间强制转换它了?还是第三个?

您需要这些属性。为了让您的生活更轻松,您可以使用像
AutoMapper
这样的工具来对数据传输对象进行布线,因为所有属性的手动设置可能会很繁琐


无论如何,最好将模型类与数据契约分开,这样对模型的更改就不必直接影响数据契约。

首先,不严格要求您提供数据契约;只要您在.NET3.5SP1或更高版本上,WCF就会正确序列化普通旧类对象(POCO)

第二,您可以在服务器端和客户端的项目中共享相同的物理类文件;我们的项目中有数百个类(和代码),它们以这种方式直接共享,这在开发和测试中节省了大量的时间和精力

要启动并运行它,需要几个步骤(从内存中执行此操作,因此我可能需要调整答案):

1) 在客户端,如果您使用的是VB,请在与要在客户端中使用的类相同的默认命名空间中创建一个项目(对于C#,这并不重要,因为命名空间嵌入在类中)

2) 将类文件作为链接添加到项目中,这样您就有了类的一个物理副本

3) 如果您还没有WCF配置,请向WCF配置中添加一个

4) 在客户端,右键单击服务并选择配置服务引用。。。在生成的对话框中,确保选中了所有引用程序集中的
重用类型
,并选择了所有引用程序集中的
重用类型
选项

5) 要想让它发挥作用,最棘手的部分是收集

a) 使用属性装饰集合

b) 将此集合的条目添加到
reference.svcmap
CollectionMappings
表中。要查找reference.svcmap,请显示项目中的所有文件,然后展开服务。要编辑它,只需双击该文件。对于要序列化的每个特定集合,您将在此处添加一个条目,并且需要区分具有列表库的项和具有词典库的项。如果不执行此步骤,WCF将自动将这些类序列化为底层泛型签名,您将失去对类的使用

此表中的条目如下所示:

<CollectionMappings>
  <CollectionMapping TypeName="System.Collections.Generic.Dictionary`2" Category="Dictionary" />
  <CollectionMapping TypeName="System.Collections.Generic.List`1" Category="List" />
  <CollectionMapping TypeName="System.Collections.Specialized.StringCollection" Category="List" />
  <CollectionMapping TypeName="My.Namespace.MyDictionaryCollection" Category="Dictionary" />

添加这些条目并保存文件时,WCF客户端生成器将根据您使用的语言重新生成reference.cs或reference.vb文件。您可以通过查看生成的代码来判断是否未正确配置引用:如果该代码包含类定义,则由于某种原因,WCF代码生成器无法映射到复制的类中

最后一点注意:有时WCF代码生成器完全无法生成代码,这总是由于服务中的问题(通常类不够唯一,或者类型由于某种原因无法序列化)

为了调试这类问题,最简单的方法是添加WCF诊断日志记录,它将生成一个文件,该文件可以由一个特殊工具(忘记它的名称)打开,该工具允许您深入查看错误消息并准确地发现出错的地方。这为我们节省了数不清的工作时间。要配置此日志记录,请将以下内容添加到
部分的web.config中的任意位置:

  <system.diagnostics>
    <sources>
      <source name="System.ServiceModel"
              switchValue="Information, ActivityTracing"
              propagateActivity="true">
        <listeners>
          <add name="traceListener"
              type="System.Diagnostics.XmlWriterTraceListener"
              initializeData="c:\log\WcfTrace.svclog"  />
        </listeners>
      </source>
    </sources>
  </system.diagnostics>

添加并保存web.config后,尝试更新客户端中的服务引用,然后双击指定的日志文件,工具将打开