Как MVC вызывает действие и сопоставляет Request.Form с его параметрами - PullRequest
1 голос
/ 01 октября 2009

Мне нужно создать что-то похожее на то, как MVC вызывает метод (Action), а также использует связыватель модели для сопоставления NamedValueCollection с параметрами этого метода. По сути, у меня есть действие Controller, которое должно динамически вызывать метод класса, в контроллере есть любая информация, отправляемая в форме или строке запроса, а также имя метода для вызова в виде строки.

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

Я скачал ASP.Net MVC 1.0 Source, но есть куча классов, у меня проблемы с поиском кода, который это обрабатывает.

Я знаю, как вызвать метод, имя которого содержится в строке, но, возможно, есть лучший способ, который использует MVC. Мне также нужно знать, как использовать связыватели моделей, чтобы сделать Request.Form + Query Strings для параметров этого метода.

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

Дайте мне знать, если я смогу прояснить это.

Спасибо

1 Ответ

3 голосов
/ 01 октября 2009

Это сложно. FindAction вызывается для ControllerActionInvoker. Это в конечном итоге вызывает ReflectedControllerDescriptor.FindAction, который, в свою очередь, вызывает ActionMethodSelector.FindActionMethod, который вызывает RunSelectionFilters для того же типа. Этот метод берет список методов, переданных ему воротником, и повторяет их, изучая аргументы каждого метода и сравнивая их со значениями в запросе. Поскольку это должно выполняться быстро при поступлении запроса, все это кэшируется, и поскольку он предназначен для расширения, между уровнями, которые я описал, есть несколько абстрактных типов. Следовательно, поначалу может быть немного трудно следовать, и, вероятно, было бы трудно повторно использовать его для логики, не связанной с контроллером. Тем не менее, вы можете использовать его в качестве модели для реализации своей собственной системы. Я думаю, что это слишком сложно для доменного приложения. Число точек расширения, вероятно, подходит для инфраструктуры MVC, но для вашего собственного кода YAGNI.

Я надеюсь, что этого достаточно для начала.

Что касается использования связывателя модели без веб-стека: ну, вам все еще нужен MVC, но не обязательно веб-сервер. Вот как мы это делаем в модульном тесте:

    internal static T Bind<T>(string prefix, FormCollection collection, ModelStateDictionary modelState) where T:BaseTimeRecordPresentationModel
    {
        var mbc = new ModelBindingContext()
        {
            ModelName = prefix,
            ModelState = modelState,
            ModelType = typeof(T),
            ValueProvider = collection.ToValueProvider()
        };
        IModelBinder binder = new TimeRecordModelBinder();
        var cc = new ControllerContext();

        return binder.BindModel(cc, mbc) as T;
    }

    internal static T BindAndAssertValid<T>(string prefix, FormCollection collection) where T:BaseTimeRecordPresentationModel
    {
        var msd = new ModelStateDictionary();
        var result = Bind<T>(prefix, collection, msd);
        if (!msd.IsValid)
        {
            Assert.Fail(ModelStateValidationSummary(msd));
        }
        return result;
    }
...