Throwing the concurrent access message down to the Silverlight client

Throwing the concurrent access message down to the Silverlight client

Old forum URL: forums.lhotka.net/forums/t/9091.aspx


chrisdot posted on Wednesday, June 16, 2010

Hello,

I'm using the latest 3.8 of cslalight on both client and server side (SL4).

I would like to manage the concurrent DB access problem. I decided to use the timestamp technique to handle that like explained in this thread. But this is not really the problem here.

My question is rather about finding a way to propagate this information down to the client. Suppose we are updating a business object. Once we have reached the DataPortal_Update() on the server side, and that we have detected the concurrent access problem, what would be the relevant strategy to notify the silverlight client ? 

Naturally, I was thinking of using the exceptions to handle that. But as I could read here, here, and here, as SL is not the same framework as full .NET, we can't serialize the exceptions on server and just deserialize them on the client, and that's why evrything is "pasted" into DataPortalException.(ErrorInfo of DataPortalException on client side).

But, I consider the case of the concurrent access problem is not the same as another general error (let's say a fatal error, where we could not do anything). I just would like to notify user that he should reload the date or something like that. How can I make a distinction of the exception coming to the client side? I started overriding the DataPortalException class, but it doesn't seem to be the relevant way. (Basically, I don't want to have to extract strings in the DataPortalException.Message, because I hate handling strings, and additionnaly, the [collapse]original message of the exception is a subset of the transported exception message. CSLA is doing some string.format() around it before sending it through the wires) 

Does anyone have an idea to solve that, or another strategy? (even other than using exceptions) I browsed through the samples, but could not find anything about that (in the book neither)...

Thank you,

Christophe

[/collapse]

rnb replied on Wednesday, June 16, 2010

Hi Christophe,

You're on the right track with the ErrorInfo.  The structure is similar to the way inner exceptions are nested.  So if your custom concurrent exception is the lowest level, you'll want to drill down the ErrorInfo.InnerError all the way down to the last one.  You can then compare the ExceptionTypeName to your exception class name.  You can also link and compile your existing exception class file into your Silverlight library project so you can compare it to the FullName property.  So, something like:

if (errorInfo.ExceptionTypeName == typeof(ConcurrentException).FullName)

...

 

That's the closest to a strongly typed solution that I can think of.

Good luck.

chrisdot replied on Thursday, June 17, 2010

Thank you MB for your answer.

I tried to rely on your idea, but I could not achieve anything significant.

Here is what I've done. First I created my

public class ConcurrencyException : DataPortalException

{

       public ConcurrencyException(string message, object businessObject)

              :base(message, businessObject)

       {

       }

}

 

Then, when in the DataPortal update method (handling my concurrency tests), I put the following (just throwing my new exception) :

protected override void DataPortal_Update()

{

       //...

       throw new ConcurrencyException("Concurrent access", this);

       //...

}

 

Finally, on my SL client side, I test my error info :

private void SaveDone(object source, DataPortalResult<CVisitDetailBO> args)

{

       if (args.Error != null)

       {

             DataPortalException custom_excp = args.Error as DataPortalException;

             string exception_name = custom_excp.ErrorInfo.ExceptionTypeName;

 

             //!!!!

//And here, exception_name is still "DataPortalException" Is that correct ?

       }

}

 

What did I miss? What should I do?

Thanks, Christophe

rnb replied on Thursday, June 17, 2010

All exceptions gets wrapped inside a DataPortalException.  So what you want to do is get the innermost error.


        private static WcfErrorInfo GetInnermostErrorInfo(DataPortalException exception)
        {
            WcfErrorInfo errorInfo = exception.ErrorInfo;
            while (errorInfo.InnerError != null)
            {
                errorInfo = errorInfo.InnerError;
            }

            return errorInfo;
        }

 

That should give you "Namespace.ConcurrencyException"

chrisdot replied on Friday, June 18, 2010

Hello RNB,

Ok, now I understand (sorry, I should have found that alone). This is exactly what I need !

Thanks a lot!!

Christophe

skagen00 replied on Friday, June 18, 2010

I actually have a ConcurrencyException myself and I dig into the exception if it's a dataportalexception to check for concurrency exception... it works just fine - just set a debug breakpoint and open up the exception until you find exactly where the concurrency exception can be detected (I don't have code in front of me right now).

 

 

chrisdot replied on Friday, June 18, 2010

@skagen00: just in case, if you find the example, I would still be interested just to gather different ideas.

Copyright (c) Marimer LLC