gpt4 book ai didi

c# - 在 Web.API Controller 中自动反序列化为类似字符串的类

转载 作者:可可西里 更新时间:2023-11-01 09:11:38 31 4
gpt4 key购买 nike

我有一个 Web.API 端点,它将这样的对象作为参数:

public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
public UserName UserName { get; set; }
}

例如:

[Route("api/person")]
[AcceptVerbs("POST")]
public void UpdatePerson(Person person)
{
// etc.
}

(这只是一个例子 - 我们实际上并没有通过我们的 Web.API 端点接受用户名)

我们的 UserName 类是一个对象,它定义了 string 的隐式运算符,因此我们在整个应用程序中都像对待 string 一样对待它.

不幸的是,Web.API 不会自动知道如何将相应的 JavaScript Person 对象反序列化为 C# Person 对象 - 反序列化的 C# Person 对象始终为空。例如,下面是我如何使用 jQuery 从我的 JavaScript 前端调用此端点:

$.ajax({
type: 'POST',
url: 'api/test',
data: { FirstName: 'First', LastName: 'Last', Age: 110, UserName: 'UserName' }
});

如果我离开 UserName 属性,data 参数会正确反序列化为 C# Person 对象(使用 UserName 属性设置为 null)。

我怎样才能让 Web.API 正确地将 JavaScript 对象上的 UserName 属性反序列化到我们自定义的 UserName 类中?


这是我的 UserName 类的样子:

public class UserName
{
private readonly string value;
public UserName(string value)
{
this.value = value;
}
public static implicit operator string (UserName d)
{
return d != null ? d.ToString() : null;
}
public static implicit operator UserName(string d)
{
return new UserName(d);
}
public override string ToString()
{
return value != null ? value.ToUpper().ToString() : null;
}

public static bool operator ==(UserName a, UserName b)
{
// If both are null, or both are same instance, return true.
if (System.Object.ReferenceEquals(a, b))
return true;

// If one is null, but not both, return false.
if (((object)a == null) || ((object)b == null))
return false;

return a.Equals(b);
}

public static bool operator !=(UserName a, UserName b)
{
return !(a == b);
}

public override bool Equals(object obj)
{
if ((obj as UserName) == null)
return false;
return string.Equals(this, (UserName)obj);
}

public override int GetHashCode()
{
string stringValue = this.ToString();
return stringValue != null ? stringValue.GetHashCode() : base.GetHashCode();
}
}

最佳答案

你需要写一个自定义Json.NET Converter为您的 UserName 类。创建自定义转换器后,您需要将其告知 Json.NET。在我的一个项目中,我们将以下代码行添加到 Global.asax.cs 文件中的 Application_Start 方法,让 Json.NET 了解转换器:

// Global Json.Net config settings.
JsonConvert.DefaultSettings = () =>
{
var settings = new JsonSerializerSettings();
// replace UserNameConverter with whatever the name is for your converter below
settings.Converters.Add(new UserNameConverter());
return settings;
};

这是一个应该有效(未经测试)的快速和基本实现。它几乎肯定可以改进:

public class UserNameConverter : JsonConverter
{

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var username = (UserName)value;

writer.WriteStartObject();
writer.WritePropertyName("UserName");
serializer.Serialize(writer, username.ToString());
writer.WriteEndObject();
}

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
// Variables to be set along with sensing variables
string username = null;
var gotName = false;

// Read the properties
while (reader.Read())
{
if (reader.TokenType != JsonToken.PropertyName)
{
break;
}

var propertyName = (string)reader.Value;
if (!reader.Read())
{
continue;
}

// Set the group
if (propertyName.Equals("UserName", StringComparison.OrdinalIgnoreCase))
{
username = serializer.Deserialize<string>(reader);
gotName = true;
}
}

if (!gotName)
{
throw new InvalidDataException("A username must be present.");
}

return new UserName(username);
}

public override bool CanConvert(Type objectType)
{
return objectType == typeof(UserName);
}
}

关于c# - 在 Web.API Controller 中自动反序列化为类似字符串的类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34400191/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com