C# 嵌套结构从WCF服务返回空
我需要从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
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
属性(这两个属性都是从程序集级别继承的名称空间和专门设置的名称,只是为了确保这一点)。事实上,它们不是必需的,推断出的合同对我来说很好(通常的警告不适用,这是一个固定打印机SDK,服务的双方都在同一个应用程序中,由我控制)DataMember
- 添加
。没有变化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);正如我提到的,日志记录和跟踪显示数据是由服务提供的,这一点毫无疑问。在测试过程中,我还试图简单地将所有函数替换为除了手动填充out变量之外不做任何其他事情的函数。结构在调用方/客户端中的定义方式完全相同?是的,非常准确,名称中的任何地方都没有输入错误。你能为我们展示一个有效与一个无效的服务代码和数据契约吗,我们可以比较一下吗?你能给我们看一下GetBaseInfo和GetInkInfo的代码吗?简单地调用通道的类似函数:return channel.GetBaseInfo(printerID,out\u BaseInfo)正如我提到的,日志记录和跟踪显示数据是由服务提供的,这一点毫无疑问。在测试期间,我还试图简单地将所有函数替换为除了手动填充out变量之外不做任何其他事情的函数。在调用方/客户机中,结构的定义方式完全相同?是的,非常准确,名称中没有任何键入错误
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;
}