在 Umbraco 11 中处理表单发布

问题描述 投票:0回答:1

我是 umbraco (v11) 的新手,正在努力解决一些我确信可以很快得到回答的问题。

我需要创建一个包含单个文本框和按钮的页面。

当页面呈现时,我们在视图模型中设置一些值。

单击按钮时,表单将被发回服务器并验证数据。 如果数据无效(格式不正确/不是预期值),那么我们将设置模型状态错误并重新呈现页面。

如果值符合预期,那么我们将重定向到另一个页面。

这是我的视图模型

public class ExampleViewModel : PublishedContentWrapped
{
    public ExampleViewModel (IPublishedContent content, IPublishedValueFallback publishedValueFallback) : base(content, publishedValueFallback)
    { }
    
    public string MessageSent { get; set; }
    
    public string PhoneNumber { get; set; }
    
    public string Code { get; set; }
}

这是控制器(为简洁起见被截断)

public class ExampleController : RenderController
    {
        private readonly IVariationContextAccessor _variationContextAccessor;
        private readonly ServiceContext _context;
        private readonly IMediator _mediator;
        
        public ExampleController(
            ILogger<ExampleController> logger,
            ICompositeViewEngine compositeViewEngine,
            IUmbracoContextAccessor umbracoContextAccessor,
            IVariationContextAccessor variationContextAccessor,
            ServiceContext context,
            IMediator mediator)
            : base(logger, compositeViewEngine, umbracoContextAccessor)
        {
            _variationContextAccessor = variationContextAccessor;
            _context = context;
            _mediator = mediator;
        }

        [HttpGet]
        public override IActionResult Index()
        {
            var exampleViewModel = new ExampleViewModel(CurrentPage, new PublishedValueFallback(_context, _variationContextAccessor))
            {
                MessageSentVia = mfaResponse.SendMethod,
                MaskedPhoneNumber = mfaResponse.MaskedContact
            };

            return CurrentTemplate(exampleViewModel);
        }

        [HttpPost]
        public async Task<IActionResult> Index(ExampleViewModel viewModel) 
        {
            if (!ModelState.IsValid)
            {
                ModelState.AddModelError("exampleViewModel", "One or more of the given answers was not in the expected format.");

                return CurrentTemplate(CurrentPage);
            }

            if (viewModel.Code == "1234")
            {
                return Redirect("/NextPage/");
            }

            // Answer is incorrect 

            ModelState.AddModelError("exampleViewModel", validationResponse.ErrorMessage);

           return CurrentTemplate(viewModel);
        }
    }

最后景色是

@using Umbraco.Cms.Web.Common.PublishedModels;
@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage<TP.Landing.Web.UI.ViewModels.ExampleViewModel>
@using ContentModels = Umbraco.Cms.Web.Common.PublishedModels;
@{
    Layout = "Layout.cshtml";
}

<h1>@Model.Value("pageTitle")</h1>

@Model.Value("pageContent")

<p>We have sent you a code via @Model.MessageSentVia to the contact @Model.MaskedPhoneNumber</p>

<div class="container justify-content-center align-items-center mt-3">

    <form action="@Url.Action("")" method="POST" class="col-sm-6 col-md-6 offset-md-3">
        
        @Html.HiddenFor(m=> Model.PhoneNumber)
        @Html.HiddenFor(m=> Model.MessageSent)

        @Html.ValidationSummary("exampleViewModel", true, "", new {@class = "alert alert-danger"})

        <div class="input-group mb-2">
            <input type="text" class="form-control text-center text-uppercase fw-bolder w-100" placeholder="Confirmation Code" asp-for="Code" maxlength="5" size="5" />
        </div>

        <button type="submit" class="btn btn-primary w-100 mt-3">Submit</button>

    </form>

</div>

问题是当我提交表单时出现异常

ModelBindingException: Cannot bind source content type Umbraco.Cms.Web.Common.PublishedModels.Example to model type TP.Landing.Web.UI.ViewModels.ExampleViewModel. The source is a ModelsBuilder type, but the view model is not. The application is in an unstable state and should be restarted.

我有点理解这里的问题是什么,因为 ExampleViewModel 是 Umbraco 发布模型的包装器,并且在帖子中它不会有任何 umbraco 位 - 只是我从包装器中提取的额外内容。

有人可以澄清这里的问题是什么以及我如何解决这个问题吗?

如果我将帖子移到表面控制器中,当他们输入不正确的值时,我们如何将它们放回带有验证消息的表单中?

谢谢

umbraco
1个回答
0
投票

您正在寻找的是一个SurfaceController。该控制器能够处理回发,但将路由留给 Umbraco(因为这是由内容指示的)。

您使用的是 RenderController。渲染控制器用于更改特定文档类型的服务行为。它不是为拦截 HTTP 帖子而构建的。

© www.soinside.com 2019 - 2024. All rights reserved.