ASP.NET MVC2 Строго типизированный вопрос о привязке к данным - PullRequest
1 голос
/ 26 октября 2010

Я начну с того, что моя терминология может быть отключена, поэтому у меня могут возникнуть проблемы с поиском ответа на этот вопрос и извинением за стену текста.

У меня строго типизированное представление, которое наследуется от пользовательского типа с именем Record. Запись содержит словарь именованных полей различных типов данных - некоторые строки, некоторые целые, некоторые DateTime / TimeSpans.

Через раскрывающийся список onchange в форме я получаю метод HttpPost Action в моем контроллере - насколько я понимаю, модель текущего представления, как предполагается, «передается» в метод контроллера. Похоже, что это происходит, но только частично: поля DateTime и TimeSpan в Записи записываются как значения по умолчанию. Все поля string, int и т. Д. Проходят через нормально.

Я отлаживал код записи во время привязки данных, которая происходит в бэкэнде, когда вызывается метод контроллера HttpPost, и кажется, что создается новая, пустая запись, тогда устанавливаются различные свойства - но если как часть построения «пустая» запись, свойство инициализируется некоторым допустимым ненулевым значением, методы Set этих свойств никогда не вызываются.

Мой вопрос - что на самом деле происходит на этом этапе привязки данных? Это как я описал? Нужно ли инициализировать все свойства моей записи как нули, чтобы они правильно связывались с данными?

Редактировать: Запись (упрощенно)

public class Record
{
    public Record() : base()
    {
        fields.Add("Id", new FieldValue { DataType = typeof(int) });     
        fields.Add("StartDateTime", new FieldValue { DataType = typeof(DateTime) });      
    }

    private Dictionary<string, FieldValue> fields = new Dictionary<string, FieldValue>();

    public Dictionary<string, FieldValue> Fields
    {
        get
        {
            return fields;
        }
    }

    public long? Id
    {
        get
        {
            FieldValue fieldValue = Fields["Id"];
            return fieldValue != null ? (long?)fieldValue.Value : null;
        }
        set 
        {
            SetFieldValue("Id", value);
        }
    }

    public DateTime StartDateTime
    {
        get
        {
            FieldValue fieldValue = Fields["StartDateTime"];
            if (fieldValue == null || fieldValue.Value == null)
            {
                return DateTime.MinValue;
            }
            else
            {
                return (DateTime)fieldValue.Value;
            }

        }
        set
        {
            SetFieldValue("StartDateTime", value);
        }
    }

    protected void SetFieldValue(string fieldName, object value)
    {
        Fields[fieldName] = new FieldValue(value);
    }
}

Класс значений для словаря FieldValues:

public class FieldValue
{
    internal FieldValue(object value)
    {
        DataType = value.GetType();
        Value = value;
    }

    internal FieldValue()
    { }

    public Type DataType { get; set; }  //The data type of the field
    public object Value { get; set; }   //The value of the field
}

Я отображаю строго типизированное представление записи, которое показывает StartTime в форме, но не Id. Когда происходит HttpPost, метод контроллера, который обрабатывает HttpPosts для этого представления, получает запись, которая имеет тот же Id, что и исходная запись, но StartDateTime of DateTime.MinValue.

Edit2: Относится ли способ, которым я отображаю любые поля модели в представлении, к тому, что «увидит» метод контроллера HttpPost модели?

Ответы [ 3 ]

1 голос
/ 27 октября 2010

Оказалось, что это было сочетание нескольких вещей:

Код представления, который я использовал для отображения моего поля StartDateTime, был недостаточно хорошо структурирован, чтобы средство сбора данных по умолчанию могло его забрать.

<input id="StartDateTime" type="text" value="<%= Model.StartDateTime.ToString("g") %>" />

Это не работает. Это также не

<input id="StartDateTime" type="text" value="<%= Model.StartDateTime %>" />

Это работает:

<%= Html.TextBoxFor(model => Model.StartDateTime)%>

Вторая проблема заключается в том, что мое текстовое поле StartDateTime было отключено (атрибут html disabled = "disabled") - оно предназначено только для просмотра, но отключенные поля ничего не возвращают в сообщении (как упоминалось здесь ) так что даже если бы я использовал TextBoxFor HtmlHelper, он все равно не работал бы. Спасибо всем за ссылки, теперь я знаю немного больше о том, каковы важные атрибуты в работе привязки данных.

0 голосов
/ 26 октября 2010

У вас есть поле формы с именем StartDateTime? Связыватель модели по умолчанию сопоставляет идентификаторы полей формы с именами свойств в модели представления. Если у вас нет поля формы с именем StartDateTime, связыватель модели не будет заполнять это свойство.

Если вам нужно отслеживать значение, но не отображать его, вы всегда можете использовать скрытое поле на странице, чтобы вернуть значение.

Кроме того, могут возникнуть проблемы из-за компонентов даты и времени и форматирования, используемого на веб-странице. У Скотта Хансельмана есть запись в блоге , которая может помочь.

0 голосов
/ 26 октября 2010

Вы ищете реализацию IModelBinder ?По умолчанию IModelBinder

Это то, что вы искали?

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