モデルプロパティに割り当てる前に、いくつかの前処理を生データに適用したいとします。つまり、この文字列 "324.32"と "324,32"の両方を二重に変換できるようにするには、カンマをドットで置き換えます。だから私は、その後、適切なプロバイダ[FromBody]属性を持つモデルプロパティバインディング
public class MoneyModelBinderProvider : IModelBinderProvider
{
public IModelBinder GetBinder(ModelBinderProviderContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
if(context.Metadata?.ModelType == null)
{
return null;
}
if (context.Metadata.ModelType.In(typeof(double), typeof(decimal), typeof(float)))
{
return new MoneyModelBinder(context.Metadata.ModelType);
}
return null;
}
}
とStartup.cs
services.AddMvc(options =>
{
options.ModelBinderProviders.Insert(0, new MoneyModelBinderProvider());
});
内側に登録このモデルバインダーに
public class MoneyModelBinder: IModelBinder
{
private readonly Type _modelType;
public MoneyModelBinder(Type modelType)
{
_modelType = modelType;
}
public Task BindModelAsync(ModelBindingContext bindingContext)
{
if (bindingContext == null)
{
throw new ArgumentNullException(nameof(bindingContext));
}
string modelName = bindingContext.ModelName;
ValueProviderResult providerResult = bindingContext.ValueProvider.GetValue(modelName);
if (providerResult == ValueProviderResult.None)
{
return TaskCache.CompletedTask;
}
bindingContext.ModelState.SetModelValue(modelName, providerResult);
string value = providerResult.FirstValue;
if (string.IsNullOrEmpty(value))
{
return TaskCache.CompletedTask;
}
value = value.Replace(",", ".");
object result;
if(_modelType == typeof(double))
{
result = Convert.ToDouble(value, CultureInfo.InvariantCulture);
}
else if(_modelType == typeof(decimal))
{
result = Convert.ToDecimal(value, CultureInfo.InvariantCulture);
}
else if(_modelType == typeof(float))
{
result = Convert.ToSingle(value, CultureInfo.InvariantCulture);
}
else
{
throw new NotSupportedException($"binder doesn't implement this type {_modelType}");
}
bindingContext.Result = ModelBindingResult.Success(result);
return TaskCache.CompletedTask;
}
}
を書いたが、私はいくつかの奇妙な行動に気づいたか、多分私が何かを逃しました。この種のアクションを使用すると、最初のプロバイダはモデル自体のために呼び出され、次にモデルのすべてのプロパティに対して呼び出されます。 [FromBody]属性を使用し、JSONでパラメータを指定すると、プロバイダはモデルに対して呼び出されますが、このモデルのプロパティは呼び出されません。しかし、なぜ? FromBodyでバインダーを使用するにはどうすればいいですか?
カントのコメントを使用して、あなたの周りの簡単な作業は、ビューモデルを受け入れることができるよう(それらのプロパティを文字列として)AutoMapperを使用して、コントローラアクション内のエンティティモデル/ dtoにマップします。 – Steveland83
投稿時にコンテンツタイプヘッダーを明示的に設定していますか? JSONのように見えるだけで、JSONとして解釈されるわけではありません。 –