MVC2 и две разные модели, использующие один и тот же метод контроллера?Возможный? - PullRequest
1 голос
/ 26 января 2011

Я не знаю, правильно ли это делать, но я использую Jquery и MVC2.Я использую метод $ .ajax для обратного вызова контроллера для выполнения бизнес-логики над .blur текстового поля.

У меня есть два представления, которые в основном делают то же самое с общими данными, но используют разные модели.Они оба используют один и тот же контроллер.Это может быть проще объяснить с помощью кода:

Итак, вот две модели:

public class RecordModel {
    public string RecordID { get; set; }
    public string OtherProperties { get; set; }
}

public class SecondaryModel {
    public string RecordID { get; set; }
    public string OtherPropertiesDifferentThanOtherModel { get; set; }
}

Есть два представления, которые строго типизированы для этих моделей.Один из них - RecordModel, другой - SecondaryModel.

Теперь в этих представлениях есть input = "text", который создается с помощью:

<%= Html.TextBoxFor(model => model.RecordID) %>

Существует jQuery javascript, который связывает метод .blurвызов:

<script>
    $('#RecordID').blur(function() {
        var data = new Object();
        data.RecordID = $('#RecordID').val();
        // Any other stuff needed

        $.ajax({
            url: '/Controller/ValidateRecordID',
            type: 'post',
            dataType: 'json',
            data: data,
            success: function(result) {
                 alert('success: ' + result);
            },
            error: function(result) {
                 alert('failed');
            }
         });
      }
 </script>

Контроллер выглядит следующим образом:

[HttpPost]
public ActionResult ValidateRecordID(RecordModel model) {
    // TODO: Do some verification code here

    return this.Json("Validated.");
}

Теперь это работает нормально, если я явно назову RecordModel в контроллере для представления, использующего RecordModel.Тем не менее, представление SecondaryModel также пытается вызвать эту функцию, и происходит сбой, потому что он ожидает RecordModel, а не SecondaryModel.

Так что мой вопрос таков.Как два разных строго типизированных представления могут использовать одно и то же действие в контроллере и при этом придерживаться шаблона моделирования?Я попробовал абстрактные классы и интерфейсы (и изменил страницы представления для использования интерфейса / абстрактного класса), и он все еще не работает.

Любая помощь?И извините за надежность сообщения ...

Спасибо.

Ответы [ 4 ]

1 голос
/ 26 января 2011

Вы можете определить интерфейс для этих классов.

interface IRecord
{
    string RecordID { get; set; }
    string OtherProperties { get; set; }
}

и заставить метод получать модель, используя это:

[HttpPost]
public ActionResult ValidateRecordID(IRecord model) 
{
    // TODO: Do some verification code here

    return this.Json("Validated.");
}
0 голосов
/ 26 января 2011

В приведенном выше случае ваши действия могут принимать две строки вместо конкретного типа.

Еще одна возможность - два действия. Каждое действие принимает один из ваших типов. Я предполагаю, что функциональность каждого типа в основном одинакова. Как только значения были извлечены, передайте их методу. В вашем случае метод, вероятно, будет одинаковым для каждого действия.

public ActionResult Method1(Record record)
{
ProcessAction(record.id, record.Property);

}

public ActionResult Action2(OtherRecord record)
{

ProcessAction(record.id, record.OtherProperty);

}


private void ProcessAction(string id, string otherproperity)
{
//make happen
}
0 голосов
/ 26 января 2011

Если вам нужен только RecordID, вы можете просто заставить метод контроллера взять int RecordID, и он извлечет его из данных публикации формы, вместо того, чтобы создать резервную копию модели представления и предоставить это вашему методу действия.

[HttpPost]
public ActionResult ValidateRecordID(int RecordID) {
    // TODO: Do some verification code here

    return this.Json("Validated.");
}
0 голосов
/ 26 января 2011

Не существует прямого способа привязки данных к интерфейсу / абстрактному классу.DefaultModelBinder попытается создать экземпляр этого типа, который (по определению) невозможен.

Так что, IMHO, вы не должны использовать эту опцию.И если вы все еще хотите разделить одно и то же действие контроллера между двумя представлениями, обычный способ сделать это - использовать ViewModel .

Сделайте так, чтобы ваши строго типизированные представления ссылались на эту модель представления.Сделайте так, чтобы одно общее действие получило его экземпляр.Внутри действия вы решите, какую «реальную» модель следует использовать ...

Если вам нужен какой-то параметр, чтобы отличить, откуда пришло сообщение (вид 1 или 2), просто добавьте этот параметр вURL-адрес вызова ajax.

Конечно, другой способ - сохранить то, что вы уже попробовали (интерфейс / абстрактный класс), но в этом случае вам понадобится пользовательский связыватель модели .Звучит как перекодировка, но это твой выбор.

Edit После того, как мой дорогой ТАК @Charles Boyung сделал милостивый (и неправильный) комментарий ниже, я пришел к выводучто мой ответ был не совсем точным.Поэтому я исправил некоторую терминологию, которую использовал здесь - надеюсь, теперь она понятнее.

...