views:

30

answers:

0

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?

related questions