My problem is that when I add a new entity with a required field, the entity doesn't show the validation error in the UI. I'm using using EF CTP4 Code First. My setup :
I have an entity.
public class Category
{
[Key]
public int Id { get; set; }
[Required]
public string Name { get; set; }
public string ImageUrl { get; set; }
}
I then have my DbContext
public class CompuSportCatalog : DbContext
{
/// <summary>
/// Initializes a new instance of the TestDbContext class
/// Default initialization the context will search for a connection
/// with the same name in the .config file
/// </summary>
public CompuSportCatalog()
: base()
{
Database.SetInitializer<CompuSportCatalog>(new RecreateDatabaseIfModelChanges<CompuSportCatalog>());
}
/// <summary>
/// Exposes the ObjectContext of the DbContext
/// As suggested by Arthur Vickers
/// </summary>
public new ObjectContext ObjectContext
{
get
{
return base.ObjectContext;
}
}
public DbSet<Category> Categories { get; set; }
public IEnumerable<Category> GetCategories()
{
var q = from c in this.Categories
select c;
return q.AsEnumerable();
}
}
And my DomainService
[EnableClientAccess()]
public partial class CompuSportDomain : DomainService
{
private CompuSportCatalog context = new CompuSportCatalog();
public IEnumerable<Category> GetCategories()
{
return this.context.GetCategories();
}
public void InsertCategory(Category category)
{
this.context.ObjectContext.AddObject("CategorySet", category);
this.context.SaveChanges();
}
public void UpdateCategory(Category currentCategory)
{
this.context.Categories.Find(currentCategory.Id);
this.context.ObjectContext.ApplyCurrentValues("CategorySet", currentCategory);
this.context.SaveChanges();
}
public void DeleteCategory(Category category)
{
this.context.ObjectContext.AttachTo("CategorySet", category);
this.context.ObjectContext.DeleteObject(category);
this.context.SaveChanges();
}
}
My UI
<navigation:Page
x:Class="TestCodeFirst.Home"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
xmlns:riaControls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.DomainServices"
xmlns:my="clr-namespace:TestCodeFirst.Web.Domain"
xmlns:my1="clr-namespace:TestCodeFirst.Web.Models"
xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480"
Style="{StaticResource PageStyle}"
>
<Grid x:Name="LayoutRoot">
<ScrollViewer x:Name="PageScrollViewer" Style="{StaticResource PageScrollViewerStyle}" >
<StackPanel x:Name="ContentStackPanel" Style="{StaticResource ContentStackPanelStyle}">
<TextBlock x:Name="HeaderText" Style="{StaticResource HeaderTextStyle}"
Text="{Binding Path=ApplicationStrings.HomePageTitle, Source={StaticResource ResourceWrapper}}"/>
<TextBlock x:Name="ContentText" Style="{StaticResource ContentTextStyle}"
Text="Home page content"/>
<riaControls:DomainDataSource AutoLoad="True" d:DesignData="{d:DesignInstance my1:Category, CreateList=true}" Height="0" LoadedData="categoryDomainDataSource_LoadedData" Name="categoryDomainDataSource" QueryName="GetCategoriesQuery" Width="0">
<riaControls:DomainDataSource.DomainContext>
<my:CompuSportDomain />
</riaControls:DomainDataSource.DomainContext>
</riaControls:DomainDataSource>
<sdk:DataGrid AutoGenerateColumns="False" Height="200" ItemsSource="{Binding ElementName=categoryDomainDataSource, Path=Data}" Name="categoryDataGrid" RowDetailsVisibilityMode="VisibleWhenSelected" Width="400">
<sdk:DataGrid.Columns>
<sdk:DataGridTextColumn x:Name="idColumn" Binding="{Binding Path=Id, Mode=OneWay}" Header="Id" IsReadOnly="True" Width="SizeToHeader" />
<sdk:DataGridTextColumn x:Name="imageUrlColumn" Binding="{Binding Path=ImageUrl}" Header="Image Url" Width="SizeToHeader" />
<sdk:DataGridTextColumn x:Name="nameColumn" Binding="{Binding Path=Name}" Header="Name" Width="SizeToHeader" />
</sdk:DataGrid.Columns>
</sdk:DataGrid>
<Button Content="Button" Height="23" Name="button1" Width="75" Click="button1_Click" />
<Button Content="Button" Height="23" Name="button2" Width="75" Click="button2_Click" />
</StackPanel>
</ScrollViewer>
</Grid>
</navigation:Page>
And my UI code
public partial class Home : Page
{
private Category cat;
/// <summary>
/// Creates a new <see cref="Home"/> instance.
/// </summary>
public Home()
{
InitializeComponent();
this.Title = ApplicationStrings.HomePageTitle;
}
/// <summary>
/// Executes when the user navigates to this page.
/// </summary>
protected override void OnNavigatedTo(NavigationEventArgs e)
{
}
private void categoryDomainDataSource_LoadedData(object sender, System.Windows.Controls.LoadedDataEventArgs e)
{
if (e.HasError)
{
System.Windows.MessageBox.Show(e.Error.ToString(), "Load Error", System.Windows.MessageBoxButton.OK);
e.MarkErrorAsHandled();
}
}
private void button1_Click(object sender, System.Windows.RoutedEventArgs e)
{
cat = new Category();
//NOTE: Works fine with the 2 commented lines
//cat.Accronym = "e";
//cat.Accronym = "";
categoryDomainDataSource.DataView.Add(cat);
}
private void button2_Click(object sender, System.Windows.RoutedEventArgs e)
{
//List<ValidationResult> validationResults = new List<ValidationResult>();
//ValidationContext validationContext = new ValidationContext(cat, null, null);
//Validator.TryValidateObject(cat, validationContext, validationResults, true);
categoryDomainDataSource.DomainContext.SubmitChanges(
submitOperation =>
{
if (submitOperation.HasError)
{
//MessageBox.Show(submitOperation.Error.Message);
}
},
null);
}
}
This works fine if I set a dummy value to the required property since the generated property set calls ValidateProperty (the 2 commented lines in button1_click).
Am I doing something wrong in there?