F# 多数据成员属性

F# 多数据成员属性,f#,datacontract,F#,Datacontract,主题 对于错误,api返回两种结果,一种是字段error,另一种是一些error\u code,api可以根据参数返回这两种结果,因此不能真正在那里分支 JSON 1 { "error_code": "234", "message": "Api Key is required" } JSON 2 { "code": "NotFound", "message": "Could not find the resource" } 代码 [<DataContr

主题

对于错误,api返回两种结果,一种是字段
error
,另一种是一些
error\u code
,api可以根据参数返回这两种结果,因此不能真正在那里分支

JSON 1

{
    "error_code": "234",
    "message": "Api Key is required"
}
JSON 2

{
    "code": "NotFound",
    "message": "Could not find the resource"
}
代码

[<DataContract>]
type Error = {
    [<field: DataMemberAttribute(Name="code",Name="error_code")>]
    code: string
    [<field: DataMemberAttribute(Name="message")>]
    message: string
}
[]
类型错误={
[]
代码:字符串
[]
消息:string
}
错误

已为命名参数指定了多个值

预期解决方案

如果相同的错误类型可以处理这两种类型的JSON输出

根据给定答案编辑

[<DataContract>]
type Error = {
    [<field: DataMemberAttribute(Name="code")>]
    code: string

    [<field: DataMemberAttribute(Name="error_code")>]
    error_code: string

    [<field: DataMemberAttribute(Name="message")>]
    Message: string
} 
with member this.Code : string =
        if not (String.IsNullOrEmpty(this.code)) then this.code
        else if not (String.IsNullOrEmpty(this.error_code)) then this.error_code
        else ""
[]
类型错误={
[]
代码:字符串
[]
错误代码:string
[]
消息:string
} 
使用此成员。代码:string=
如果不是(String.IsNullOrEmpty(this.code)),则为this.code
否则,如果不是(String.IsNullOrEmpty(this.error\u code)),则为this.error\u code
否则“

我认为F#记录类型不可能直接实现这一点,但根据反序列化程序的行为,您可能可以执行以下操作:

[<DataContract>]
type Error = {
    [<field: DataMemberAttribute(Name="error_code")>]
    numericCode: string
    [<field: DataMemberAttribute(Name="code")>]
    textCode: string
    [<field: DataMemberAttribute(Name="message")>]
    message: string
}
    with member this.code =
        if not (String.IsNullOrEmpty(this.numericCode)) then Some this.numericCode
        else if not (String.IsNullOrEmpty(this.textCode)) then Some this.textCode
        else None
[]
类型错误={
[]
数字代码:字符串
[]
文本代码:字符串
[]
消息:string
}
使用此成员代码=
如果不是(String.IsNullOrEmpty(this.numericCode)),那么一些this.numericCode
否则,如果不是(String.IsNullOrEmpty(this.textCode)),则使用一些this.textCode
没有别的
这样,您仍然需要显式处理类型中的不同情况,但它允许您从代码中调用
error.code
,而不必担心这两个单独的字段

根据您使用的反序列化程序库的不同,您可能可以使用访问修饰符来隐藏这两个字段(但这对于记录来说可能是不切实际的),或者使其类型
选项
,以便类型使用者知道他们应该处理缺少的值



如果使用不同的字段指定多个示例,FSharp.Data也会这样做:它将它们合并在一起,创建一个能够表示所有示例的类型,并为所有示例中不存在的值提供可选字段。然后由您为特定于应用程序的映射编写帮助函数或类型扩展。

那么您的问题是什么?是否可以为多个json字段设置一个数据成员属性,该属性可以在一个字段中存储代码或错误代码回答:否,它不可能发出警告,然后一些数字代码请检查我的编辑,你看到它有任何问题吗?如果缺少任何一个值,
DataMemberAttribute
具有
IsRequired
属性,默认情况下为false,它应该可以工作。在这种情况下,反序列化程序应该将缺少的字段初始化为null。通过
,watning可能缺少访问权限,我在稍后编辑了它-我将编辑答案以添加它。你的编辑看起来不错,如果它做了我们期望它做的:)太好了。使用访问修饰符隐藏这两个字段,你能帮我处理代码吗?我不熟悉这种语法,是的,我想隐藏那些
numericCode
textCode
,我使用的是
DataContractJsonSerializer
,这取决于反序列化程序是否可以找到字段,例如,通过使用反射-尝试一下并查看。但是对于C#类,我认为大多数类(*使用DataMember属性的类)都使用私有setter处理私有字段和属性,所以我希望它在这里也能工作。