Подтвердить что ты не робот

Булевое поле, созданное в разных случаях

Немного странное для тех, у кого есть мысли об этом... Im визуализирует скрытое логическое поле на определенной странице. Тем не менее, я получаю две слегка разные разметки для одного и того же поля в зависимости от того, произошло ли какое-либо событие ранее в процессе. Создаются два поля:

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

и

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

Проблема заключается в том, что текст в атрибуте "значение", который вы считаете, отличается, а затем влияет на условия JS. Разметка бритвы, создающая это:

@Html.Hidden("HasPreviouslyIssuedCard", Model.HasPreviouslyIssuedCard?.ToString(), new { id = nameof(Model.HasPreviouslyIssuedCard) })

Однако Ive также попробовал вариант с использованием следующего с той же разницей в визуализации скрытого поля;

@Html.HiddenFor(m => m.HasPreviouslyIssuedCard)

Какое событие я могу сделать, чтобы получить эту разницу? Чтобы получить вариант верхнего регистра, я нажимаю кнопку "Назад" браузера, прежде чем перейти на соответствующую страницу. Оба метода загружают данные одинаково и одинаково передают одно и то же значение в рендеринг. Два разных выхода.

Имейте в виду, что это булевское поле типа значения, которое визуализируется. Там не должно быть много возможностей для возиться с. Существует множество способов обойти это, но поскольку у нас есть пара элементов, относящихся к логическим полям и обратной кнопке, Id нравится объяснять это, а не работать вокруг него.

Мое лучшее предположение заключается в том, что нажатие кнопки "назад" каким-то образом изменяет состояние рендерера или что другой флаг в модели отличается (имеется 70+ полей, так как это мастер) меняет способ визуализации визуализатора как введите логическое значение. Значение одно и то же, страница одна и та же, данные читаются одинаково.

Основываясь на этой странице (Почему вывод Boolean.ToString "true" и не "true" ?), мы должны гипотетически получить в верхнем регистре все но это не результат.

Любые участники/идеи/мысли?

РЕДАКТИРОВАТЬ 1

Выкапывание через визуализацию MVC в методе HiddenFor(), в конечном итоге вызывается Convert.ToString(value, CultureInfo.CurrentCulture). Я не могу заставить это создавать строчные логические значения при вызове напрямую, но это явно делает. Мой текущий код культуры установлен на en-IE, но при вызове его я вижу заглавные логические значения.

РЕДАКТИРОВАТЬ 2

Я сделал немного больше мастеринга и отслеживания через свое приложение и могу предоставить немного более подробную информацию о том, что происходит, хотя я еще не смог воспроизвести это в более простом приложении.

MVC 5 Приложение: оно имеет:

  • Начальная целевая страница с URL-адресом в корневом домене /, полученном через HTTP GET. Boolean input теги отображаются как True/False
  • Первая страница в мастере по URL /Apply, полученная через HTTP GET. Boolean input теги отображаются как True/False
  • Вторая страница в мастере с тем же URL-адресом после отправки пользователем страницы на шаге 2. Получено через HTTP POST. Пример тегов input теперь отображается как True/False.
  • Нажмите кнопку "Назад" браузера и нажмите страницу ловушки (мы устанавливаем историю браузера, которая всегда попадает на страницу ловушки на "Назад" , когда она играет с адским волшебником).
  • Пользователь нажимает кнопку на странице ловушки, чтобы вернуть их в приложение, где они остановились. Теги input теперь возвращают рендеринг в верхнем регистре (исходная ошибка).

Я вникал в библиотеку MVC, используя ILSpy, чтобы попробовать и проверить, и MVC (если я правильно читаю код) фактически использует реализацию IConverter для записи логического значения, а не Convert.ToString(value, CultureInfo.CurrentCulture) как Я изначально думал.

Стек кода, прослеживаемого от вызова HiddenFor(), (я думаю),

  • System.Web.Mvc.InputExtentions.HiddenFor() (публичная функция)
  • System.Web.Mvc.InputExtentions.HiddenHelper() (частная функция, некоторая логика здесь для массивов, но не применима в нашей ситуации)
  • System.Web.Mvc.InputExtentions.InputHelper() (частная функция, здесь происходит магия)

Декомпилированный код для 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 в передаче. HTML, который генерирует MVC, меняет регистр - и я могу видеть это в Fiddler, в момент, когда JS будет даже загружаться, не стоит запускать. Это не проблема JS.

4b9b3361

Ответ 1

Кажется, я был неправ, это был JS в конце концов, хотя и не в том месте, где я пытался это исключить. Последовательность событий для повторного создания этого;

  • Создать HTML form с булевым скрытым полем + кнопка без отправки
  • В событии onclick для кнопки используйте кусок JS, который устанавливает логическое поле в true (строчный)
  • В вашем действии POST в контроллере отобразите тот же вид

После POST булевское поле будет иметь строчное значение, а не в верхнем регистре.

Что происходит? Ну, HiddenFor() (и его варианты) выдаст логическое значение из ViewData.ModelState, а не логическое значение модели, если оно присутствует в коллекции ModelState. Кажется интуитивным, но что может (и сделал для меня) бросить вас в том, что все другие типы данных, привязка к модели довольно специфичны - значение ModelState и ваши значения свойств модели будут одинаковыми. За исключением случая для логического - модельное связующее достаточно умен, чтобы обрабатывать true и true как одно и то же, но это оставляет значение ModelState и значение вашего строкового значения из-за удара, если оно было задано с помощью буфера JS.

Что касается этого reset для меня после нажатия кнопки "Назад назад" - страница ловушки, которой у нас нет, не имеет значений формы и ссылок обратно в приложение через HTTP GET, что вызывает вызов HiddenFor модели свойство .ToString() вместо того, чтобы вытащить его из ModelState, поскольку он не находится там в этот момент времени. Аналогичным образом, в моих тестах пользователь будет находиться в точке мастера после того, как он будет установлен через JS, поэтому он останется в верхнем регистре, когда они продолжат работу с мастером.

Мое предположение заключалось в том, что JS загружался после загрузки страницы. Фактически это произошло из-за того, что JS установил значение перед тем, как начать POST, и это значение нижнего регистра сохранилось в течение жизненного цикла страницы через ModelState. Наведите указатель мыши.

ИЗМЕНИТЬ

Код для воспроизведения;

Модель;

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

Разметка бритвы;

@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>
}

контроллер;

    public ActionResult Index()
    {
        Test model = new Test();
        return View(model);
    }

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

Ответ 2

Случай логического компиляции с контроллера очень сложный, поскольку большая часть времени интерпретируется как строка .

Это похоже на @Hidden.

Для меня более простой способ добиться этого - создать флажок и установить отображение на "none"

@html.CheckBoxFor(m=> m.HasPreviouslyIssuedCard,  new { style ="display:none"}))

С помощью этого решения у вас будет более типизированная переменная на обоих языках (С# и JavaScript).