【问题标题】:.input-validation-error to a textbox when the form is redisplayed for failed value.input-validation-error 当表单重新显示失败值时到文本框
【发布时间】:2015-12-18 05:28:25
【问题描述】:

我已经问过question,以了解为什么在我的应用程序中,当我使用模型绑定来验证模型时,文本框会被突出显示(即红色边框和粉红色阴影背景应用于文本框)( TryUpdateModel()),但在我手动验证时没有(ModelState.AddModelError)。现在已经2天了,没有任何答复。我自己尝试了所有事情,但没有成功。所以,我决定换个方式问这个问题。

按照我对 IT 的理解,这是 ModelBinding 处理请求的方式。

  1. ModelBinding 从 httpcontext 获取传入值
  2. 实例化该模型的对象
  3. 尝试将这些值解析为对象
  4. 如果某个属性有问题,它会使用 ModelState.AddModelError 来标记有问题的属性。
  5. 重新显示视图

这是我的问题当表格重新显示时:

对值无效以突出显示的文本框做了什么?

我知道 Site.css 中的类很少,例如应用于文本框的 .input-validation-error.field-validation-error。也许 ModelBinding 在内部使用了诸如 AddCss("#MyTextBox", ".input-validation-error") 之类的命令。

如果我知道它是如何工作的,我可以(也许)手动应用它并解决我的问题。

编辑

根据@Ian Galloway 的要求,这是代码

