Помощь со сложными объектами ModelBinding в .NET

У меня есть специальный привязщик моделей, предназначенный для обработки моего класса accountRequest. Этот класс состоит из некоторых логических значений и UserViewModel.

UserViewModel состоит из таких строк, как имя, фамилия, адрес.

Первоначально я просто передавал UserViewModel в качестве параметра действия, но теперь мне нужно упаковать UserViewModel внутри accountRequest.

однако теперь мой связыватель моделей не будет сопоставлять строки в httpContext.Request с моей UserViewModel внутри AccountRequest. Все логические карты в порядке.

Есть ли простой способ сопоставить его данные со свойствами UserViewModel, кроме жесткого кодирования?

Я пытался это сделать, но мне это не нравится. (упрощенный)

Dim accountRequest As New AccountRequest
Dim user As New UserViewModel

If Not String.IsNullOrEmpty(controllerContext.HttpContext.Request("Firstname")) Then
  user.FirstName = controllerContext.HttpContext.Request("Firstname")
End If

accountRequest.CurrentUser = user
Return accountRequest

Очевидно, что любая помощь приветствуется. Заранее спасибо!


person MFD3000    schedule 08.02.2011    source источник


Ответы (1)


Извините - только что понял, что ваш код был VB, и я ответил на C #

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

Теперь, когда тип модели является членом другого типа, его имя свойства будет использоваться в качестве префикса, и я не верю, что вы можете удалить это требование (можно попробовать Bind(Prefix="") для параметра, но я не не думаю, что это сработает).

Предполагается, что вы не настраиваете привязку каждого свойства и что DefaultModelBinder выполняет некоторые из этих свойств за вас.

Вы должны иметь возможность заставить его работать без изменения кода, изменив строку запроса на ?modelname.property=[value]. Если вы используете форму, вам следует рассмотреть возможность использования метода расширения Html.EditorFor, поскольку он заботится об именовании модели (при условии, что имена ваших членов ViewModel и имена модели ввода согласованы). Но как пример из строки запроса:

public class MyObject{
  public string StringValue { get; set; }
}

public class MyObjectOuter{
  public MyObject Nested { get; set; }
}

public ActionResult Index(MyObjectOuter obj);

Значение obj.Nested.StringProperty может быть заполнено: /Index?Nested.StringValue=hello%20world, потому что префикс obj в любом случае неявный.

Если вам это не нравится, у вас есть несколько вариантов:

1) Измените подпись метода, чтобы она принимала два параметра:

public ActionResult Index(MyObjectOuter outer, MyObject nested)

А потом в теле сразу копируешь nested в свойство obj.Nested. Это немного взломано, но это сработает.

2) Вручную заставьте привязку свойств вашего класса использовать значения без префикса из ValueProviders (но тогда вы ограничиваете тип своей модели только для работы с определенными типами запросов - что не совсем гибко).

3) Или, как я сказал ранее, если эти свойства привязываются из Http Form, используйте Html.EditorFor для генерации разметки - он автоматически генерирует входные данные с правильными именами, если они не меняются от input-> output.

person Andras Zoltan    schedule 08.02.2011