繁体   English   中英

剃刀视图以ASP.NET Core 2表单输入验证为字符串

[英]Razor view to string with ASP.NET Core 2 form inputs validation

我使用.NET core2。我发现了将渲染剃刀视图转换为字符串的解决方案。 我使用过较低版本的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值或键也为空。

我的服务器端:

  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; }
}

我已添加到Startup.cs:

services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();

var viewDictionary = new ViewDataDictionary(new EmptyModelMetadataProvider(), _contenxt.ActionContext?.ModelState ?? new ModelStateDictionary())
 {
  Model = model
 };

似乎有效

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM