如何在.NET Core中定义适配Docker Engine API的请求结构——解决ExposedPorts序列化报错问题
解决Docker Engine API中ExposedPorts的.NET结构定义问题
你遇到的cannot unmarshal number into Go struct field ContainerConfigWrapper.ExposedPorts of type nat.PortSet错误,核心原因是Docker Engine API的ExposedPorts字段在Go后端里是nat.PortSet类型——本质是一个键为「端口/协议」字符串、值为空结构体的映射,而你之前定义的.NET结构没有匹配这个格式。
在.NET里,我们可以用两种方式正确定义这个字段:
方式一:使用Dictionary<string, object>快速实现
这是最简便的方式,利用空对象来对应Go里的空结构体:
Public Class ContainerCreateRequest Public Property Hostname As String ' 按照Docker API文档补充其他需要的属性,比如Image、Cmd等 Public Property ExposedPorts As Dictionary(Of String, Object) End Class
使用的时候,给ExposedPorts添加端口协议键和空对象值即可:
Dim postPrm As New ContainerCreateRequest() postPrm.Hostname = "my-test-container" postPrm.ExposedPorts = New Dictionary(Of String, Object)() ' 添加要暴露的端口,格式为"端口号/协议" postPrm.ExposedPorts.Add("80/tcp", New Object()) postPrm.ExposedPorts.Add("443/tcp", New Object()) ' 后续序列化请求的代码保持不变 Dim postData = JsonConvert.SerializeObject(postPrm) Dim response = Encoding.UTF8.GetString(Request.UploadData(URL, Encoding.UTF8.GetBytes(postData)))
序列化后的JSON里ExposedPorts部分会是Docker API期望的格式:
"ExposedPorts": { "80/tcp": {}, "443/tcp": {} }
方式二:定义专用空结构体(更严谨)
如果想让类型更明确,可以专门定义一个空结构体来对应Go里的空结构:
' 空结构体,用于对应Go的struct{} Public Class EmptyStruct End Class Public Class ContainerCreateRequest Public Property Hostname As String ' 其他属性... Public Property ExposedPorts As Dictionary(Of String, EmptyStruct) End Class
使用时替换成空结构体实例:
postPrm.ExposedPorts.Add("80/tcp", New EmptyStruct())
这种方式类型约束更强,避免不小心给值赋了非空内容,序列化后的效果和方式一完全一致。
为什么之前的定义会出错?
如果之前你把ExposedPorts定义成数字数组、字符串数组或者其他非字典类型,序列化后的JSON就会和Docker API期望的键值对格式不匹配,Go后端自然无法反序列化,就会抛出你看到的错误。
内容的提问来源于stack exchange,提问作者user18928007
相关产品推荐
相关产品推荐

