首页 > 解决方案 > asp.net core 2.1 模型绑定(提交后)

问题描述

我有使用 asp.net 的经验,但我是 .net 核心的新手,所以当我尝试执行简单的提交任务时,我得到了奇怪的行为。当我打开视图并向其发送一些模型时,绑定工作正常,但在我提交此表单并尝试返回空模型或更改传递的模型绑定的值不起作用......它保持原来的值提交。

看法

 @model EmailModel


    <div class="w3-col m6 w3-panel">
        <div class="w3-large w3-margin-bottom">
            <i class="fa fa-map-marker fa-fw w3-hover-text-black w3-xlarge w3-margin-right"></i> Rzemieślnicza 26, 30-403 Kraków, POL<br>
            <i class="fa fa-phone fa-fw w3-hover-text-black w3-xlarge w3-margin-right"></i> Telefon: 667 071 064<br>
            <i class="fa fa-envelope fa-fw w3-hover-text-black w3-xlarge w3-margin-right"></i> Email: mail@mail.com<br>
        </div>
        <p>Jeżeli masz jakieś pytania, zastrzeżenia lub wątpliwości napisz do nas</p>
        <p>  <span asp-validation-for="Name" class="text-danger"></span></p>
        <p>  <span asp-validation-for="EmailTo" class="text-danger"></span></p>
        <p>  <span asp-validation-for="Phone" class="text-danger"></span></p>
        <p>  <span asp-validation-for="Subject" class="text-danger"></span></p>
        <p>  <span asp-validation-for="Text" class="text-danger"></span></p>
        @using (@Html.BeginForm("Contacts", "Home", FormMethod.Post))
        {

            <div class="w3-row-padding" style="margin:0 -16px 8px -16px">
                <div class="w3-third">

                    <input asp-for="Name" class="w3-input w3-border" type="text" placeholder="Imię i Nazwisko" required>
                </div>
                <div class="w3-third">

                    <input asp-for="EmailTo" class="w3-input w3-border" placeholder="Email" required />

                </div>
                <div class="w3-third">

                    <input asp-for="Phone" class="w3-input w3-border" type="tel" placeholder="Telefon" required />

                </div>
            </div>
            <div style="width:100%">

                <input asp-for="Subject" class="w3-input w3-border" type="text" placeholder="Temat wiadomości" required>

            </div>

            <textarea asp-for="Text" class="w3-input w3-border" type="text" placeholder="Temat wiadomości" required rows="6"></textarea>

            <button class="w3-button w3-black w3-right w3-section" type="submit">
                <i class="fa fa-paper-plane"></i> Wyślij wiadomość
            </button>
        }

</div>

模型

public class EmailModel
{
    [Required]
    [EmailAddress]
    public string EmailTo { get; set; }
    [Required]
    public string Name { get; set; }
    public string Surname { get; set; }
    [Required]
    [Phone]
    public string Phone { get; set; }
    [Required]
    public string Subject { get; set; }
    [Required]
    public string Text { get; set; }
}

行动

   public IActionResult Contacts()
    {
        ViewData["Title"] = _translation["Contacts"];

        return View(new EmailModel() { Name = "Test" });
    }
    [HttpPost]
    public IActionResult Contacts(EmailModel model)
    {
        if(!ModelState.IsValid)
        {
            return View("Contacts", model);
        }
        try
        {
            string mailBodyhtml = "Imię i Nazwisko: " + model.Name + "<br>" + "Telefon: " + model.Phone + "<br>" + "Email: " + model.EmailTo + "<br><br>" + model.Text;
            var msg = new MailMessage("******", "******", "ZD -"+ model.Subject, mailBodyhtml);
            msg.IsBodyHtml = true;
            var smtpClient = new SmtpClient("******", 587); //if your from email address is "from@hotmail.com" then host should be "smtp.hotmail.com"
            smtpClient.UseDefaultCredentials = true;
            smtpClient.Credentials = new NetworkCredential("***", "*****"); 
            smtpClient.EnableSsl = true;
            smtpClient.Send(msg);
            Console.WriteLine("Email Sended Successfully");
        }
        catch (Exception ex)
        {
            Console.Write(ex.ToString());
        }
        model.Name = "After submit name";

        return View("Contacts" ,model);
    }
  1. 在第一次查看加载Name ="Test"
  2. 提交前开启Name ="My submit name"
  3. 提交后应该是 Name = "After submit name"但它是till ="My submit name"

但是在调试中提交后 Model.Name ="After submit name"

标签: c#asp.net-core

解决方案


视图中显示的值来自ModelState,而不是模型。ModelStateRequestViewData/ViewBagfinally Model的值组成。由于您已经发布了,这意味着现在有一个Namein的值Request,它将优先于您在模型上设置的任何内容。

虽然有一些解决这个问题的方法,但最合适的路径是遵循 PRG(Post-Redirect-Get)模式。本质上,发布后,只有在出现验证错误时才再次返回视图(在这种情况下,您希望重新显示发布的值,以便用户进行必要的更正)。否则,您重定向 - 即使您重定向到相同的操作。纯粹的重定向行为会导致发出一个新的 GET 请求,并具有重置页面的效果,就好像它是第一次加载一样 - 模型中的值适用。


推荐阅读