MVC Получить модель по каждому запросу - PullRequest
0 голосов
/ 16 сентября 2008

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

http://helpdesk/HR/Members
http://helpdesk/HR/Members/PeterParker
http://helpdesk/HR/Categories
http://helpdesk/Finance/Members
http://helpdesk/Finance/Members/BruceWayne
http://helpdesk/Finance/Categories

Проблема заключается в том, что в каждом действии по каждому запросу мне нужно принять этот параметр, а затем извлечь модель отдела поддержки из хранилища на основе этого ключа. Из этой модели я могу получить список участников, категорий и т. Д., Который отличается для каждого отдела технической поддержки. Это явно нарушает СУХОЙ.

У меня вопрос, как я могу создать базовый контроллер, который делает это для меня, чтобы определенный отдел службы поддержки, указанный в URL, был доступен для всех производных контроллеров, и я мог просто сосредоточиться на действиях?

Ответы [ 3 ]

2 голосов
/ 17 сентября 2008

У меня похожий сценарий в одном из моих проектов, и я склонен использовать ModelBinder, а не отдельную иерархию наследования. Вы можете создать атрибут ModelBinder для выборки объекта / объектов из RouteData:

public class HelpdeskDepartmentBinder : CustomModelBinderAttribute, IModelBinder {

    public override IModelBinder GetBinder() {
        return this;
    }

    public object GetValue(ControllerContext controllerContext, string modelName, Type modelType, ModelStateDictionary modelState) {
        //... extract appropriate value from RouteData and fetch corresponding entity from database. 
    }
}

... тогда вы можете использовать его, чтобы сделать HelpdeskDepartment доступным для всех ваших действий:

public class MyController : Controller {
    public ActionResult Index([HelpdeskDepartmentBinder] HelpdeskDepartment department) {
        return View();
    }
}
0 голосов
/ 16 сентября 2008

Вы можете создать базовый класс контроллера через обычное наследование C #:

public abstract class BaseController : Controller 
{
}

public class DerivedController : BaseController 
{
}

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

Технически это работает нормально. Однако существует некоторый риск с точки зрения дизайна. Если, как вы говорите, всем вашим контролерам потребуется отдел, это нормально. Если только некоторые из них будут нуждаться в отделе, это все еще может быть хорошо. Но если для некоторых контроллеров требуется отдел, а для других контроллеров требуется другое наследуемое поведение, и оба подмножества пересекаются, то вы можете столкнуться с проблемой множественного наследования. Это предполагает, что наследование не будет лучшим решением для решения вашей заявленной проблемы.

0 голосов
/ 16 сентября 2008

Отказ от ответственности: в настоящее время я использую MVC Preview 5, поэтому некоторые из них могут быть новыми.

Метод наилучшей практики: просто реализуйте статический служебный класс, который предоставляет метод, который выполняет поиск модели, принимая RouteData из действия в качестве параметра. Затем вызовите этот метод из всех действий, для которых требуется модель.

Глупый способ, если только для каждого отдельного действия в каждом контроллере нужна модель, и вы действительно не хотите, чтобы в ваших действиях был дополнительный вызов метода: в вашем базовом классе-контроллере переопределите ExecuteCore (), используйте RouteData для заполнения модели, затем вызовите base.ExecuteCore ().

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