public class RegistrationController : Controller
{
  public FormViewModel formViewModel;
  private RegistrationService _registrationService = new RegistrationService();
  private SaveService _saveService = new SaveService();
  protected override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var serialized = Request.Form["formViewModel"];
        if (serialized != null)
        {
            formViewModel = (FormViewModel)new MvcSerializer()
                            .Deserialize(serialized);
            TryUpdateModel(formViewModel);
        }
        else
            formViewModel = (FormViewModel)TempData["formViewModel"] 
                            ?? new   FormViewModel();
    }
  protected override void OnResultExecuted(ResultExecutedContext filterContext)
    {
        if (filterContext.Result is RedirectToRouteResult)
            TempData["formViewModel"] = formViewModel;
    }
    public ActionResult SetUpOrganization(string cancel, string nextButton)
    {
        if ((nextButton != null) && ModelState.IsValid)
        {
            if (formViewModel.navigationData.IsAReview)
                return RedirectToAction("RequestPreview");
            return RedirectToAction("ChooseTypeOrganization");
        }
        ViewData["Cities"] = _registrationService.Get_Cities();
        formViewModel.navigationData.NextAction = "SetUpOrganization";
        return View(formViewModel);
    }
  public ActionResult ChooseTypeOrganization(string backButton, string nextButton)
    {
        if (backButton != null)
        {
            return RedirectToAction("SetUpOrganization");
        }
        if (nextButton != null)
        {
            if (formViewModel.navigationData.IsAReview)
                return RedirectToAction("RequestPreview");
            return RedirectToAction("DocumentsPresented");
        }
        ViewData["TypeOrganization"] = _registrationService.Get_AllTypeOrganization();
        formViewModel.navigationData.NextAction = "ChooseTypeOrganization";
        return View(formViewModel);
    }
    public ActionResult DocumentsPresented(string backButton, string nextButton)
    {
        if (backButton != null)
        {
            return RedirectToAction("ChooseTypeOrganization");
        }
        if (nextButton != null)
        {
            //Validation
            if (string.IsNullOrEmpty(formViewModel.registrationData.DocumentPresente))
            {
                ModelState.AddModelError("DocumentPresente", "Veuillez préciser votre
                  autorisation");
                return View(formViewModel);
            }
            //Navigation
            if (formViewModel.navigationData.IsAReview)
                return RedirectToAction("RequestPreview");
            return RedirectToAction("PeopleRecommended");
        }
        formViewModel.navigationData.NextAction = "DocumentsPresented";
        return View(formViewModel);
    }
  public ActionResult PeopleRecommended(string backButton, string nextButton, string deleteButton,
                                          string deletePerson, string addPerson)
    {
        if (backButton != null)
        {
            return RedirectToAction("DocumentsPresented");
        }
        if (nextButton != null)
        {
            ModelState.Clear();
            if (formViewModel.registrationData.PeopleRecommended.Count == 0)
                ModelState.AddModelError("", "Il faut absolument designer un responsable pour la requête");
            //
            if (ModelState.IsValid)
            {
                if (formViewModel.navigationData.IsAReview)
                    return RedirectToAction("RequestPreview");
                return RedirectToAction("StateObjectifs");
            }
            else
            {
                return View(formViewModel);
            }
        }
        //
        if (addPerson != null)
        {
            if (ModelState.IsValid)
            {
                formViewModel.registrationData.PeopleRecommended.Add(
                    _registrationService.Translate_PersonToBeAdded_Into_Person(formViewModel.personToBeAdded)
                    );
                formViewModel.personToBeAdded = null;
            }
            else
            {
                formViewModel.navigationData.NextAction = "PeopleRecommended";
                return View(formViewModel);
            }
        }
        if (deleteButton != null)
        {
            formViewModel.registrationData.PeopleRecommended.RemoveAt(int.Parse(deletePerson));
        }
        ViewData.ModelState.Clear();
        formViewModel.navigationData.NextAction = "PeopleRecommended";
        return View(formViewModel);
    }
    [ValidateInput(false)]
    public ActionResult StateObjectifs(string backButton, string nextButton)
    {
        if (backButton != null)
        {
            return RedirectToAction("PeopleRecommended");
        }
        if (nextButton != null)
        {
            if (string.IsNullOrEmpty(formViewModel.registrationData.Objective) ||
               string.IsNullOrEmpty(formViewModel.registrationData.RequestDetails))
            {
                 if (string.IsNullOrEmpty(formViewModel.registrationData.Objective))
                     ModelState.AddModelError("Objective", "Vous devez préciser l'objectif de votre requête");

                 if (string.IsNullOrEmpty(formViewModel.registrationData.RequestDetails))
                     ModelState.AddModelError("RequestDetails", "Vous devez préciser le contenu de votre requête");
                 return View(formViewModel);
            }

            if (formViewModel.navigationData.IsAReview)
                return RedirectToAction("RequestPreview");
            return RedirectToAction("StateDeadLine");
        }
        return View(formViewModel);
    }

    public ActionResult StateDeadLine(string backButton, string nextButton)
    {
        if (backButton != null)
        {
            return RedirectToAction("StateObjectifs");
        }
        if (nextButton != null)
        {
            if (formViewModel.registrationData.ChooseDifferentDeadLine)
            {
                if (formViewModel.registrationData.DifferentDeadline == null ||
                    string.IsNullOrEmpty(formViewModel.registrationData.ReasonsForDifferentDeadLine))
                {
                    if (formViewModel.registrationData.DifferentDeadline == null)
                        ModelState.AddModelError("DifferentDeadline", "Clickez pour choisir une nouvelle date");
                    if (string.IsNullOrEmpty(formViewModel.registrationData.ReasonsForDifferentDeadLine))
                        ModelState.AddModelError("ReasonsForDifferentDeadLine", "Expliquez brievement pour quoi ce changement");

                    return View(formViewModel);
                }
            }
            return RedirectToAction("RequestPreview");
        }
        formViewModel.navigationData.NextAction = "StateDeadLine";
        return View(formViewModel);
    }
  public ActionResult RequestPreview(string backButton, string nextButton, string reviewInput, string save)
    {
        if (backButton != null)
        {
            return RedirectToAction("StateDeadLine");
        }
        if (nextButton != null)
        {
            _saveService.Save_FormViewModel(formViewModel);   
            return RedirectToAction("Index", "Home");
        }
        if (reviewInput != null)
        {
            formViewModel.navigationData.IsAReview = true;
            return RedirectToAction(RedirectHelpers.RedirectReviewAction(formViewModel.navigationData, reviewInput));
        }
        ViewData["TypeOrganization_Summary"] = _registrationService.Get_TypeOrganization_Summary(
                                                                formViewModel.registrationData.TypeOrganizationID                                                                   );
        if (save != null)
        {
            _saveService.Save_FormViewModel(formViewModel);
            return RedirectToAction("Index", "Home");
        }

        formViewModel.navigationData.NextAction = "RequestPreview";
        return View(formViewModel);
    }
}

编辑编号 2

我选择了一种观点(因为他们都遇到了同样的问题)。该视图称为 StateObjectifs.aspx

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<!-- Script Begin -->
<script src="../../Scripts/tiny_mce/tiny_mce.js" type="text/javascript"></script>
<script type = "text/javascript">
    tinyMCE.init({
        mode: "textareas",
        theme: "advanced",

        theme_advanced_toolbar_location: "top",
        theme_advanced_toolbar_align: "left",
        theme_advanced_statusbar_location: "bottom",
        theme_advanced_resizing: true
    });
</script>
 <!-- End Script -->
