我需要从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完美无瑕地工作。命名空间和类似的东西都是正确的。
我尝试的事情:
DataContract
和DataMember
属性(包含从程序集级别继承的名称空间和具体设置的名称,只是为了确保)。它们实际上并不是必需的,推断的合同对我来说没问题(通常的注意事项不适用,这是一个固定的打印机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()
调用都清楚地表明在离开函数之前填充了变量。
答案 0 :(得分:0)
再一次,电脑是对的。 :-) 是在某些结构上的差异,这是一个容易错过的差异:int
和long
之间的差异。在C#世界中,它们分别是32位和64位,但在C ++ / CLI中(为了保持兼容性)它们都是32位的。我在某个地方定义了一个“长”,这意味着差异......