2009-11-22 8 views
5

VS 2010 beta 2, .NET 4.błąd Entity Framework podczas składania pustych pól

W mojej aplikacji ASP.NET MVC 2, kiedy złożyć formularz do sposobu działania, który akceptuje obiekt utworzony przez Entity Framework , pojawia się następujący błąd:

Exception Details: System.Data.ConstraintException: This property cannot be set to a 
null value. 

Source Error: 


Line 4500:    OnTextChanging(value); 
Line 4501:    ReportPropertyChanging("Text"); 
Line 4502:    _Text = StructuralObject.SetValidValue(value, false); 
Line 4503:    ReportPropertyChanged("Text"); 
Line 4504:    OnTextChanged(); 

Obiekt nazywany jest "Tekst" i jest typu "text NOT NULL" w MS SQL 2008.

Moje działania będą sprawdzać, czy wartość jest nullorempty, jeśli to jest, błąd modelu zostanie dodany, ale dostaję błąd zaraz po przesłaniu formularza.

+0

Może to nie jest bezpośrednio związane z pytaniem, ale typ danych TEKST jest przestarzały. Masz NVARCHAR (MAX) od SQL Server 2005. W wielu sytuacjach jest znacznie łatwiejszy w użyciu. – LukLed

+0

Dzięki, zmieniłem pola na nvarchar (i zaktualizowałem model bazy danych za pomocą kreatora aktualizacji encji jednostki), ale problem nadal istnieje. – Omar

Odpowiedz

8

Czy wiążesz bezpośrednio podmiot? Pewnie tak wygląda. Masz więc dwie możliwości:

  1. Napisz niestandardowy segregator, który tłumaczy pusty łańcuch - null.
  2. Powiąż model edytowania, który pozwala zamiast tego na wartości zerowe, a następnie zmień wartość na pusty ciąg podczas kopiowania wartości do obiektu w akcji.

Wybrałbym 2, osobiście. Myślę, że zawsze powinieneś używać modeli przeglądania/edycji, co jest doskonałym przykładem tego.

2

Czy to jest problem z MVC2 i Entity Framework 4, czy jest to zgodne z projektem? Wygląda na to, że sprawdzanie poprawności właściwości EF działa dobrze dla terminowych pól nienapełnianych (wymaganych), a sprawdzanie typu danych dla pól liczbowych i łańcuchowych działa bez użycia ViewModels.

Odtworzyłem ten problem, używając prostej tabeli FOOBAR, używając pojedynczej, nieakceptowalnej kolumny varchar (50) o nazwie barName w slq 2008. Wygenerowałem model EF z tej bazy danych i szybko dodałem kontroler i widok CREATE dla podmiot FOOBAR. Jeśli spróbuję POST do działania CREATE bez wpisywania wartości dla właściwości barName, VS przechodzi do wyjątku w pliku designer.cs modelu (tak jak ten powyżej). Kiedy próbuję przekroczyć wyjątek, w formularzu pojawi się komunikat sprawdzania poprawności, a pole zostanie podświetlone na różowo.

Wygląda na to, że coś nie wystrzeliwuje we właściwej kolejności. Ponieważ wyjątek występuje przed krokami VS w metodę CREATE HTTPPOST.

Znalazłem próbkę kodu z przykładu ASP.Net MvcMusicStore. http://mvcmusicstore.codeplex.com/releases/view/44445#DownloadId=119336

Wygląda na to, że powiązanie z ViewModel rozwiązuje problem.

namespace MvcMusicStore.ViewModels 
{ 
    public class StoreManagerViewModel 
    { 
     public Album Album { get; set; } 
     public List<Artist> Artists { get; set; } 
     public List<Genre> Genres { get; set; } 
    } 
} 
........ 

namespace MvcMusicStore.Models 
{ 
    [MetadataType(typeof(AlbumMetaData))] 
    public partial class Album 
    { 
     // Validation rules for the Album class 

     [Bind(Exclude = "AlbumId")] 
     public class AlbumMetaData 
     { 
      [ScaffoldColumn(false)] 
      public object AlbumId { get; set; } 

      [DisplayName("Genre")] 
      public object GenreId { get; set; } 

      [DisplayName("Artist")] 
      public object ArtistId { get; set; } 

      [Required(ErrorMessage = "An Album Title is required")] 
      [StringLength(160)] 
      public object Title { get; set; } 

      [DisplayName("Album Art URL")] 
      [StringLength(1024)] 
      public object AlbumArtUrl { get; set; } 

      [Required(ErrorMessage = "Price is required")] 
      [Range(0.01, 100.00, ErrorMessage="Price must be between 0.01 and 100.00")] 
      public object Price { get; set; } 
     } 
    } 
} 
1

miałem ten sam problem i naprawić go poprzez false do true tak: odpowiedź

Line 4502: 
_Text = StructuralObject.SetValidValue(value, false); 
1

Ashish Szakja pomógł mnie. Dodałem ten atrybut do właściwości i teraz działa.

[DisplayFormat(ConvertEmptyStringToNull = false, NullDisplayText="")] 

Więc wygląda to tak:

[EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)] 
    [DataMemberAttribute()] 
    [DisplayFormat(ConvertEmptyStringToNull = false, NullDisplayText="")] 
    public global::System.String MyProperty 
    { 
     get 
     { 
      return _MyProperty; 
     } 
     set 
     { 
      OnMyPropertyChanging(value); 
      ReportPropertyChanging("MyProperty"); 
      _MyProperty = StructuralObject.SetValidValue(value, false); 
      ReportPropertyChanged("MyProperty"); 
      OnMyPropertyChanged(); 
     } 
    } 
1

importować nazw:

using System.ComponentModel.DataAnnotations; 

I dodać właściwość atrybutu [Required]

[Required] 
public global::System.String MyProperty 
    { 
     get 
     { 
      return _MyProperty; 
     } 
     set 
     { 
      OnMyPropertyChanging(value); 
      ReportPropertyChanging("MyProperty"); 
      _MyProperty = StructuralObject.SetValidValue(value, false); 
      ReportPropertyChanged("MyProperty"); 
      OnMyPropertyChanged(); 
     } 
    } 

Zatem ModelState.IsValid równa false , pokazujący komunikat o błędzie podczas sprawdzania poprawności i nie zawiedzie na serwerze z wartością Null.

0

Po prostu sam miałem ten sam problem i przybyłem tutaj, aby znaleźć rozwiązanie. Jednak odpowiedź można poprawić.

Svavar's i HackITMngr były na dobrej drodze, jednak połączenie obu daje najlepszy wynik. Nie chcesz dekorować wygenerowanych klas, ponieważ ryzykujesz utratę niestandardowych zmian po modyfikacji modelu EF.

[MetadataType (typeof (MyTableMetaData))] public partial class mojatabela {// zasady walidacji dla klasy albumu

public class MyTableMetaData 
    { 
     [DisplayFormat(ConvertEmptyStringToNull = false, NullDisplayText="")] 
     public string MyTextProperty { get; set; } 
    } 
} 

Aby rozstrzygnąć wszelkie spory pomiędzy nimi. Powiedziałbym, że Svavar była bezpośrednią odpowiedzią, HackITMngr było ulepszeniem.

Działa doskonale dla mnie!

0

Ustawię właściwość StoreGeneratedPattern jako obliczoną dla każdego pola i rozwiązanie problemu dla mnie.

Powiązane problemy