2011-11-23 22 views
7

Próbuję obejść fakt, że kiedy napisał asp.net MVC 3, zapomnieli dołączyć kod, aby dodać dyskretne atrybuty sprawdzania poprawności do wybierania list i ich "fix", ponieważ ma to obejmować to w MVC 4, który nie jest żadnym krwawym użytkiem dla kogokolwiek używającego MVC 3.Jak korzystać z Html.GetUnobtrusiveValidationAttributes()

Proponowana praca polega na użyciu Html.GetUnobtrusiveValidationAttributes(), aby dodać je samodzielnie, tak jak wszystkie inne niestandardowe atrybuty, ale nie mogę wyliczyć poprawnej składni do wywoływania metody. Występują 2 przeciążenia, jeden bierze ciąg, a drugi przyjmuje ciąg i klasę ModelMetaData. Rozumiem paradę metadanych, domyślam się, że po prostu przekazuję ViewData.ModelMetadata, ale jaki powinien być łańcuch? Dokumentacja MSDN mówi, że jest to "określony atrybut nazwy HTML", który nie ma dla mnie żadnego sensu. Jaki jest atrybut nazwy HTML? Lista wyboru? Dlaczego miałoby to być potrzebne i jak to pomóc, aby wiedział, jakie właściwości w moim modelu chcę zatwierdzić? Patrząc na przykłady użycia, wszystkie wydają się przekazywać nazwę właściwości w moim modelu, dla której chcę atrybuty sprawdzania poprawności, co ma sens. Niestety nie mogę uzyskać metody zwracania niczego poza pustą kolekcją, niezależnie od tego, co przekazuję.

Moja klasa modelu nosi nazwę zdarzenia, a moja właściwość nosi nazwę EventTypeID. Używam nieco innej klasy viewmodel jako podstawy dla widoku, ponieważ potrzebuję wyświetlić listę zdarzeń, a także pozwolić na wpisanie nowego zdarzenia w tym samym widoku, więc mam prostą klasę viewmodel jak poniżej:

public class EventViewModel 
{ 
    public Model.Event NewEvent { get; set; } 
    public IEnumerable<Model.Event> Events { get; set; } 
} 

Lista rozwijana jest mapowana do usługi, na przykład: @Html.DropDownListFor(model => model.NewEvent.EventTypeID co przekazuję jako ciąg do Html.GetUnobtrusiveValidationAttributes(string) lub Html.GetUnobtrusiveValidationAttributes(string, ModelMetadata), aby uzyskać atrybuty dla tej właściwości. Próbowałem:

Html.GetUnobtrusiveValidationAttributes("EventTypeID") 
Html.GetUnobtrusiveValidationAttributes("EventTypeID",ViewData.ModelMetadata) 
Html.GetUnobtrusiveValidationAttributes("NewEvent.EventTypeID") 
Html.GetUnobtrusiveValidationAttributes("NewEvent.EventTypeID",ModelMetadata) 

Wszystkie zwracają pustą kolekcję.

Wiem, że mój model jest poprawny, ponieważ jeśli zmieniam wywołanie z Html.DropDownListFor na Html.TextBoxFor, sprawdzanie poprawności "po prostu działa" bez konieczności wykonywania innych czynności niż dodawanie atrybutów sprawdzania poprawności do mojej klasy modelu.

EDIT:

właśnie próbował włączeniu walidacji po stronie klienta off, walidacja działa poprawnie po stronie serwera dla wszystkich listach wyboru.

Odpowiedz

0

Tu jest link do odpowiedzi napisałem, wykazujące HtmlHelper napisałem zapewnić dyskretne walidacji dla dropdownlists: MVC 3 dropdownlist validation not working for complex view model

UPDATE

Czy próbujesz uzyskać atrybuty w HtmlHelper, lub w linii w twoim widoku?

Zakładając, że próbujesz uzyskać atrybuty w swoim widoku, to jest problem.

Najpierw należy zrozumieć, że ModelMetadata nie reprezentuje pojedynczego obiektu dostępnego w całym modelu. Raczej reprezentuje metadane dla konkretnego elementu, czy to twojego modelu, czy dowolnej właściwości w modelu. Lepszą opisową nazwą będzie ObjectMetadata, ponieważ ModelMetadata jest metadane dla określonego obiektu, czy to model, model zagnieżdżony czy określona właściwość.

ModelMetadata w widoku to tylko metadane modelu najwyższego poziomu. Musisz pobrać modelMetadata dla właściwości, do której jest przypisana lista rozwijana.Jeśli korzystasz z helpera, pomocnik otrzymuje oczywiście poprawne ModelMetadata. Jeśli używasz widoku, trzeba zaangażować się w niektórych gimnastyki, aby uzyskać prawidłową ModelMetadata, patrz na przykład moja odpowiedź tutaj: Validating and editing a “Changeable”/optional type in Asp.net MVC 3

+1

widziałem, że już wcześniej napisałem, nie jestem pewien, że w pełni zrozumieć kod, więc mam przechowywaną z korzystania z niej. Czy mógłbyś wyjaśnić mi, co robię źle, jak na moje pytanie i wyjaśnić, co powinienem przechodzić do GetUnobtrusiveValidationAttributes(), aby uzyskać atrybuty dla mojego modelu? –

13

Dla tych, wciąż szuka odpowiedzi, to działa na mnie:

public static IDictionary<string, object> UnobtrusiveValidationAttributesFor<TModel, TProperty>(this HtmlHelper<TModel> html, Expression<Func<TModel, TProperty>> propertyExpression) 
{ 
    var propertyName = html.NameFor(propertyExpression).ToString(); 
    var metadata = ModelMetadata.FromLambdaExpression(propertyExpression, html.ViewData); 
    var attributes = html.GetUnobtrusiveValidationAttributes(propertyName, metadata); 
    return attributes; 
} 

Zauważ, że używam MVC 4, nie ma sposobu html.NameFor w MVC 3. Uważam jednak, można to zrobić w MVC 3 z następującym sposobem:

var propertyName = ExpressionHelper.GetExpressionText(propertyExpression); 
3

ty można go użyć w linii

Przykład elementu select

<select name="@Html.NameFor(m=> m.MyProperty)" 
     id="@Html.IdFor(m=> m.MyProperty)" 
     @Html.Raw(string.Join(" ", Html.GetUnobtrusiveValidationAttributes(Html.NameFor(m => m.MyProperty).ToString()).Select(x => x.Key.ToString() + "=\"" + x.Value + "\""))) 
>