元ネタは以下
HtmlHelper.TextBox uses the model value even when an explicit value provided
https://stackoverflow.com/questions/12271994/htmlhelper-textbox-uses-the-model-value-even-when-an-explicit-value-provided
やりたかったこと
入力欄2つ => 1つでもキーワード検索可 => 一意に特定できたら、入力欄に検索結果をセット
がやりたい。
問題
HtmlヘルパーのTextBoxForを使って表示すると、モデルに検索結果をセットしていても、検索後の表示は入力値のままになってしまう。
片方の入力欄にだけ入力して検索しヒットした場合、もう片方にはその結果が反映されない。
原因
Htmlヘルパーの値は、ModelStateDictionary(入力パラメータ)
=>ViewDataDictionary(結果のモデル)
の順で表示するため
the ModelStateDictionary object, the value of this parameter, the ViewDataDictionary object, and lastly, a value attribute in the html attributes.
https://docs.microsoft.com/en-us/dotnet/api/system.web.mvc.html.inputextensions.textbox?view=aspnet-mvc-5.2
対応方法
モデル値を優先したい場合、ModelStateの値を削除する
@Html.TextBoxFor(model => model.KeywordA, new { @class = "form-control" })
@Html.TextBoxFor(model => model.KeywordB, new { @class = "form-control" })
public class SearchViewModel
{
public string KeywordA { get; set; }
public string KeywordB { get; set; }
}
public class HomeController : Controller
public ActionResult Search(SearchViewModel model)
{
if (ModelState.IsValid)
{
model = repo.Search(model.KeywordA, model.KeywordB);
//検索後の入力値はModelState(入力パラメータ)が優先されるため、検索結果が入らない
//ModelStateの値を削除することで検索結果が表示されるようにする
ModelState.Remove(nameof(SearchViewModel.KeywordA));
ModelState.Remove(nameof(SearchViewModel.KeywordB));
}
return View(model);
}
}