Freigeben über


Silverlight TV: RIA Services Q & A

John and I went through four questions we see frequently on the WCF RIA Services forum. Here’s our episode and some notes to go along with it.

Silverlight TV: Episode 52

How do I investigate exceptions thrown from my DomainContext?

If you’ve been using RIA, you’ve undoubtedly seen this exception before.

Load operation failed for query 'GetEmployees'. Exception of type 'System.ServiceModel.DomainServices.Client.DomainOperationException' was thrown.
at System.ServiceModel.DomainServices.Client.WebDomainClient`1.EndQueryCore(IAsyncResult asyncResult)
at System.ServiceModel.DomainServices.Client.DomainClient.EndQuery(IAsyncResult asyncResult)
at System.ServiceModel.DomainServices.Client.DomainContext.CompleteLoad(IAsyncResult asyncResult)

A rough translation is “An exception was thrown in your DomainService while loading data. ” The problem is this exception is opaque and masks the real failure. What we need is some way to get the details about what is actually occurring.

Option 1: Temporarily set the customErrors mode to “Off”

In your web.config file, you can update the customErrors element.

   <customErrors mode="Off"/>

Option 2: Use fiddler to look at the response from the server

There’s a lot to know about using fiddler, but I’ll keep this section sparse. I showed a little in the video and there are plenty of other examples.

Download Fiddler

Tips for using Fiddler on localhost

Option 3: Override DomainService.OnError to inspect the error on the server

There are a number of reasons to override OnError (logging, etc.) in your DomainServices. One of the ways it can be useful is to give you a place to inspect errors before they’re sent back to the client.

Using any of these method, we can get more useful information from the error.

Load operation failed for query 'GetEmployees'. Object reference not set to an instance of an object.
at SampleBusinessApplication.Web.EmployeeDomainService.GetEmployees() in …\EmployeeDomainService.cs:line 22 at GetEmployees(DomainService , Object[] ) at System.ServiceModel.DomainServices.Server.ReflectionDomainServiceDescriptionProvider.ReflectionDomainOperationEntry.Invoke(DomainService domainService, Object[] parameters) at System.ServiceModel.DomainServices.Server.DomainOperationEntry.Invoke(DomainService domainService, Object[] parameters, Int32& totalCount) at System.ServiceModel.DomainServices.Server.DomainService.Query(QueryDescription queryDescription, IEnumerable`1& validationErrors, Int32& totalCount) at System.ServiceModel.DomainServices.Hosting.QueryProcessor.Process[TEntity](DomainService domainService, DomainOperationEntry queryOperation, Object[] parameters, ServiceQuery serviceQuery, IEnumerable`1& validationErrors, Int32& totalCount) at System.ServiceModel.DomainServices.Hosting.QueryOperationBehavior`1.QueryOperationInvoker.InvokeCore(Object instance, Object[] inputs, Object[]& outputs)

How do I add a ComboBox to a DataGrid or DataForm?

I have a couple posts that cover these topics.

Silverlight ComboBox Frequently Asked Questions

Silverlight ComboBox Sample for RIA Services

How do I change the default metadata added to an Entity when using the LinqToEntitiesDomainService?

It’s worth taking a second to provide context for this question. When you use the LinqToEntitiesDomainService, RIA Services codegen will add some default metadata to your entity types. For instance, if we look at the generated code for our Employee type, we can see the metadata on the FirstName property.

   [DataMember()]
  [Required()]
  [StringLength(10)]
  public string FirstName

It’s worth asking “Where do these value come from?” In short, the code generator is looking at the constraints you specified in your database and converting them into attributes. This helps reduce the number of exceptions you encounter when submitting your changes to the database.

If you want to use something other than the default metadata you only need to specify it yourself. All the metadata you specify will override the codegen defaults. For instance, I can add some metadata to the Employee type.

   // The MetadataTypeAttribute identifies EmployeeMetadata as the class
  // that carries additional metadata for the Employee class.
  [MetadataTypeAttribute(typeof(Employee.EmployeeMetadata))]
  public partial class Employee
  {
    internal sealed class EmployeeMetadata
    {
      [Required(AllowEmptyStrings = true,
                ErrorMessage = "First name cannot be null.")]
      public string FirstName { get; set; }
    }
  }

When I do this, I can see the attribute I specified for the FirstName property get generated in place of the default attribute.

   [DataMember()]
  [Required(AllowEmptyStrings=true,
            ErrorMessage="First name cannot be null.")]
  [StringLength(10)]
  public string FirstName

How do I add cross-field validation to an Entity?

Jeff has some great posts on validation. Here are the two that cover cross-field validation.

Cross-Field Validation

Entity-Level Validation 

Do you have the sample code?

Yep. Here it is.

Comments

  • Anonymous
    November 17, 2010
    I use in DataForm a Combobox and combine the selectedItem with validation attribute. When a validation failed for a property and this property is bound to a textbox, the textbox is borderd in red and the label is highlighted also in red. I want to realize that in the same way with the Combobox. What to do?

  • Anonymous
    November 17, 2010
    It should just happen by default. If it doesn't, there are a few things to check. (1) Is the ComboBox two-way binding to the same property the TextBox was? (2) Is the validation method the same? (3) Is the validation method returning a ValidationResult with the property names specified?

  • Anonymous
    January 08, 2011
    @kylemc: Thanks for the sample you published, this helped me to solve my problem: blogs.msdn.com/.../using-ria-services-with-comboboxes-and-enums.aspx