純粹是自己會用到的各種筆記備註
如果需要寫一個自己json convert (ps. POST json body才有效果。queryString 無法吃到此jsonConverter)
此範例為 同時允許 timestamp格式、又允許yyyy-MM-dd的常用時間格式 (ps. 這是newtonsoft版本的 如果是 System.Text.Json 寫法不太一樣)
/// <summary>
/// 使用方法 options.SerializerSettings.Converters.Add(new ApiAlwaysTimestampConverterNewtonsoft());
/// </summary>
public class ApiAlwaysTimestampConverterNewtonsoft : JsonConverter<DateTime>
{
public override DateTime ReadJson(JsonReader reader, Type objectType, DateTime existingValue, bool hasExistingValue, JsonSerializer serializer)
{
string myValue = reader.Value.ToString();
if (myValue.IsNumeric())
{
return Double.Parse(myValue).UnixTimeStampToDateTime();
}
return DateTime.Parse(myValue);
}
public override void WriteJson(JsonWriter writer, DateTime value, JsonSerializer serializer)
{
string resultValue = value.ToString("yyyy-MM-ddTHH:mm:ssZ");
JToken t = JToken.FromObject(resultValue);
t.WriteTo(writer);
}
}
自訂DateTime的modelBinder
但我在try的時候 一度一直遇到modelValid失敗,但後來不曉得改了哪邊、又好了 ...
public class DateTimeModelBinder : IModelBinder
{
private readonly ILogger _logger;
public DateTimeModelBinder(ILoggerFactory loggerFactory)
{
if (loggerFactory == null)
{
throw new ArgumentNullException(nameof(loggerFactory));
}
}
public Task BindModelAsync(ModelBindingContext bindingContext)
{
if (bindingContext == null)
{
throw new ArgumentNullException(nameof(bindingContext));
}
var modelName = bindingContext.ModelName;
var valueProviderResult = bindingContext.ValueProvider.GetValue(modelName);
if (valueProviderResult == ValueProviderResult.None)
{
// no entry
return Task.CompletedTask;
}
var modelState = bindingContext.ModelState;
modelState.SetModelValue(modelName, valueProviderResult);
var metadata = bindingContext.ModelMetadata;
var type = metadata.UnderlyingOrModelType;
var value = valueProviderResult.FirstValue;
object model;
if (string.IsNullOrWhiteSpace(value))
{
model = null;
}
else if (type == typeof(DateTime))
{
if (value.IsNumeric())
{
model = double.Parse(value).UnixTimeStampToDateTime();
}
else
{
model = DateTime.Parse(value);
}
}
else
{
// unreachable
throw new NotSupportedException();
}
// When converting value, a null model may indicate a failed conversion for an otherwise required
// model (can't set a ValueType to null). This detects if a null model value is acceptable given the
// current bindingContext. If not, an error is logged.
if (model == null && !metadata.IsReferenceOrNullableType)
{
modelState.TryAddModelError(
modelName,
metadata.ModelBindingMessageProvider.ValueMustNotBeNullAccessor(
valueProviderResult.ToString()));
}
else
{
bindingContext.Result = ModelBindingResult.Success(model);
}
return Task.CompletedTask;
}
}
public class CustomModelBinderProvider : IModelBinderProvider
{
public IModelBinder GetBinder(ModelBinderProviderContext context)
{
if (context.Metadata.ModelType == typeof(DateTime))
{
var loggerFactory = context.Services.GetRequiredService<ILoggerFactory>();
return new DateTimeModelBinder(loggerFactory);
}
return null;
}
}
services
.AddControllers(x =>
{
x.ModelBinderProviders.Insert(0, new CustomModelBinderProvider());
})