繁体   English   中英

asp.net core 2.1模型绑定(提交后)

[英]asp.net core 2.1 model binding (after submit)

我有使用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"

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

尽管有一些解决方法,但最合适的方法是遵循PRG(后重定向获取)模式。 本质上,发布后,只有在出现验证错误时才再次返回视图(在这种情况下,您希望重新显示发布的值,以便用户可以进行必要的更正)。 否则,您将重定向-即使您重定向到同一操作。 重定向纯粹的行为导致发行新的GET请求而进行的,如果它是第一个负载复位页面的效果-在模型中的数值适用

正如Chris Pratt所建议的那样,“重定向后获取”模式是合适的。

这是实现此目标的一种方法(使用代码的简化版本)。 在调用RedirectToAction之前,将更新的模型存储在TempData

// using Newtonsoft.Json;

public IActionResult Contacts()
{
    var model = new EmailModel { Name = "Test" };

    if (TempData[nameof(EmailModel)] is string json)
    {
        model = JsonConvert.DeserializeObject<EmailModel>(json);
    }

    return View(model);
}

[HttpPost]
public IActionResult Contacts(EmailModel model)
{
    model.Name = "After submit name";
    TempData[nameof(EmailModel)] = JsonConvert.SerializeObject(model);

    return RedirectToAction("Contacts");
}

由于TempData仅在读取数据之前才存储数据,因此它特别适合于重定向。

菲纳丽找到了我想要的。 解决方案是使用ModelState.Clear();

1)

[HttpPost]
public IActionResult Contacts(EmailModel model)
{
    if(!ModelState.IsValid)
    {
        return View("Contacts", model);
    }
   ///some code
   ModelState.Clear();
    return View("Contacts", new EmailModel() );
}

并且如果我们只需要替换部分视图(例如ajax请求):

2)

[HttpPost]
public IActionResult Contacts(EmailModel model)
{
    if(!ModelState.IsValid)
    {
        return PartialView("Contacts", model);
    }
   ///some code
   ModelState.Clear();
    return PartialView("Contacts", new EmailModel() );
}

Sorce: 成功后清除字段

暂无
暂无

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

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