[個人筆記] .net core 3.1 程式碼筆記

  • 240
  • 0

純粹是自己會用到的各種筆記備註

 

 

如果需要寫一個自己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());
 })