<fieldset id = "StateObjectifs">
    <legend>Etape 5:</legend>
    <div id = "left-pane" style = "width:700px">
    <%using (Html.BeginForm("StateObjectifs", "Registration"))
  { %>
   <%: Html.ValidationSummary() %>
  <% = Html.Serialize("formViewModel", Model) %> 
  <table>
    <tr>
        <th><% = Html.LabelFor(x=>x.registrationData.Objective) %></th>
        <td><% = Html.TextBoxFor(x=>x.registrationData.Objective) %>
            <%: Html.ValidationMessageFor(x =>x.registrationData.Objective, "*")%></td>
    </tr>
    <tr>
        <th colspan = "2"><% = Html.LabelFor(x =>x.registrationData.RequestDetails) %></th>
    </tr>
    <tr>
        <td colspan = "2">
            <% = Html.TextAreaFor(x =>x.registrationData.RequestDetails, 10, 75, null) %>

        </td>
    </tr>
  </table>
  </div>
  <div id = "right-pane">
        <ul>
            <li>Les cases pour lesquelles le titre se termine par (*) sont obligatoires</li>
            <li>Pour mieux vous servir, veuillez décrire clairement de manière concise
                votre requête. Par exemple: <i>Les données de l'USAID sur le secteur santé pour l'année 2009</i></li>
        </ul>  
      </div>
      <div class = "clear"></div>

  <fieldset>
            <% Html.RenderPartial("NavigationView", Model.navigationData); %>
  </fieldset>
</fieldset>
<%} %>

感谢您的帮助。

【问题讨论】:

  • 你能发布文本框的视图代码,以及你手动添加模型错误的c#代码吗?
  • @Ian Galloway:检查上面的编辑
  • @Ian Galloway:我尝试发布代码,但格式不好。所以我会尝试选择一些代码并手动编写它们,而不是复制/粘贴所有内容。
  • 干杯:我还需要您渲染文本框的视图部分。

标签: asp.net-mvc model-binding


【解决方案1】:

实际上这个高亮是由渲染文本框的html助手来执行的。它使用给定键检查模型状态是否存在错误,并在必要时添加必要的 CSS 类。

【讨论】:

  • 你好@Darin Dimitrov。很高兴再次拥有你。如果这个突出显示是由 html 助手执行的,为什么当我使用 ModelState.AddModelError 而不是 TryUpdateModel 时这个助手没有检测到错误?
  • 如果您使用TryUpdateModel,是否使用给定键将错误添加到 ModelState 字典中?如果不是,那么这可能就是 HTML 助手不接受它的原因。
  • 是的。实际上,TryUpdateModel 和 ModelState.AddModelError 都会向 ModelSate 添加错误。而且,在这两种情况下,Html.ValidateSummary() 都会在表单顶部显示错误消息。但是,Html.validateMessageFor() 仅在我使用 TryUpdateModel 时有效,而不是在 ModelState.AddModelError() 时有效。同样,文本框仅使用 TryUpdateModel 突出显示,而不是 ModelState.AddModelError()。
  • 您在使用一些复杂的模型类型吗?如果是这样,在这两种情况下,指向 ModelState 字典中错误元素的键是否相同?使用TryUpdateModel 时,可能会在键中添加一个前缀,该前缀与输入的ID 完全匹配,而使用AddModelError 手动添加错误时,情况并非如此。 ValidateSummary 助手在模型状态中显示所有错误消息。
  • 是的。因为我在发送数据以来回查看时正在序列化数据。我创建了 1 个模型,其中包括 3 个子模型。所以我只需要担心序列化 1 个模型,即超级模型。我已经发布了控制器。您还需要视图吗?型号?
【解决方案2】:

我怀疑您遇到的问题是您传递给 ModelState.AddModelError 的“key”参数必须与表单上匹配控件的名称匹配。

(否则,您如何期望视图引擎知道要在错误状态下呈现哪个控件?)

【讨论】:

  • @Ian Galloway:我开始怀疑我没有正确写密钥。然后检查第二次编辑。
  • 嗯。你能看看你的标记并告诉我 Html.TextBoxFor(x=>x.registrationData.Objective) 的名称是什么吗?
  • @Ian Galloway:谢谢。从上面的标记中,我使用了“registrationData.Objective”,而不仅仅是“Objective”。现在,它起作用了。我没想到会这么容易。
【解决方案3】:

高亮是由适用于文本框的 CSS 完成的。所以你需要在下面添加css:

.input-validation-error {
border: 1px solid #ff0000;
background-color: #ffeeee;

}

【讨论】:

    猜你喜欢
    • 2010-11-24
    • 2011-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-11
    • 1970-01-01
    相关资源
    最近更新 更多