0

I tried to solve by myself, but... Looks like I need help from people. I have Business Silverlight application with WCF RIA and EntityFramework. Access to Database I get via LinqToEntites.

Common loading data from database I making by this:

return DbContext.Customers

This code returns full Customers table from DataBase. But sometimes I do not need to show all data. Easy way is use linq filters in client side by next code:

public LoadInfo()
{
...
var LO1 = PublicDomainContext.Load(PublicDomainContext.GetCustomersQuery());
            LO1.Completed += LO1Completed;
...
}

private void LO1Completed(object sender, EventArgs eventArgs)
{
...
DatatViewGrid.ItemsSource = null;
DatatViewGrid.ItemsSource = loadOperation.Entities.Where(c=>c ...filtering...); 
//or PublicDomainContext.Customers.Where(c=>c ...filtering...)
...
}

However this way has very and very important flaw: all data passing from server to client side via DomainService may be viewed by applications like Fiddler. So I need to come up with another way.

Task: filter recieving data in server side and return this data.

Way #1: LinqToEntites has a beautiful projection method:

//MSDN Example
var query =
contacts.SelectMany(
    contact => orders.Where(order =>
        (contact.ContactID == order.Contact.ContactID)
            && order.TotalDue < totalDue)
        .Select(order => new
        {
            ContactID = contact.ContactID,
            LastName = contact.LastName,
            FirstName = contact.FirstName,
            OrderID = order.SalesOrderID,
            Total = order.TotalDue
        }));

But, unfortunately, DomainServices cannot return undefined types, so this way won't work.

Way #2: I found next solution - make separate DTO classes (DataTransferObject). I just read some samples and made on the server side next class:

[DataContract]
public partial class CustomerDTO
{
    [DataMember]
    public int ISN { get; set; }
    [DataMember]
    public string FIO { get; set; }
    [DataMember]
    public string Listeners { get; set; }
}

And based this class I made a row of methods which return filtered data:

[OperationContract]
public List<CustomerDTO> Customers_Common()
{
     return DbContext.Customers....Select(c => new CustomerDTO { ISN = c.ISN, FIO = c.FIO, Listeners = c.Listeners }).ToList();
}

And this works fine, all good...

But, there is strange problem: running application locally does not affect any troubles, but after publishing project on the Web Site, DomainService returns per each method HTTP 500 Error ("Not Found" exception). Of course, I cannot even LogIn into my application. DomainService is dead. If I delete last class and new methods from application and republish - all works fine, but without speacial filtering...

The Question: what I do wrong, why Service is dying with new classes, or tell me another way to solve my trouble. Please.


U P D A T E :

Hey, finally I solved this! There is an answer: Dynamic query with WCF RIA Services

Community
  • 1
  • 1
Mans7
  • 30
  • 6

1 Answers1

1

Your best shot is to find out what is causing the error. For that, override the OnError method on the DomainService like this:

 protected override void OnError(DomainServiceErrorInfo errorInfo)
 {
     /* Log the error info to a file. Don't forget inner exceptions.
      */

     base.OnError(errorInfo);
 }

This is useful, because only two exceptions will be passed to the client, so if there are a lot of nested inner exceptions, you should still be able to see what actually causes the error.

In addition, you can inspect the error by attaching the debugger to the browser instance you are opening the site with. In VS2010 this is done by doing [Debug] -> [Attach to Process] in the menu-bar.

LueTm
  • 2,366
  • 21
  • 31
  • I think this won't work, because, the DomainService is not found with DTO classes. Fiddler returns HTTP 500 error. And typing service link (e.g. website.com/ClientBin/My-Service.svc) too returns HTTP 500, so method OnError won't occur. So even if I delete this service, nothing changes with DTO classes. – Mans7 Apr 30 '13 at 07:11
  • You have to override this method in your 'PublicDomainService' in the .Web Project. It really should be there. In the same place your service methods are. – LueTm Apr 30 '13 at 07:24
  • You do not understand... The Service s NOT FOUND. So it is does not matter what code in DomainService, because it is NOT FOUND with classes. Application NEVER reach OnError method, because it is hasn't object of DomainService class, because (again) - service is NOT FOUND... – Mans7 Apr 30 '13 at 10:40
  • NOT FOUND is just an error message that means that there was an error. But hey, do what you want. – LueTm Apr 30 '13 at 20:44