Сбой проверки на стороне клиента для DropDownList в поле int, браузер IE - PullRequest
3 голосов
/ 03 апреля 2012

Win 7 Ult, IE9. Следующий список передается DropDownList в представлении через пакет представления.

List<int> test1ddl = new List<int> { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

В течение нескольких дней он работал нормально, а затем неожиданно начал сбой проверки на стороне клиента с сообщением «Поле Test1 должно быть числом» при публикации (оно никогда не достигает действия POST). Это терпит неудачу, когда я передаю Список или Список. Если я заменяю DropDownList на Editor, то POST работает и поле обновляется.

Единственное, что я сделал на компьютере, это переустановил IIS, это происходит при отладке с использованием IIS Express.

Когда я восстановил резервную копию на компьютере, проблема ушла. Впоследствии я развернул приложение в Интернете, используя эту настройку DropDownList, и оно перестало работать с ошибкой «должен быть номер» в IE 8 на XP. Chrome и FireFox работают нормально. Он также отлично работает с IE9 на Win7.

Я также обнаружил, что мне даже не нужно нажимать кнопку Сохранить, просто щелкнув мышью из окна браузера, чтобы вывести его из фокуса, после выбора DropDownList выдается ошибка проверки. Это происходит как со строкой, так и с int List. Это также происходит с IE8 на XP с развернутым веб-приложением.

Я восстановил резервную копию сбойной конфигурации Win7, а затем снова произошел сбой при отладке с использованием IE9 в IIS Express. Если я открою развернутый сайт с IE9 в этой конфигурации, он будет работать нормально. (Я не могу тестировать Chrome с IIS Express, потому что в сбойной конфигурации VS2010 не будет использовать браузер по умолчанию, только IE. Это отдельный вопрос, если у кого-то есть представление о том, почему это происходит).

На данный момент я не думаю, что с текущим кодом что-то не так, но, похоже, это проблема браузера. Поскольку XP и IE8 все еще очень распространены, мне нужно, чтобы это работало.

Мой вопрос: почему некоторые браузеры генерируют ошибку проверки?

Спасибо, Джо

Если вы создадите новое веб-приложение MVC3 и добавите эти файлы, вы можете заново создать мое приложение ddlTestDB.

Add this to the _Layout.cshtml menu.         <li>@Html.ActionLink("Test", "Index", "Test")</li>

*************** Controller     TestController.cs    **********
using System.Collections.Generic;
using System.Web.Mvc;
using ddltest.Models;
using ddltest.Infrastructure;

namespace ddltest.Controllers
{
  public class TestController : Controller
  {
    ddlTestDb _db = new ddlTestDb();

    public ActionResult Index()
    {
      var model = _db.Tests;
      return View(model);
    }

    public ActionResult Edit(int id)
    {
      var test = _db.Tests.FindById(id);
      //List<string> test1ddl = new List<string> { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
      List<int> test1ddl = new List<int> { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
      ViewBag._Test1 = test1ddl;
      return View(test);
    }

    [HttpPost]
    public ActionResult Edit(int id, FormCollection collection)
    {
      var test = _db.Tests.FindById(id);

      if (TryUpdateModel(test)) { return RedirectToAction("Index"); }

      return View(test);
    }
  }
}

********************** Class          Test.cs **************
namespace ddltest.Models
{   public class Test   {   public int Id { get; set; }     public int Test1 { get; set; }  }  }

********************** Static data  ddlTestDb.cs *****************
using System.Collections.Generic;

namespace ddltest.Models
{
  public class ddlTestDb
  {
    static ddlTestDb()
    {
        _tests = new List<Test>();
        _tests.Add(new Test { Id = 1, Test1 = 0 });
        _tests.Add(new Test { Id = 2, Test1 = 1 });
        _tests.Add(new Test { Id = 3, Test1 = 2 });
        _tests.Add(new Test { Id = 4, Test1 = 1 });
    }

    public IList<Test> Tests { get { return _tests; } }

    static List<Test> _tests;
  }
}

*********************  Extensions.cs ************
using System.Collections.Generic;
using System.Linq;
using ddltest.Models;

namespace ddltest.Infrastructure
{
  public static class TestExtensions
  {
    public static Test FindById(this IList<Test> tests, int id)
    {
      return tests.Single(t => t.Id == id);
    }
  }
}

******************  Views\Test\Edit.cshtml ****************
@model ddltest.Models.Test

@{
    ViewBag.Title = "Edit";
}

<h2>Edit</h2>

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>

@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>Test</legend>

        @Html.HiddenFor(model => model.Id)

        <div class="editor-label">
            @Html.LabelFor(model => model.Test1)
        </div>
        <div class="editor-field">
            @Html.DropDownList("Test1", new SelectList(ViewBag._Test1))
            @*@Html.EditorFor(model => model.Test1)*@
            @Html.ValidationMessageFor(model => model.Test1)
        </div>

        <p>
            <input type="submit" value="Save" />
        </p>
    </fieldset>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

***************Views\Test\ Index.cshtml ************
@model IEnumerable<ddltest.Models.Test>

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

<p>
    @Html.ActionLink("Create New", "Create")
</p>
<table>
    <tr>
         <th>
            Id
        </th>
        <th>
            Test1
        </th>
        <th></th>
    </tr>

@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.Id)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Test1)
        </td>
        <td>
            @Html.ActionLink("Edit", "Edit", new { id=item.Id }) |
            @Html.ActionLink("Details", "Details", new { id=item.Id }) |
            @Html.ActionLink("Delete", "Delete", new { id=item.Id })
        </td>
    </tr>
}
</table>

1 Ответ

10 голосов
/ 03 апреля 2012

Ваши <option> элементы не имеют значений. Посмотри на них:

<select id="Test1" name="Test1">
    <option>0</option>
    <option>1</option>
    <option>2</option>
    <option>3</option>
    <option>4</option>
    <option>5</option>
    <option>6</option>
    <option>7</option>
    <option>8</option>
    <option>9</option>
</select>

Видишь проблему? Ни у одного из них нет атрибута значения, поэтому на сервере ничего не публикуется, и когда вы пытаетесь ничего не связать с целым числом, вы получаете то, что получаете: сообщение об ошибке.

Итак:

List<int> test1ddl = new List<int> { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
ViewBag._Test1 = test1ddl.Select(x => new SelectListItem
{
    Value = x.ToString(),
    Text = x.ToString()
});

, а затем:

@Html.DropDownList("Test1", (IEnumerable<SelectListItem>)ViewBag._Test1)

Посмотрите сейчас:

<select id="Test1" name="Test1">
    <option value="0">0</option>
    <option value="1">1</option>
    <option value="2">2</option>
    <option value="3">3</option>
    <option value="4">4</option>
    <option value="5">5</option>
    <option value="6">6</option>
    <option value="7">7</option>
    <option value="8">8</option>
    <option value="9">9</option>
</select>

Намного лучше. Ох, и, пожалуйста, не используйте ViewBag. Используйте модели представления и строго типизированные версии помощников, такие как Html.DropDownListFor.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...