ASP.NET MVC Frameworkは、MVCパターンをベースとした、マイクロソフトのウェブアプリケーション開発用のフレームワークです。
0グッド
1クリップ
投稿2019/08/28 07:07
0
1
ASP.NET core MVC でwebアプリを作っています。
カスタムモデルバインダでパラメータの取得失敗した場合、ModelBindingContextのResultにModelBindingResult.Failed()を入れていますが、これだけだとどのパラメータの取得に失敗したかがコントローラに伝わりません。
これを伝える方法はあるでしょうか?
モデルクラス
C#
1[ModelBinder(BinderType =typeof(MyModelBinder))]2public class Model
3{4[Key]5 public int Id { get; set;}67 public string Foo { get; set;}8 public string Bar { get; set;}9 public string Baz { get; set;}10}
モデルバインダ
C#
1public class MyModelBinder: IModelBinder
2{3 public Task BindModelAsync(ModelBindingContext bindingContext)4{5if(bindingContext == null)6 throw new ArgumentNullException(nameof(bindingContext));78 var id =int.Parse(bindingContext.ValueProvider.GetValue("id").FirstValue);9 var foo = bindingContext.ValueProvider.GetValue("foo").FirstValue;10 var bar = bindingContext.ValueProvider.GetValue("bar").FirstValue;11 var baz = bindingContext.ValueProvider.GetValue("baz").FirstValue;1213if(foo != null && bar != null && baz != null)14{15 bindingContext.Result = ModelBindingResult.Success(new Model
16{17 Id = id;18 Foo = foo;19 Bar = bar;20 Baz = baz;21});22}23else24{25 bindingContext.Result = ModelBindingResult.Failed();2627// ここでどのプロパティが取れなかったかをコントローラに通知したい2829}30return Task.CompletedTask;31}32}
public class CustomModelBinderSample
{
public bool Flg { get; set; }
public string A { get; set; }
public string B { get; set; }
public string C { get; set; }
public string D { get; set; }
}
public class CustomModelBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext,
ModelBindingContext bindingContext)
{
if (bindingContext == null)
{
return new ArgumentNullException("bindingContext");
}
var model = new CustomModelBinderSample();
model.Flg = FromPostedData<bool>(bindingContext, "Flg");
model.A = FromPostedData<string>(bindingContext, "A");
model.B = FromPostedData<string>(bindingContext, "B");
model.C = FromPostedData<string>(bindingContext, "C");
model.D = FromPostedData<string>(bindingContext, "D");
if (model.Flg)
{
// 事前に Trim した方がよさそうだが省略
if (string.IsNullOrEmpty(model.A))
{
bindingContext.ModelState.AddModelError("A", "Flg = 1 and TextBox A empty");
}
if (string.IsNullOrEmpty(model.B))
{
bindingContext.ModelState.AddModelError("B", "Flg = 1 and TextBox B empty");
}
if (string.IsNullOrEmpty(model.C))
{
bindingContext.ModelState.AddModelError("C", "Flg = 1 and TextBox C empty");
}
if (string.IsNullOrEmpty(model.D))
{
bindingContext.ModelState.AddModelError("D", "Flg = 1 and TextBox D empty");
}
}
else
{
if (string.IsNullOrEmpty(model.D))
{
bindingContext.ModelState.AddModelError("D", "Flg = 0 and TextBox D empty");
}
}
return model;
}
// ヘルパーメソッド
private static T FromPostedData<T>(ModelBindingContext context, string key)
{
var result = context.ValueProvider.GetValue(key);
context.ModelState.SetModelValue(key, result);
return (T)result.ConvertTo(typeof(T));
}
}
Controler
public ActionResult CustomModelBinderCreate()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult CustomModelBinderCreate([ModelBinder(typeof(CustomModelBinder))]
CustomModelBinderSample sample)
{
if (!ModelState.IsValid)
{
return View(sample);
}
return RedirectToAction("Index", "Home");
}