2013-08-16 14 views
15

Dlaczego programista może używać atrybutu Bind w obiekcie ViewModel w projekcie ASP.NET MVC i czy może to mieć szkodliwy wpływ na aplikację?Używanie atrybutu wiązania w klasie ViewModel w ASP.NET MVC

[Bind(Include = "Id,Name")] 
[MetadataType(typeof (MyViewModelValidation))] 
public class MyViewModel 
{ 
    public string CustomerProductUserName { get; set; } 

    [Display(Name = "Name")] 
    public string Name { get; set; } 

} 

public class MyViewModelValidation 
{ 
    [HiddenInput(DisplayValue = false)] 
    public int Id { get; set; } 

    [Required] 
    public string Name{ get; set; } 
} 

Odpowiedz

18

Przede wszystkim nie trzeba utworzyć klasę MetadataType na ViewModel. Możesz użyć atrybutów adnotacji danych bezpośrednio w swoim ViewModelu. Klasy MetadataType są używane w przypadku modeli automatycznie generowanych przez EF lub inne ORMy, dzięki czemu można korzystać z atrybutów adnotacji danych bez dotykania automatycznie generowanego kodu.

Bind atrybut nie musi być używany - chyba że chcesz używać Include lub Exclude właściwości atrybutu Bind, aby włączyć lub wyłączyć właściwości w modelu lub w wiązaniu, odpowiednio.

Na przykład w kodzie w pytaniu tylko właściwości Id i Name zostaną powiązane podczas przesyłania modelu z widoku. Nawet jeśli masz wpis w widoku dla CustomerProductUserName, po przesłaniu formularza, właściwość zawsze będzie mieć wartość NULL. Może to być przydatne w przypadkach, gdy nie chcesz, aby automatycznie generowane pole identyfikacyjne było dołączone do wiązania.

Właściwości wyłączone z wiązania są również wykluczane z sprawdzania poprawności, ponieważ sprawdzanie poprawności jest wykonywane jako część powiązania modelu. Z powodów bezpieczeństwa możesz również użyć atrybutu Bind; na przykład, gdy chcesz się upewnić, że do kontrolera są wysyłane tylko właściwości w twoim modelu.

+0

Czy te właściwości są również wyłączone z dyskretnego sprawdzania poprawności klienta? – astian

+0

@astian, nigdy tego nie próbowałem, ale najprawdopodobniej tak nie jest. Są one wyłączone z sprawdzania poprawności serwera, ponieważ są wykluczone z powiązania modelu. – ataravati

+0

@ataravati ze względów bezpieczeństwa http://stackoverflow.com/questions/29164776/mvc-security-violation-improperly-controlled-modification-of-dynamically-deter? – Peru

4

Za pomocą atrybutu wiązania można kontrolować, w jaki sposób spoina modelu przekształca żądanie w obiekt o numerze . Najczęstszym sposobem użycia atrybutu Bind jest wyłączenie właściwości wiązania ID. Na przykład tabela bazy danych Osoby zawiera kolumnę o nazwie Id , która jest kolumną Tożsamość. Ponieważ wartość kolumny Tożsamość jest generowana automatycznie przez bazę danych , nie chcesz powiązać pola formularza z tą właściwością.

Z drugiej strony, wyobraź sobie, że własność modelu jest szczególnie wrażliwa, co złośliwy użytkownik może po prostu dołączyć do adresu URL podczas przesyłania formularza. Gdyby to było zrobione, modelowy segregator z radością odkryłby i użyłby wartości danych w procesie wiązania. Dzięki atrybutowi Bind możesz zabezpieczyć swoją aplikację przed tego rodzaju atakiem.

Użycie atrybutu Bindowanie może sprawiać problemy, na przykład gdy będziesz aktualizować obiekt, a identyfikator jest dla Ciebie ważny.

15

Celem stosowania atrybutu wiązania jest zapobieganie przypisywaniu przez atakującego wartości właściwości podczas publikowania żądania lub kontrolowania właściwości, które chcesz powiązać.

Załóżmy, że masz klasę o nazwie Member i metodę create, która zapisuje element. Ale nie chcesz, aby użytkownik wysłał wartość dla właściwości MemberType.

Class Member 
{ 
    public int MemberId { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public string MemberType { get; set; } 
} 

[HttpPost] 
Public ActionResult Create(Member member) 
{ 
    Save(member); 
} 

Załóżmy teraz, jesteś tylko oferując Regularne typ elementu, który jest wartością domyślną. Możesz myśleć, że możesz uniemożliwić użytkownikowi wysłanie wartości właściwości MemberType, nie zezwalając na wprowadzanie danych dla właściwości MemberType.Ale gdy użytkownik opublikuje obiekt członka, atakujący może przechwycić żądanie i wysłać wartość MemberType w żądaniu, jako MemberId=1&FirstName=Chandra&LastName=Malla&MemberType=Premium i zapisać członka jako członka Premium. Aby temu zapobiec, możesz ozdobić klasę Member atrybutem Bind.

[Bind(Include="MemberId,FirstName,LastName")] 
Class Member 
{ 
    ... 

lub

[Bind(Exclude="MemberType")] 
Class Member 
{ 
    ... 

Teraz jeśli Member obiekt zostanie wysłana, typ członkostwa wartość nieruchomości nie zostanie opublikowany.

Jeśli korzystasz z ViewModel, niekoniecznie musisz używać atrybutu bind, ponieważ możesz pominąć właściwości MemberType w swoim ViewModelu.

Class Member 
{ 
    public int MemberId { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public string MemberType { get; set; } 
} 

Class MemberViewModel 
{  
    public int MemberId { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
} 

[HttpPost] 
Public ActionResult Create(MemberViewModel memberviewmodel) 
{ 
    Save(memberviewmodel); 
} 

Jeśli nie ładnie zaprojektować swój model i/lub ViewModel i nie używać atrybut powiązania uniknąć delegowania nieruchomości nie chcesz, które mogą mieć szkodliwy wpływ.

+0

, więc czy korzystanie z powiązania jest obowiązkowe z powodów bezpieczeństwa? odpowiedź http://stackoverflow.com/questions/29164776/mvc-security-violation-improperly-controlled-modyfikation-of-dynamically-deter – Peru

+0

Tak, ale jeśli przechodzisz viewmodel zamiast modelu, możesz dołączyć tylko niezbędne właściwości w viewmodel, więc nie musisz wiązać. –

+0

co to jest viewmodel? model, który przekazuje go do widoku lub ten, który otrzymuję w Post jako parametr? – Peru

Powiązane problemy