Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/dart/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_Struct_Datacontract - Fatal编程技术网

C# 嵌套结构从WCF服务返回空

C# 嵌套结构从WCF服务返回空,c#,wcf,struct,datacontract,C#,Wcf,Struct,Datacontract,我需要从WCF服务返回以下嵌套数据,作为调用的out参数: [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct PrinterInfo { public InkInfo Cyan; public InkInfo Magenta; public InkInfo Yellow; public InkInfo Black; public InkInfo LightCyan; public InkInfo L

我需要从WCF服务返回以下嵌套数据,作为调用的
out
参数:

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct PrinterInfo {
  public InkInfo Cyan;
  public InkInfo Magenta;
  public InkInfo Yellow;
  public InkInfo Black;
  public InkInfo LightCyan;
  public InkInfo LightMagenta;
  public int MaintenanceTankStatus;
  public int WasteInkTankStatus;
};

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct InkInfo {
  public int InkStatus;
  public double Remaining;
};
从服务返回时,所有字段均为空。通常,显而易见的答案是数据契约不匹配(类似于不同的名称空间)。但请注意,同一服务中的其他调用,返回另一个非嵌套结构,可以完美地工作。名称空间和所有类似的东西都是正确的

我尝试过的事情:

  • 添加和删除
    DataContract
    DataMember
    属性(这两个属性都是从程序集级别继承的名称空间和专门设置的名称,只是为了确保这一点)。事实上,它们不是必需的,推断出的合同对我来说很好(通常的警告不适用,这是一个固定打印机SDK,服务的双方都在同一个应用程序中,由我控制)
  • 添加
    KnownType(typeof(InkInfo))
    。没有变化
  • 添加
    [DataContract(IsReference=true)]
    。作为结构,这会导致异常
  • 将结构更改为类并再次尝试上述所有操作。没有变化
  • 记录和跟踪通信表明数据是从服务返回的,只有客户机中的反序列化失败
总而言之:简单的结构工作得非常好。只有包含其他结构的结构才会失败。还有什么我忘了试试的吗

更新:这是服务的一个片段,另一个调用返回
BaseInfo
结构。而且它会退回,没有问题

[ServiceContract(Namespace = "http://schemas.example.com/2017/06/printer-service", Name = "printer")]
public interface IPrinterService {
  [OperationContract]
  int GetBaseInfo(uint printerID, out BaseInfo out_BaseInfo);
  [OperationContract]
  int GetInkInfo(uint printerID, out PrinterInfo out_PrinterInfo);
}

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public class BaseInfo {
  public string PrinterSerial;
  public string Name;
  public string ModelName;
};
通常,除非不可避免,否则没有明确的数据契约,只有推断的数据契约。数据约定名称空间是在程序集级别提供的(看起来SOAP消息是正确的):

服务端恰好是用C++/CLI编写的,但看起来几乎相同:

int GetBaseInfo(unsigned int printerID, [Out] BaseInfo% out_BaseInfo) {
  ...
  Log::Debug(out_BaseInfo);
  return result;
}

int GetInkInfo(unsigned int printerID, [Out] PrinterInfo% out_PrinterInfo) {
  ...
  Log::Debug(out_PrinterInfo);
  return result;
}

两个
Log::Debug()
调用都清楚地表明变量在离开函数之前已填充。

再次说明,计算机是正确的。:-)在某些结构中存在差异,这种差异很容易被忽略:
int
long
之间的差异。在C#世界中,它们分别是32位和64位,但在C++/CLI中(为了保持兼容性),它们都是32位。我在某个地方定义了一个“long”,它意味着一种不同…

再一次,计算机是对的。:-)在某些结构中存在差异,这种差异很容易被忽略:
int
long
之间的差异。在C#世界中,它们分别是32位和64位,但在C++/CLI中(为了保持兼容性),它们都是32位。我在某个地方定义了一个“long”,它意味着一个不同…

你能给我们看一个正常和一个不正常的服务代码和数据契约,这样我们就可以比较了吗?你能给我们看GetBaseInfo和GetInkInfo的代码吗?简单地调用频道的同名函数:
return channel.GetBaseInfo(printerID,out\u BaseInfo);return channel.GetBaseInfo(printerID,out\u BaseInfo)int GetBaseInfo(unsigned int printerID, [Out] BaseInfo% out_BaseInfo) {
  ...
  Log::Debug(out_BaseInfo);
  return result;
}

int GetInkInfo(unsigned int printerID, [Out] PrinterInfo% out_PrinterInfo) {
  ...
  Log::Debug(out_PrinterInfo);
  return result;
}