.NET 코어 2를 사용합니다. 문자열에 대한 렌더링 면도기 솔루션의 해결책을 발견했습니다. MVC 버전을 낮 춥니 다. 결과/양식이 부트 스트랩 모달로 표시됩니다. 컨트롤러 (예 : 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);
}
뷰 모델 :
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