草庐IT

c# - 不同情况下呈现的 bool 字段

coder 2024-05-28 原文

对于任何有想法的人来说,这有点奇怪……我正在特定页面上渲染一个隐藏的 bool 字段。但是,根据特定事件是否在流程之前发生,我会为同一字段获得两个略有不同的标记。正在生成的两个字段是;

<input id="HasPreviouslyIssuedCard" name="HasPreviouslyIssuedCard" type="hidden" value="false" />


<input id="HasPreviouslyIssuedCard" name="HasPreviouslyIssuedCard" type="hidden" value="False" />

问题是“value”属性中的文本的情况,您会注意到它是不同的,并且稍后会影响 JS 条件。生成这个的 Razor 标记是;
@Html.Hidden("HasPreviouslyIssuedCard", Model.HasPreviouslyIssuedCard?.ToString(), new { id = nameof(Model.HasPreviouslyIssuedCard) })

但是,我也尝试了使用以下内容的变体,在渲染隐藏字段方面具有相同的区别;
@Html.HiddenFor(m => m.HasPreviouslyIssuedCard)

我该怎么做才能获得这种差异?为了获得大写的变体,我在进入相关页面之前点击了浏览器的后退按钮。这两种方法都以相同的方式加载数据,并以相同的方式将相同的值传递给渲染器。两种不同的输出。

请记住,这是一个正在呈现的 bool 值类型字段。应该没有太大的修补余地。有多种方法可以解决这个问题,但由于我们在 backlog 中有几个与 bool 字段和后退按钮相关的项目,我想解释一下而不是解决它。

我最好的猜测是,点击后退按钮以某种方式改变了渲染器的状态,或者模型中的其他一些标志不同(有 70 多个字段,因为它是一个向导)正在改变渲染器解释如何区分 bool 值的方式值(value)。值相同,页相同,数据读取方式相同。

基于此页面 ( Why does Boolean.ToString output "True" and not "true" ),假设我们应该一直获得大写变体,但这不是结果。

任何接受者/想法/想法?

编辑 1

HiddenFor() 中挖掘 MVC 的渲染逻辑方法,最终 Convert.ToString(value, CultureInfo.CurrentCulture)叫做。当直接调用时,我无法让它产生一个小写的 bool 值,但它显然是这样做的。我当前的文化代码设置为 en-IE但是在直接调用它时我看到的是大写的 bool 值。

编辑 2

我已经对我的应用程序进行了更多的修补和跟踪,并且可以提供有关正在发生的事情的更多详细信息,尽管我还没有能够在更简单的应用程序中重现这一点。

