私は.NETコア2を使用しています。私は文字列にレンダリングレザービューの解決策を見出しました。 MVCのバージョンを下げて使用しました。 私はresult/formをブートストラップモーダルにします。コントローラに投稿すると(UserName
空値)、ModelStateから<span asp-validation-for="UserName" class="text-danger"></span>
という結果が得られません。問題はどこですか? RenderToStringAsync
メソッドとreturn View()
を使用しないと、ModelStateから<span asp-validation-for="UserName" class="text-danger"></span>
という結果が得られます。 常にactionContext
ModelStateの値またはキーも空です。ASP.NET Core 2フォーム入力のバリデーションの文字列へのレイブビュー
私のサーバー側:
public class RazorViewToStringRenderer
{
private readonly IRazorViewEngine viewEngine;
private readonly ITempDataProvider tempDataProvider;
private readonly IHttpContextAccessor _httpContext;
public RazorViewToStringRenderer(
IRazorViewEngine viewEngine,
ITempDataProvider tempDataProvider,
//IServiceProvider serviceProvider,
IHttpContextAccessor httpContext)
{
this.viewEngine = viewEngine;
this.tempDataProvider = tempDataProvider;
_httpContext = httpContext;
}
public async Task<string> RenderToStringAsync(string viewName, object model)
{
var httpContext = _httpContext.HttpContext;
var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor());
using (var sw = new StringWriter())
{
var viewResult = viewEngine.FindView(actionContext, viewName, false);
if (viewResult.View == null)
{
throw new ArgumentNullException($"{viewName} does not match any available view");
}
var viewDictionary = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary())
{
Model = model
};
var viewContext = new ViewContext(
actionContext,
viewResult.View,
viewDictionary,
new TempDataDictionary(actionContext.HttpContext, tempDataProvider),
sw,
new HtmlHelperOptions()
)
{ RouteData = httpContext.GetRouteData() };
await viewResult.View.RenderAsync(viewContext);
return sw.ToString();
}
}
}
クライアント側:
@model EditUserViewModel
<form asp-controller="Account" asp-action="EditUser" asp-antiforgery="true" data-ajax-success="onSuccess" data-ajax="true" data-ajax-begin="onBegin" method="post" class="form-horizontal" role="form">
....
<div class="form-group">
<div class="col-sm-12">
<label asp-for="UserName" class="col-form-label"></label>
<input asp-for="UserName" class="form-control" />
<span asp-validation-for="UserName" class="text-danger"></span>
</div>
</div>
....
</form>
コントローラー:
[HttpPost]
public async Task<IActionResult> EditUser(EditUserViewModel editUserViewModel)
{
var user = await _userManager.FindByIdAsync(editUserViewModel.Id);
if (user != null)
{
user.UserName = editUserViewModel.UserName;
user.FirstName = editUserViewModel.FirstName;
user.LastName = editUserViewModel.LastName;
var result = await _userManager.UpdateAsync(user);
if (ModelState.IsValid)
{
if (result.Succeeded)
return Json("Ok");
}
else
{
return Json(new
{
ModalClose = false,
Data = _renderer.RenderToStringAsync("EditUser", editUserViewModel)
});
}
}
return RedirectToAction("UserManagement", _userManager.Users);
}
塗りつぶし結果:
function onSuccess(data, status, xhr)
{
$("#" + modid + " .modal-body").empty();
$("#" + modid + " .modal-body").html(data.data.result);
}
のViewModel:
public class EditUserViewModel
{
public string Id { get; set; }
[Display(Name = "User Name")]
[Required(ErrorMessage = "UserName required")]
public string UserName { get; set; }
[Display(Name = "First Name")]
[Required(ErrorMessage = "FirstName required")]
public string FirstName { get; set; }
}
あなたの問題を解決した場合は、これを受け入れられた回答としてマークする必要があります。 – CalC