C# 从web api返回XML会更改字段名

C# 从web api返回XML会更改字段名,c#,asp.net,.net,asp.net-web-api,C#,Asp.net,.net,Asp.net Web Api,我有一个类,我正试图从我的web api方法中以XML的形式返回该类: [Serializable] public partial class LoggedInUser { public int UserID { get; set; } public string EmailAddress { get; set; } public string FirstName { get; set; } public string LastName { get; set

我有一个类,我正试图从我的web api方法中以XML的形式返回该类:

[Serializable]
public partial class LoggedInUser
{
    public int UserID { get; set; }

    public string EmailAddress { get; set; }

    public string FirstName { get; set; }

    public string LastName { get; set; }

    public short RoleID { get; set; }

    public short UserStatusID { get; set; }

    public DateTime LastLoginDateTime { get; set; }

}
Web API方法很简单:

[HttpGet]
public LoggedInUser Me()
{
    var user = new LoggedInUser() { FirstName = "Test"  };
    return user;
}
这是我在浏览器中点击该方法时在XML中得到的结果:

<_x003C_FirstName_x003E_k__BackingField>Test</_x003C_FirstName_x003E_k__BackingField>
测试
注意FirstName如何更改为其他字段名。这是由于存在我需要的
[Serializable]
属性,因为当会话状态为
outProc


如何解决此问题,即使存在
Serializable
属性,它也会返回与类定义相同的字段名作为响应。

当需要
Serializable
属性时,我总是返回匿名类型

public dynamic Me()
{
    var user = new LoggedInUser() { FirstName = "Test" };
    return new {FirstName = user.FirstName};
}

当需要
Serializable
属性时,我总是返回一个匿名类型

public dynamic Me()
{
    var user = new LoggedInUser() { FirstName = "Test" };
    return new {FirstName = user.FirstName};
}

默认情况下,Web API的
XmlMediaTypeFormmatter
使用
DataContractSerializer

当此序列化程序序列化自动属性时,它会将臭名昭著的
xxx\u BackingField
添加到序列化属性中。为了避免这种情况,您可以做两件不同的事情:

  • 使用
    [DataMember]
    装饰所有自动属性,并继续使用默认的
    DataContractSerializer
  • 将xml媒体类型格式化程序默认序列化程序更改为使用
    XmlSerializer
    。您可以像这样更改global.asax中的配置:
    GlobalConfiguration.configuration.Formatters.XmlFormatter.UseXmlSerializer=true
    有关更多信息,请参阅

使用匿名类型(如另一个答案中所建议的)可以避免问题,因为匿名类没有
[DataContract]
属性。问题是,使用该选项时,始终必须使用匿名类型,这可能需要大量键入,甚至容易出错。

默认情况下,Web API的
XmlMediaTypeFormmatter
使用
DataContractSerializer

当此序列化程序序列化自动属性时,它会将臭名昭著的
xxx\u BackingField
添加到序列化属性中。为了避免这种情况,您可以做两件不同的事情:

  • 使用
    [DataMember]
    装饰所有自动属性,并继续使用默认的
    DataContractSerializer
  • 将xml媒体类型格式化程序默认序列化程序更改为使用
    XmlSerializer
    。您可以像这样更改global.asax中的配置:
    GlobalConfiguration.configuration.Formatters.XmlFormatter.UseXmlSerializer=true
    有关更多信息,请参阅

使用匿名类型(如另一个答案中所建议的)可以避免问题,因为匿名类没有
[DataContract]
属性。问题是,使用该选项时,您始终必须使用匿名类型,这可能需要大量键入,甚至容易出错。

这不是最佳解决方案,但可以避免此问题。请相信我的答案。你是对的。。。如果您可以访问模型的源代码,那么使用DataContract/DataMember属性是更好的解决方案。另一个解决方案是使用AutoMapper,但您有一个不同的选择,即使用XmlSerializer,即使您没有访问模型的权限,它也可以工作。使用AutoMapper或ValueInjector还需要创建新类别、维护它们等等。我更喜欢将其使用重新定义为DTO或视图模型,而不是为了避免属性问题。事实上,序列化为JSON或XML总是让人头疼……是的,它会让人头疼。这就是为什么你总是需要仔细考虑你所做的改变来解决问题。首先,返回动态似乎是一个快速修复方法,但在更改整个序列化过程或模型之前,可能是在特定点解决问题的正确选择。我并不是说你错了,而且对于@TCM来说,你的解决方案符合他的需要。但是,如果您不知道应用程序背后的环境或体系结构决策,则不能说返回动态不是最佳解决方案。:-)我想你已经知道了利弊,但我还是粘贴了链接。干杯这不是最好的解决方案,但可以避免问题。请相信我的答案。你是对的。。。如果您可以访问模型的源代码,那么使用DataContract/DataMember属性是更好的解决方案。另一个解决方案是使用AutoMapper,但您有一个不同的选择,即使用XmlSerializer,即使您没有访问模型的权限,它也可以工作。使用AutoMapper或ValueInjector还需要创建新类别、维护它们等等。我更喜欢将其使用重新定义为DTO或视图模型,而不是为了避免属性问题。事实上,序列化为JSON或XML总是让人头疼……是的,它会让人头疼。这就是为什么你总是需要仔细考虑你所做的改变来解决问题。首先,返回动态似乎是一个快速修复方法,但在更改整个序列化过程或模型之前,可能是在特定点解决问题的正确选择。我并不是说你错了,而且对于@TCM来说,你的解决方案符合他的需要。但是,如果您不知道应用程序背后的环境或体系结构决策,则不能说返回动态不是最佳解决方案。:-)我想你已经知道了利弊,但我还是粘贴了链接。干杯谢谢正是我想要的。谢谢。正是我想要的。