MVC 5 应用程序:它有;
  • 初始登录页面,其 URL 位于根域 /通过 HTTP 检索 GET . bool input标签呈现为 True/False
  • 位于 URL /Apply 的向导中的第一页通过 HTTP 检索 GET . bool input标签呈现为 True/False
  • 用户在第 2 步提交页面后,向导中位于相同 URL 的第二页。通过 HTTP POST 检索. input案例标签现在呈现为 true/false .
  • 点击浏览器的后退按钮并点击陷阱页面(我们将浏览器历史设置为总是在后退上点击陷阱页面,因为它与向导一起玩得很开心)。
  • 用户点击陷阱页面上的按钮将他们带回他们离开的应用程序。 input标签现在以大写形式返回渲染(最初报告的问题)。

  • 我一直在深入研究 MVC 库,使用 ILSpy 尝试扫描,MVC(如果我正确阅读代码)实际上使用了 IConverter 的实现。写入 bool 值,而不是 Convert.ToString(value, CultureInfo.CurrentCulture)正如我最初的想法。

    从对 HiddenFor() 的调用跟踪的代码堆栈是(我认为);
  • System.Web.Mvc.InputExtentions.HiddenFor() (公共(public)功能)
  • System.Web.Mvc.InputExtentions.HiddenHelper() (私有(private)函数,这里有一些用于数组的逻辑,但不适用于我们的情况)
  • System.Web.Mvc.InputExtentions.InputHelper() (私有(private)函数,魔法在这里发生)
  • System.Web.Mvc.InputExtentions.InputHelper()的反编译代码;
    private static MvcHtmlString InputHelper(HtmlHelper htmlHelper, InputType inputType, ModelMetadata metadata, string name, object value, bool useViewData, bool isChecked, bool setId, bool isExplicitValue, string format, IDictionary<string, object> htmlAttributes)
    {
        string fullHtmlFieldName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);
        if (string.IsNullOrEmpty(fullHtmlFieldName))
        {
            throw new ArgumentException(MvcResources.Common_NullOrEmpty, "name");
        }
        TagBuilder tagBuilder = new TagBuilder("input");
        tagBuilder.MergeAttributes<string, object>(htmlAttributes);
        tagBuilder.MergeAttribute("type", HtmlHelper.GetInputTypeString(inputType));
        tagBuilder.MergeAttribute("name", fullHtmlFieldName, true);
        string text = htmlHelper.FormatValue(value, format);
        bool flag = false;
        switch (inputType)
        {
        case InputType.CheckBox:
        {
            bool? flag2 = htmlHelper.GetModelStateValue(fullHtmlFieldName, typeof(bool)) as bool?;
            if (flag2.HasValue)
            {
                isChecked = flag2.Value;
                flag = true;
            }
            break;
        }
        case InputType.Hidden:
            goto IL_131;
        case InputType.Password:
            if (value != null)
            {
                tagBuilder.MergeAttribute("value", text, isExplicitValue);
                goto IL_16C;
            }
            goto IL_16C;
        case InputType.Radio:
            break;
        default:
            goto IL_131;
        }
        if (!flag)
        {
            string text2 = htmlHelper.GetModelStateValue(fullHtmlFieldName, typeof(string)) as string;
            if (text2 != null)
            {
                isChecked = string.Equals(text2, text, StringComparison.Ordinal);
                flag = true;
            }
        }
        if (!flag && useViewData)
        {
            isChecked = htmlHelper.EvalBoolean(fullHtmlFieldName);
        }
        if (isChecked)
        {
            tagBuilder.MergeAttribute("checked", "checked");
        }
        tagBuilder.MergeAttribute("value", text, isExplicitValue);
        goto IL_16C;
        IL_131:
        string text3 = (string)htmlHelper.GetModelStateValue(fullHtmlFieldName, typeof(string));
        tagBuilder.MergeAttribute("value", text3 ?? (useViewData ? htmlHelper.EvalString(fullHtmlFieldName, format) : text), isExplicitValue);
        IL_16C:
        if (setId)
        {
            tagBuilder.GenerateId(fullHtmlFieldName);
        }
        ModelState modelState;
        if (htmlHelper.ViewData.ModelState.TryGetValue(fullHtmlFieldName, out modelState) && modelState.Errors.Count > 0)
        {
            tagBuilder.AddCssClass(HtmlHelper.ValidationInputCssClassName);
        }
        tagBuilder.MergeAttributes<string, object>(htmlHelper.GetUnobtrusiveValidationAttributes(name, metadata));
        if (inputType == InputType.CheckBox)
        {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.Append(tagBuilder.ToString(TagRenderMode.SelfClosing));
            TagBuilder tagBuilder2 = new TagBuilder("input");
            tagBuilder2.MergeAttribute("type", HtmlHelper.GetInputTypeString(InputType.Hidden));
            tagBuilder2.MergeAttribute("name", fullHtmlFieldName);
            tagBuilder2.MergeAttribute("value", "false");
            stringBuilder.Append(tagBuilder2.ToString(TagRenderMode.SelfClosing));
            return MvcHtmlString.Create(stringBuilder.ToString());
        }
        return tagBuilder.ToMvcHtmlString(TagRenderMode.SelfClosing);
    }
    

    编辑 3

    只是重申一下,因为有一些关于 javascript 方面的评论。我很早就在尝试诊断问题时考虑过这一点。为了排除任何潜在的 JS 干扰/操纵,我使用 Fiddler 来捕获传输中的 HTML。 MVC 生成的 HTML 正在改变大小写 - 我可以在 Fiddler 中看到这一点,甚至在 JS 加载之前,更不用说运行了。这不是JS问题。

    最佳答案

    看来我错了,毕竟是 JS,虽然不是在我试图排除它的时候。重现这一点的事件序列;

  • 创建 HTML form带有 bool 隐藏字段 + 非提交按钮
  • onclick按钮的事件,有一段 JS 将 bool 字段设置为 true (小写)
  • 在 Controller 中的 POST 操作中,呈现相同的 View

  • 在 POST 之后, bool 字段将具有小写值而不是大写值。

    这是怎么回事?那么,HiddenFor() (及其变体)将呈现来自 ViewData.ModelState 的 bool 值而不是模型属性的 ToString()如果 key 存在于 ModelState 中,则值收藏。看起来很直观,但可以(对我来说)可以抛出的是所有其他数据类型,模型绑定(bind)器非常具体 - ModelState value 和您模型的属性值将相同。除了 bool 值 - 模型绑定(bind)器足够智能来处理 Truetrue与转换 POST 时相同,但这会留下 ModelState如果它是通过 JS bool 值设置的,则 value 和您的字符串化属性值不正常。 JS 会设置 ModelState值为 true而您的模型属性的 ToString()值显示为 True .而在 JS 中,"true" !== "True" .

    至于为什么在点击浏览器的“后退”按钮后对我重置 - 我们拥有的陷阱页面没有表单值,并且没有通过 HTTP GET 链接回应用程序,这会导致 HiddenFor调用模型属性的 .ToString()而不是从 ModelState 中拉出来因为在那个时间点它不在那里。同样,在我的测试中,用户会在通过 JS 设置之后很久才处于向导中的某个点,因此当他们继续通过向导时,它会保持大写。

    我的假设是 JS 在页面加载后启动。这实际上是由于 JS 在开始 POST 之前设置了一个值,并且该小写值通过 ModelState 在页面生命周期中持续存在。 .去搞清楚。

    编辑

    复制代码;

    模型;
    public class Test
    {
        public bool Sample { get; set; }
    }
    

    Razor 标记;
    @model TestModelValueCase.Models.Test
    @{
        ViewBag.Title = "Test Page";
    }
    
    @using (Html.BeginForm())
    {
        @Html.HiddenFor(m => m.Sample)
        <div>
            <label>Hidden Value:</label>
            <span id="_uiValue"></span>
        </div>
        <button type="submit">Try Post</button>
    }
    @section scripts
    {
        <script type="text/javascript" language="javascript">
            $(document).ready(function() {
                var source = $('#@nameof(Model.Sample)');
                $('#_uiValue').html(source.val());
                source.val(true);
            });
        </script>
    }
    

    Controller ;
        public ActionResult Index()
        {
            Test model = new Test();
            return View(model);
        }
    
        [HttpPost]
        public ActionResult Index(Test model)
        {
            return View(model);
        }
    

    关于c# - 不同情况下呈现的 bool 字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44720485/

    有关c# - 不同情况下呈现的 bool 字段的更多相关文章

    1. ruby - 默认情况下使选项为 false - 2

      这是在Ruby中设置默认值的常用方法:classQuietByDefaultdefinitialize(opts={})@verbose=opts[:verbose]endend这是一个容易落入的陷阱:classVerboseNoMatterWhatdefinitialize(opts={})@verbose=opts[:verbose]||trueendend正确的做法是:classVerboseByDefaultdefinitialize(opts={})@verbose=opts.include?(:verbose)?opts[:verbose]:trueendend编写Verb

    2. ruby-on-rails - 如何验证非模型(甚至非对象)字段 - 2

      我有一个表单,其中有很多字段取自数组(而不是模型或对象)。我如何验证这些字段的存在?solve_problem_pathdo|f|%>... 最佳答案 创建一个简单的类来包装请求参数并使用ActiveModel::Validations。#definedsomewhere,atthesimplest:require'ostruct'classSolvetrue#youcouldevencheckthesolutionwithavalidatorvalidatedoerrors.add(:base,"WRONG!!!")unlesss

    3. ruby-on-rails - form_for 中不在模型中的自定义字段 - 2

      我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢

    4. ruby - 在没有 sass 引擎的情况下使用 sass 颜色函数 - 2

      我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re

    5. ruby-on-rails - 在 Rails 和 ActiveRecord 中查询时忽略某些字段 - 2

      我知道我可以指定某些字段来使用pluck查询数据库。ids=Item.where('due_at但是我想知道,是否有一种方法可以指定我想避免从数据库查询的某些字段。某种反拔?posts=Post.where(published:true).do_not_lookup(:enormous_field) 最佳答案 Model#attribute_names应该返回列/属性数组。您可以排除其中一些并传递给pluck或select方法。像这样:posts=Post.where(published:true).select(Post.attr

    6. c# - 如何在 ruby​​ 中调用 C# dll? - 2

      如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

    7. C# 到 Ruby sha1 base64 编码 - 2

      我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha

    8. ruby - 在不使用 RVM 的情况下在 Mac 上卸载和升级 Ruby - 2

      我最近决定从我的系统中卸载RVM。在thispage提出的一些论点说服我:实际上,我的决定是,我根本不想担心Ruby的多个版本。我只想使用1.9.2-p290版本而不用担心其他任何事情。但是,当我在我的Mac上运行ruby--version时,它告诉我我的版本是1.8.7。我四处寻找如何简单地从我的Mac上卸载这个Ruby,但奇怪的是我没有找到任何东西。似乎唯一想卸载Ruby的人运行linux,而使用Mac的每个人都推荐RVM。如何从我的Mac上卸载Ruby1.8.7?我想升级到1.9.2-p290版本,并且我希望我的系统上只有一个版本。 最佳答案

    9. 基于C#实现简易绘图工具【100010177】 - 2

      C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

    10. java - 为什么 ruby​​ modulo 与 java/other lang 不同? - 2

      我基本上来自Java背景并且努力理解Ruby中的模运算。(5%3)(-5%3)(5%-3)(-5%-3)Java中的上述操作产生,2个-22个-2但在Ruby中,相同的表达式会产生21个-1-2.Ruby在逻辑上有多擅长这个?模块操作在Ruby中是如何实现的?如果将同一个操作定义为一个web服务,两个服务如何匹配逻辑。 最佳答案 在Java中,模运算的结果与被除数的符号相同。在Ruby中,它与除数的符号相同。remainder()在Ruby中与被除数的符号相同。您可能还想引用modulooperation.

    随机推荐