【发布时间】:2018-11-09 03:04:49
【问题描述】:
我有以下控制器(缩写):
public class ServicesController : Controller
{
private readonly IServiceRepository _repo;
public ServicesController(IServiceRepository repo)
{
_repo = repo;
}
[HttpPost]
public async Task<StatusCodeResult> CreateService([FromBody] JsonServiceEntity service)
{
return await _repo.CreateServiceAsync(new ServiceEntity(service));
}
}
JsonServiceEntity 类看起来像这样(缩写):
public class JsonServiceEntity
{
public string Id { get; set; } = Guid.NewGuid().ToString();
}
Id 是一个 guid 形式的字符串。如果一个是从客户端传入的,我应该使用给定的 ID。如果客户端没有传入任何值,我应该生成一个新的 guid 并使用它。
但是,当客户端没有提供默认值时,我无法让它使用默认值。无论如何,它最终都是一个空字符串。我可以调试并观察它命中属性并为默认值生成一个新的 guid,它会被使用空字符串调用 setter 迅速覆盖。
我在Startup.cs 中的SerializerSettings 上尝试了NullValueHandling 和DefaultValueHandling 的不同值,但这并没有帮助。如果我在Id 属性上设置[Required],我会收到一个ModelState 错误,让我知道尝试的值是null,而不是空字符串。
如何让它取默认值?
CONNECTServiceRegistry.dll!CONNECTServiceRegistry.Models.JsonServiceEntity.Id.set(string value) Line 45 C#
Newtonsoft.Json.dll!Newtonsoft.Json.Serialization.ExpressionValueProvider.SetValue(object target, object value) Unknown
Newtonsoft.Json.dll!Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(Newtonsoft.Json.Serialization.JsonProperty property, Newtonsoft.Json.JsonConverter propertyConverter, Newtonsoft.Json.Serialization.JsonContainerContract containerContract, Newtonsoft.Json.Serialization.JsonProperty containerProperty, Newtonsoft.Json.JsonReader reader, object target) Unknown
Newtonsoft.Json.dll!Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(object newObject, Newtonsoft.Json.JsonReader reader, Newtonsoft.Json.Serialization.JsonObjectContract contract, Newtonsoft.Json.Serialization.JsonProperty member, string id) Unknown
Newtonsoft.Json.dll!Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(Newtonsoft.Json.JsonReader reader, System.Type objectType, Newtonsoft.Json.Serialization.JsonContract contract, Newtonsoft.Json.Serialization.JsonProperty member, Newtonsoft.Json.Serialization.JsonContainerContract containerContract, Newtonsoft.Json.Serialization.JsonProperty containerMember, object existingValue) Unknown
Newtonsoft.Json.dll!Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(Newtonsoft.Json.JsonReader reader, System.Type objectType, Newtonsoft.Json.Serialization.JsonContract contract, Newtonsoft.Json.Serialization.JsonProperty member, Newtonsoft.Json.Serialization.JsonContainerContract containerContract, Newtonsoft.Json.Serialization.JsonProperty containerMember, object existingValue) Unknown
Newtonsoft.Json.dll!Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(Newtonsoft.Json.JsonReader reader, System.Type objectType, bool checkAdditionalContent) Unknown
Newtonsoft.Json.dll!Newtonsoft.Json.JsonSerializer.DeserializeInternal(Newtonsoft.Json.JsonReader reader, System.Type objectType) Unknown
Newtonsoft.Json.dll!Newtonsoft.Json.JsonSerializer.Deserialize(Newtonsoft.Json.JsonReader reader, System.Type objectType) Unknown
Microsoft.AspNetCore.Mvc.Formatters.Json.dll!Microsoft.AspNetCore.Mvc.Formatters.JsonInputFormatter.ReadRequestBodyAsync(Microsoft.AspNetCore.Mvc.Formatters.InputFormatterContext context, System.Text.Encoding encoding) Line 303 C#
Microsoft.AspNetCore.Mvc.Core.dll!Microsoft.AspNetCore.Mvc.Formatters.TextInputFormatter.ReadRequestBodyAsync(Microsoft.AspNetCore.Mvc.Formatters.InputFormatterContext context) Line 57 C#
Microsoft.AspNetCore.Mvc.Core.dll!Microsoft.AspNetCore.Mvc.Formatters.InputFormatter.ReadAsync(Microsoft.AspNetCore.Mvc.Formatters.InputFormatterContext context) Line 116 C#
Microsoft.AspNetCore.Mvc.Core.dll!Microsoft.AspNetCore.Mvc.ModelBinding.Binders.BodyModelBinder.BindModelAsync(Microsoft.AspNetCore.Mvc.ModelBinding.ModelBindingContext bindingContext) Line 158 C#
Microsoft.AspNetCore.Mvc.Core.dll!Microsoft.AspNetCore.Mvc.ModelBinding.ParameterBinder.BindModelAsync(Microsoft.AspNetCore.Mvc.ActionContext actionContext, Microsoft.AspNetCore.Mvc.ModelBinding.IModelBinder modelBinder, Microsoft.AspNetCore.Mvc.ModelBinding.IValueProvider valueProvider, Microsoft.AspNetCore.Mvc.Abstractions.ParameterDescriptor parameter, Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata metadata, object value) Line 239 C#
Microsoft.AspNetCore.Mvc.Core.dll!Microsoft.AspNetCore.Mvc.Internal.ControllerBinderDelegateProvider.CreateBinderDelegate.__Bind|0(Microsoft.AspNetCore.Mvc.ControllerContext controllerContext, object controller, System.Collections.Generic.Dictionary<string, object> arguments) Line 77 C#
Microsoft.AspNetCore.Mvc.Core.dll!Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.BindArgumentsAsync() Line 424 C#
Microsoft.AspNetCore.Mvc.Core.dll!Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(ref Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.State next, ref Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Scope scope, ref object state, ref bool isCompleted) Line 69 C#
Microsoft.AspNetCore.Mvc.Core.dll!Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeInnerFilterAsync() Line 385 C#
Microsoft.AspNetCore.Mvc.Core.dll!Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(ref Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.State next, ref Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Scope scope, ref object state, ref bool isCompleted) Line 692 C#
Microsoft.AspNetCore.Mvc.Core.dll!Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResourceFilter() Line 793 C#
Microsoft.AspNetCore.Mvc.Core.dll!Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(ref Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.State next, ref Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Scope scope, ref object state, ref bool isCompleted) Line 407 C#
Microsoft.AspNetCore.Mvc.Core.dll!Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync() Line 123 C#
Microsoft.AspNetCore.Mvc.Core.dll!Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync() Line 81 C#
Microsoft.AspNetCore.Mvc.Core.dll!Microsoft.AspNetCore.Mvc.Internal.MvcAttributeRouteHandler.RouteAsync.AnonymousMethod__0(Microsoft.AspNetCore.Http.HttpContext c) Line 105 C#
【问题讨论】:
-
你使用的是asp.net core 2.1吗?
-
不是一个信息丰富的。我无法让 Visual Studio 在跟踪中显示对 Guid.NewGuid() 的调用。但是,我可以在默认值和设置器上放置一个断点,看到调用的是默认值,然后是设置器。调用 setter 时,Id 属性具有有效的 guid 值。无论如何,我已经添加了跟踪。
-
是的,这是 asp.net core 2.1。
-
您的客户端是否真的在 JSON 文本中传递了
Id: ""? -
无论我如何尝试,都无法重现它。也许你应该看看客户端。似乎总是设置 Id。
标签: asp.net-core json.net deserialization asp.net-core-webapi