2009-11-22 10 views
5

VS 2010 Beta 2, .NET 4.errore di Entity Framework al momento della presentazione campi vuoti

Nel mio 2 applicazione ASP.NET MVC, quando invio un modulo per un metodo di azione che accetta un oggetto creato da Entity Framework , ottengo il seguente errore:

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(); 

la struttura si chiama "testo" ed è di tipo "text NOT NULL" in MS SQL 2008.

la mia azione sarà verificare se il valore è nullorempty, se è, verrà aggiunto un errore di modello, ma ottengo l'errore non appena invio il modulo.

+0

Forse questo non è direttamente correlato alla tua domanda, ma il tipo di dati TEXT è deprecato. Hai NVARCHAR (MAX) da SQL Server 2005. È molto più facile da usare in molte situazioni. – LukLed

+0

Grazie, ho modificato i miei campi in nvarchar (e aggiornato il modello di database utilizzando la procedura guidata di aggiornamento della struttura dell'entità), ma il problema esiste ancora. – Omar

risposta

8

Sei collegato direttamente all'entità? Certo sembra. Quindi hai due scelte:

  1. Scrivi un raccoglitore modello personalizzato che traduce null -> stringa vuota.
  2. Associare a un modello di modifica che consente invece null, quindi modificarlo in stringa vuota quando si copiano i valori nell'entità nell'azione.

sceglierei il n. 2, personalmente. Penso che dovresti sempre usare i modelli di visualizzazione/modifica e questo è un ottimo esempio del perché.

2

Si tratta di un problema con MVC2 e Entity Framework 4 o è questo in base alla progettazione? Sembra che la convalida delle proprietà EF funzioni correttamente per i campi datetime non annullabili (obbligatori) e la convalida del tipo di dati dei campi numerici rispetto a stringhe funzioni senza dover utilizzare ViewModels.

Ho ricreato il problema utilizzando con una semplice tabella FOOBAR utilizzando una singola colonna varchar (50) non nullable denominata barName in slq 2008. Ho generato il modello EF da quel database e aggiunto rapidamente un controller e una vista CREATE per l'entità FOOBAR. Se provo a POST per l'azione CREATE senza inserire un valore per la proprietà barName, VS esegue un'eccezione all'interno del file designer.cs del modello (proprio come quello precedente). Quando, provo a superare l'eccezione, il messaggio di convalida compare sul modulo e il campo è evidenziato in rosa.

Sembra che qualcosa non stia sparando nella sequenza corretta. Perché l'eccezione si verifica prima che VS passi nel metodo HTTPPOST CREATE.

Ho trovato utile il codice dall'account ASP.Net MvcMusicStore. http://mvcmusicstore.codeplex.com/releases/view/44445#DownloadId=119336

Sembra che il collegamento al ViewModel risolva il problema.

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

Ho avuto lo stesso problema e ha risolto il tutto facendo false a true in questo modo: risposta

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

Ashish di Shakya ha aiutato me. Ho aggiunto questo attributo alla proprietà e ora funziona.

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

in modo che appaia in questo modo:

[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

Import namespace:

using System.ComponentModel.DataAnnotations; 

e aggiungere la proprietà dell'attributo [Required]

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

Così ModelState.IsValid uguale falso , mostra un messaggio di errore nella convalida e non fallirà sul server con Null.

0

Ho appena avuto lo stesso problema e sono venuto qui per trovare la soluzione. Tuttavia, la risposta può essere migliorata.

Svavar's e HackITMngr erano sulla strada giusta, tuttavia la combinazione di entrambi offre il miglior risultato. Non vuoi andare a decorare le classi generate, poiché rischi di perdere le modifiche personalizzate in seguito alle modifiche apportate al modello EF.

[MetadataType (typeof (MyTableMetaData))] public partial class MyTable { regole // validazione per la classe Album

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

per risolvere le eventuali argomenti tra i due. Direi che Svavar era la risposta diretta, HackITMngr era il miglioramento.

Funziona alla grande per me!

0

Ho impostato la proprietà StoreGeneratedPattern come calcolato per ogni campo e ha risolto il problema per me.