嵌套结构从WCF服务

时间:2017-06-11 22:16:22

标签: 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 LightMagenta;
  public int MaintenanceTankStatus;
  public int WasteInkTankStatus;
};

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct InkInfo {
  public int InkStatus;
  public double Remaining;
};

从服务返回后,所有字段都为空。通常,明显的答案是数据合同不匹配(类似于不同的命名空间)。但请注意,在同一服务中的其他调用,返回另一个非嵌套的struct完美无瑕地工作。命名空间和类似的东西都是正确的。

我尝试的事情:

  • 添加和删除DataContractDataMember属性(包含从程序集级别继承的名称空间和具体设置的名称,只是为了确保)。它们实际上并不是必需的,推断的合同对我来说没问题(通常的注意事项不适用,这是一个固定的打印机SDK,服务的两面都在同一个应用程序中,在我的控制之下)。 / LI>
  • 添加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消息可以):

[assembly: ContractNamespace("http://schemas.example.com/2017/06/printer-service", ClrNamespace = "MyApp.Printers")]

服务端恰好用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()调用都清楚地表明在离开函数之前填充了变量。

1 个答案:

答案 0 :(得分:0)

再一次,电脑是对的。 :-) 在某些结构上的差异,这是一个容易错过的差异:intlong之间的差异。在C#世界中,它们分别是32位和64位,但在C ++ / CLI中(为了保持兼容性)它们都是32位的。我在某个地方定义了一个“长”,这意味着差异......

相关问题