/ / Dlaczego mój segregator modeli nie znajduje typów w klasie? - c #, asp.net-mvc, asp.net-mvc-3, wiązanie modelu

Dlaczego mój segregator nie znajduje typów w klasie? - c #, asp.net-mvc, asp.net-mvc-3, wiążący model

Mam następujące klasy:

public class Truck {
public Wheel Wheel { get; set; }
}

public class Wheel {
public int Number { get; set; }
}

I zarejestrowałem następujący model spoiwa:

ModelBinders.Binders.Add(typeof(Wheel), new WheelModelBinder());

I:

public class WheelModelBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
throw new NotImplementedException();
}
}

Jeśli przekażę:

public ActionResult(Wheel wheel) { ... }

Spoiwo modelu zostaje trafione i generuje wyjątek. Jeśli przejdę

public ActionResult(Truck Truck) { ... }

Spoiwo modelowe nie zostaje trafione.

W mojej aplikacji za każdym razem, gdy Wheel się włącza(niezależnie od tego, czy jest zagnieżdżony w innym typie), chcę, aby segregator modelu podniósł go i manipulował właściwościami na kole. Jaki jest najlepszy sposób na osiągnięcie tego?

Edytować: Korzystanie z EditorFor () wiąże mnie poprawnie, ale nie mogę dowolnie edytować właściwości. W powyższym przykładzie:

public class WheelModelBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var valueProviderResult = bindingContext.ValueProvider.GetValue("Wheel.Number");
return null;
}
}

Spowoduje to poprawne uzyskanie właściwości koła. Mogę jednak mieć nowy, bardziej złożony obiekt:

public class Cars {
public class Truck { get; set; }
}

To łamie ValueProvider i będę musiał zrobić ... GetValue("Truck.Wheel.Number") Czy nadużywam ModelBinder? Czy istnieje lepszy sposób na osiągnięcie mojego wyniku (załóżmy, że moim wynikiem jest wykonanie zewnętrznego wyszukiwania, aby upewnić się, że właściwość Number jest poprawny, a jeśli nie, ustaw go na coś innego).

Odpowiedzi:

1 dla odpowiedzi № 1

W rzeczywistości Twój ModelBinder i model będą działać zgodnie z definicją.

Elementem wyzwalającym cię jest widok. Jeśli użyjesz:

@model MyApplication5.Models.Truck
@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>Truck</h2>

@using (Html.BeginForm())
{
@Html.EditorFor(m => m.Wheel)
<button type="submit">Submit</button>
}

widok wygeneruje poprawnie nazwane elementy, które zostaną wykorzystane przez niestandardowy ModelBinder.

Jednak w tym scenariuszu nie potrzebujeszniestandardowy ModelBinder, ponieważ DefaultModelBinder będzie obsługiwał twój model zagnieżdżony, o ile przestrzegane będą konwencje MVC. Zasadniczo niestandardowe ModelBinder jest dla (1) złożonego typu niestandardowego lub modelu, którego DefaultModelBinder nie może wykorzystać, lub (2) w przypadku gdy używają niestandardowej konwencji nazewnictwa.


2 dla odpowiedzi nr 2

Po prostu użyj nazwy modelu:

var valueProviderResult = bindingContext
.ValueProvider
.GetValue(bindingContext.ModelName + ".Number");

Teraz bez względu na to, jak głęboki jest wykres obiektu, segregator modelu będzie działał poprawnie.


0 dla odpowiedzi № 3

Wygląda na to, że nie masz nawet ciężarówkiobiekt do wiązania (może to jednak nie być problem), a ja zbieram twój widok, nie wypisuję go również w odpowiednim formacie. Aby powiązać kolekcje, musisz dopasować określony format nazewnictwa opisany na blogu Phila Haacksa

http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx

Czy twoje elementy pasują do tej konwencji nazewnictwa?