2016-03-23 2 views
3

Я написал переопределение модели Binder.MVC 5 Model Binder Override

public override object BindModel(Controller context, ModelBindingContext bindingContext) 
{ 
    var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); 

    object returnVal = null; 

    if (value == null) 
     returnVal = base.BindModel(controllerContext, bindingContext); 
    else 
    { 
     /* custom logic here that never seems to get called. 
      returnVal = something(); 
     */ 
    } 

    return returnVal; 
} 

У меня также есть яваскрипт служба (в угловом), что делает запрос AJAX для одного из моих контроллеров.

Запрос AJAX пытается опубликовать коллекцию ints. Я пробовал переходить через связующее модель, и кажется, что value всегда имеет значение null. И каким-то волшебством base.BindModel() все еще может привязать мою коллекцию к правильному объекту C#.

Проблема заключается в том, что я не могу использовать свое настраиваемое связующее, поскольку блок else никогда не вызывается. Есть ли другой способ получить значение, кроме использования ValueProvider?

Я также считаю, что до того, как это обычное переплетное устройство работало правильно (из памяти, которая может быть неправильной). Я недавно обновлялся с 4.5 до 5.2.something. Есть ли что-то обновленное, которое могло бы изменить это поведение?

ответ

3

У меня также есть служба javascript (в Angular), которая делает запрос AJAX одному из моих контроллеров.

...

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

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

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

  1. При использовании URL вы будете повторно использовать то же имя свойства в Строка запроса. Пример: ?myArray=1&myArray=2&myArray=3. Это означает, что в вашем модельном переплете вам придется это учитывать.
  2. Если вы используете data (тело) в POST, это может быть фактический объект массива.Пример в формате JSON: {"myArray":[1,2,3,4]}
  3. Вы также можете быть сериализации всю форму и отправить ее на с угловым (который позволит вам лучше использовать связывание функциональность в MVC)

Так лучше ответить на ваш вопрос вам нужно будет предоставить

  1. формата данных, отправляемые из браузера и, как его отправка (строка запроса или в полезной нагрузке данных) (это, вероятно, в вашем угловом заводе, обслуживание, или контроллер)
  2. Определение модели вы пытаетесь привязать к

Подведем итоги: bindingContext.ModelName является ожидаемое имя и должны соответствовать данным, ваша модель связующий пытается найти. Если вы отправляете {"myArray":[1,2,3,4]}, но ваше свойство модели имеет имя ProductIds, оно всегда будет равно null.

Я недавно обновлен от 4,5 до 5.2.something

Нет, не то, что я знаю.


Заключительная мысль. Вы также можете позволить по умолчанию использовать модельное связующее, а затем сделать что-то с возвращаемым значением, если типы совпадают. Если привязка происходит сейчас без проблем, но вы хотите сделать некоторую пост-обработку, это будет лучшим выбором. Пример:

public override object BindModel(Controller context, ModelBindingContext bindingContext) 
{ 
    var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); 

    object returnVal = base.BindModel(controllerContext, bindingContext); 

    /* check returnVal and then additional custom logic here */. 

    return returnVal; 
} 
-1

Пожалуйста, убедитесь, что вы сделали что-то вроде этого: -

  1. Пользовательские модели Переплет: -

    public class HomeCustomDataBinder : DefaultModelBinder 
    { 
        public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
        { 
         if (bindingContext.ModelType == typeof(HomePageModels)) 
         { 
          HttpRequestBase request = controllerContext.HttpContext.Request; 
    
          string title = request.Form.Get("Title"); 
          string day = request.Form.Get("Day"); 
          string month = request.Form.Get("Month"); 
          string year = request.Form.Get("Year"); 
    
          return new HomePageModels 
          { 
           Title = title, 
           Date = day + "/" + month + "/" + year 
          }; 
    
          //// call the default model binder this new binding context 
          //return base.BindModel(controllerContext, newBindingContext); 
         } 
         else 
         { 
          return base.BindModel(controllerContext, bindingContext); 
         } 
        } 
    
    } 
    
  2. После того, как мы закончили кодирования наш пользовательский класс нам нужно будет зарегистрировать класс, который я делаю в Global.asax в Application_Start().

    3) Наконец, нам необходимо сообщить контроллеру о привязке, которую мы хотим использовать. Это можно указать с помощью атрибутов [ModelBinder(typeof(HomeCustomBinder))], как показано ниже:

    [HttpPost] 
    public ActionResult Index([ModelBinder(typeof(HomeCustomBinder))] HomePageModels home) 
    { 
        if (ModelState.IsValid) 
        { 
         ViewBag.Title = home.Title; 
         ViewBag.Date = home.Date; 
        } 
        return View(); 
    } 
    
Смежные вопросы