MVC WebGrid - как вызвать метод для элемента / модели WebGridRow?

При использовании WebGrids я обнаружил, что могу получить доступ к свойствам модели, привязанной к WebGrid, но не могу получить доступ к методам самой модели.

Например, это работает:

// Accessing a property of item works
reportGrid.Column("", header: "First Name", format: item => item.firstName )

Но это не работает: (я показываю тривиальный пример, но в моем случае я должен вызвать метод самого объекта User.)

// Accessing a method on item does not work 
reportGrid.Column("", header: "First Name Backwards", format: item => item.firstNameBackwards() )

=> error: 'System.Web.Helpers.WebGridRow' does not contain a definition for 'getFullName'

Похоже, это связано со следующим:

Почему нельзя Я использую свой метод расширения в делегате в Razor WebGrid http://www.mikesdotnetting.com/Article/171/Why-You-Can%27t-Use-Extension-Methods-With-A-WebGrid

Я не вижу способа применить эти решения к моей проблеме. Как утверждает Майк Бринд:

Аргумент, который принимает параметр Format WebGridColumn, является делегатом: Func. Это означает, что вам нужно передать динамический тип, а затем с ним что-то делают, прежде чем он будет возвращен как объект.

...

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

Похоже, мой метод должен быть найден, но, возможно, не потому, что модель, привязанная к WebGrid, на самом деле является моделью подкачки, которая содержит IList<T> LineItems, которые содержат мои ссылки на пользователя.

Есть ли способ преобразовать или получить ссылку на сам объект User, чтобы я мог вызывать определенные для него методы в дополнение к доступу к его свойствам?


person gooberverse    schedule 04.04.2014    source источник


Ответы (3)


Я нашел способ обойти эту проблему, но все же надеюсь, что есть способ лучше. Буду признателен за любые отзывы об этом или альтернативных решениях.

Изучая эту проблему и изучая некоторые другие мои коды WebGrid, я обнаружил, что могу получить доступ к методам 2-го порядка, определенным для объектов, к которым можно получить доступ через свойства объекта модели, привязанного к WebGrid.

Пример (упрощенный):

reportGrid.Column("", header: "First Name Backwards", 
  format: item => item.BestFriend.firstNameBackwards() )
=> Works!

Сделав еще один шаг, я проследил двунаправленную связь до исходного объекта, чтобы я мог вызвать его методы:

// Assume all best-friend relationships are reciprocal 
reportGrid.Column("", header: "First Name Backwards", 
  format: item => item.BestFriend.BestFriend.firstNameBackwards() )

=> Works!

Имея это в виду, я изменил свою модель User, чтобы она содержала ссылку на себя:

    public User() {
        this._self = this; // Initialize User object with a reference to itself
    }

    [NotMapped]
    public User _self { get; set; }

Решение - теперь я могу вызывать методы, определенные для модели User, используя свойство _self.

reportGrid.Column("", header: "", 
  format: item => Helper.userTML(item._self.firstNameBackwards() ) )

=> Works!
person gooberverse    schedule 04.04.2014

Изучая эту проблему и изучая некоторые другие мои коды WebGrid, я обнаружил, что могу получить доступ к методам 2-го порядка, определенным для объектов, к которым можно получить доступ через свойства объекта модели, привязанного к WebGrid.

У меня была такая же проблема, и в соответствии с этим комментарием я понял, что это произошло из-за того, что я не раскрыл элементы данных модели. Установите для своего определения firstName значение public, и это исправит его.

person Zakk Diaz    schedule 26.01.2016

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

В вашем классе модели (Пользователь?):

public string firstNameBackwards
{
    get 
    { 
        var firstNameBackwards = firstName;
        // Do something here
        return firstNameBackwards; 
    }
}

В вашей сетке:

reportGrid.Column("", header: "First Name Backwards", format: item => item.firstNameBackwards )
person user3452805    schedule 08.04.2016