gpt4 book ai didi

c# - Web API - 检测空赋值

转载 作者:太空狗 更新时间:2023-10-30 01:32:53 26 4
gpt4 key购买 nike

我正在尝试提出一种模式,可以检测属性何时设置为 null。类似于 Nullable<T> 的东西类,但更高级一点。我们称它为MoreThanNullable<T> .基本上我需要根据以下 3 种情况做一些不同的事情:

  1. 从未设置该属性
  2. 该属性被设置为空
  3. 该属性设置为 T 的一个实例。

我创建了自己的类来使用“实例化”属性执行此操作,并且它都在测试场景中运行。一些示例代码:

public struct MoreThanNullable<T>
{
private bool hasValue;
internal T value;
public bool Instantiated { get; set; }

public MoreThanNullable(T value)
{
this.value = value;
this.hasValue = true;
Instantiated = true;
}
// ... etc etc...

测试如我所料地通过了:

[TestFixture]
public class MoreThanNullableTests
{
public class AccountViewModel
{
public Guid Id { get; set; }
public string Name { get; set; }
public MoreThanNullable<string> Test1 { get; set; }
public MoreThanNullable<string> Test2 { get; set; }
public MoreThanNullable<string> Test3 { get; set; }
}

[Test]
public void Tests()
{
var myClass = new AccountViewModel();
Assert.AreEqual(false, myClass.Test1.Instantiated);
myClass.Test1 = null;
Assert.AreEqual(true, myClass.Test1.Instantiated);
}
}

接下来,使用相同的 View 模型,我将它连接到我的 REST 服务上的 POST,并传入以下 JSON:

{
Name:"test",
Test1:null,
Test2:"test"
}

...然后一切都崩溃了。 Test1 和 Test3 都没有被实例化!显然,我不希望 Test3 被实例化,但 Test1 保持未实例化是出乎意料的。实际上,我无法区分我通过 REST 收到和没有收到的属性。 (注意:在我们的应用程序中,not set 和 set to null 有明显的区别)

我做错了什么吗?或者这是 Web API 的正确行为?

** 更新 **

我可能没有说清楚的是我已经有效地复制了 Nullable<T>类来实现这一点,包括像这样重载隐式运算符:

public static implicit operator MoreThanNullable<T>(T value)
{
return new MoreThanNullable<T>(value);
}

我似乎总是在我的问题中遗漏重要的东西......

最佳答案

为什么不起作用?在你的 JSON 中

{
Name:"test",
Test1:null,
Test2:"test"
}

Test1 end Test2 是原始类型,但您创建了自己的类型,这些是它应该映射到的属性,因此它不再是原始类型,而是一个复杂的对象。所以实际上您的 JSON 应该也包含对象。如果你把它改成

{
Name:"test",
Test1:{Instantiated:false, value: null},
Test2:{Instantiated:false, value: "test"},
}

因为现在它们是对象并被反序列化。此外,您的结构有一个默认的空构造函数,如果它是一个具有私有(private)默认构造函数的类,它将无法再次工作。

现在,您如何获得像字符串这样的原始类型以反序列化为您的自定义类型?您可以使用自定义 web api action filter 来做到这一点并解析传入的 json 并将其映射到 OnActionExecuting 中的对象.

编辑 2

假设您使用的是 JSON.NET from newtonsoft您可以插入自定义 JSON 转换器。这将是整个 Web API 应用程序的全局更改,不需要自定义过滤器。

public sealed class MoreThanNullableConverter : Newtonsoft.Json.JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType.IsGenericType && objectType.GetGenericTypeDefinition() == typeof (MoreThanNullable<>);
}
public override bool CanWrite { get { return false; } }

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
// return a new MoreThanNullable instance with value
return Activator.CreateInstance(objectType, reader.Value);
}

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}

更改为 webapiconfig.cs

var formatters = GlobalConfiguration.Configuration.Formatters;
var jsonFormatter = formatters.JsonFormatter;
var settings = jsonFormatter.SerializerSettings;
jsonFormatter.SerializerSettings.Converters.Add(new MoreThanNullableConverter());

关于c# - Web API - 检测空赋值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35751561/

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