Blacklight.Controls.DragDockPanel - Maximize To Fullscreen

by CoderForRent 2. September 2009 04:06

The Problem

Sometimes you want to maximize the contents of the DragDockPanel to encompass the entire Host control area.  If this is a fullscreen app, this would be the entire browser.

 

 

The Solution

The code for this can be found in the CoderForRent.ProductManager.Client.Controls assembly.  I tried listing it here, but there's just too much.

Here is a link to the CodePlex Source code page.

 

The Example

The Product Manager uses a child class (SettingsDragDockPanel) of this control in the dashboard on the home page and a live demo can be found at pim.coderforrent.com.  The code for SettingsDragDockPanel can be found in that codeplex app as well.

 

Tags: , , ,

Silverlight

Silverlight/WCF - (404) Not Found - BEGONE!

by CoderForRent 25. August 2009 04:08

The Problem

The first problem is that any error thrown in the WCF layer of the application will be returned to Silverlight as "The remote server returned an unexpected response: (404) Not Found".  This isn't helpful in the least bit.  For now, let's not ask the obvious question, "Why not return better errors?"  Instead, let's look for a solution that we can control. 

Additionally, we need means to track the errors that are thrown in both the server and client.

The Basic Solution

 

The (404) Not Found Error

The first reason people get this error when they get started is because the iis root does not have the clientaccesspolicy.xml file defined properly.  This post should help you out there.  If you have this in place and you are still getting the error, make sure it is in the IIS root directory.  In Visual Studio, you can use the Development Server or the local IIS to host the WCF application.  If you use the Visual Studio Development Server, make sure the "Virtual path" is "/" and not some extended path.  Adding some virtual path here will make it impossible for you to add the clientaccesspolicy.xml file as there is no "root" directory.  It should look something like the picture below (note: you can assign any port number that you'd like).

 

 

 

 

Better Error Handling

The previous section will more than likely get you past the new project woes of 404 Not Found, but we still have to be able to track errors in our application in a responsible way.  We don't want the user of the application to see our ugly error messages, so our solution will have to be fault safe and any single error should not result in complete application failure.

 

Step 1 - Create a common Result object

We will ALWAYS return an object from the web service call (no void calls).  This means that the only server error that can occur (and not get handled) will be a bad connection to the server. A simple example of the Result object is:

[DataContract]
public class Result
{
[DataMember]
public bool HasError{get; set;}

[DataMember]
public string CustomMessage{get; set;}

public Result(){
   HasError = false;
   CustomErrorMessage = null;
}

public Result(ErrorLog err){
   HasError = true;
   CustomErrorMessage = "An error has occurred.";

}
}

 

 

Step 2 - Create an ErrorLog data store and ErrorManager class for the server

The data store can be of any type that you choose, but for the purposes of this article, I will assume a SQL Table named ErrorLog.  This table can be defined as :

 

 

 

You can of course add other fields if you have a need, such as Message, etc.  This works for our purposes. 

Defining a class called ErrorLogManager will give you an easy way to pass errors to the database.  It can be defined as:


public class ErrorLogManager
{
public static ErrorLog HandleException(Exception exc, string module, string userId)
{
//This is Linq To Sql, but you could use anything.  It's a black box.

using(MyDataContext db = new MyDataContext)
{
  ErrorLog err = new ErrorLog();
  err.StackTrace = exc.StackTrace;
  err.Module = module;
  err.UserId = userId;
  err.DateCreated = DateTime.Now;

  db.ErrorLogs.InsertOnSubmit(err);
  db.SubmitChanges();

  return err;
}
}
}

 

Step 3 Writing the Service

 

I won't spend any time explaining the service layer as it is unimportant, but the basic setup should be like this:

[OperationContract]
public Result DoSomething()
{
     try
     {
         return BusinessManager.DoSomething();
     }
     catch(Exception exc)
     {
        return new Result(ErrorLogManager.HandleException(exc, "Foo", "Bar"));
     }
}
 

 

Step 4 Extending the Result Object

It wouldn't be very useful if the error framework didn't allow other custom Data Transfer Objects to be passed in addition to the error information.  We can inherit from the Result class an create a generic Result<T> that will solve this issue:

[DataContract]
public class Result<T> : Result
{

[DataMember]
public T Item{get; set;}
public Result(T item) : base()
{
this.Item = item;
}

public Result(ErrorLog err) : base(err)
{
  Item = null;
}

}

I have also found it useful to have a Resultlist<T> option as well:

[DataContract]
public class ResultList<T> : Result
{

[DataMember]
public List<T> Items{get; set;}
public ItemResult(T items) : base()
{
this.Items = items;
}

public ItemResult(ErrorLog err) : base(err)
{
  Item = null;
}

}

 

The Example

 

Our Product Information Manager uses this model in the latest builds.  It is the only open source example of this method that I know of.

 

 

Tags: , ,

Silverlight