2009-10-01 4 views
1

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

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

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

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

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

Сообщите мне, если я смогу сделать это более ясным.

Thanks

ответ

3

Это сложно. 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; 
    } 
+0

Да. Я нашел FindAction и начал видеть, что его будет непросто переносить. Я написал часть, которая находит правильный метод, простой, но знаете ли вы, можно ли использовать привязку модели вручную? – Damien

+0

См. Обновленный ответ. –