Error Messages

You might run into a variety of error messages, but we’ll try to focus on some of the more common areas where problems might arise.

Let’s start off by looking at a couple common error messages.You might run into this one right off the bat:

System.IO.FileInfo cannot be serialized because it does not have a default public
 constructor. 

If you manage to get past that error, you might run into the following one:

System.Exception: There was an error generating the XML document. – - > 
System.Exception: System.IO.FileInfo cannot be serialized because it does not have a
 default public constructor. 
   at System.Xml.Serialization. TypeScope.ImportTypeDesc(Type type, Boolean canBePrimitive) 
   at System.Xml.Serialization. TypeScope.GetTypeDesc(Type type) 
   at System.Xml.Serialization. TypeScope.ImportTypeDesc(Type type, Boolean canBePrimitive) 
   at System.Xml.Serialization. TypeScope.GetTypeDesc(Type type) 
   atSystem.Xml.Serialization.XmlSerializationWriter.CreateUnknownTypeException(Type type) 
   at System.Xml.Serialization.XmlSerializationWriter.WriteTypedPrimitive(String name,
 String ns, Object o, Boolean xsiType) 
   atn2499d7d93ffa468fbd8861780677ee41.XmlSerializationWriter1.Write4_Object(String n,
 String ns, Object o, Boolean isNullable, Boolean needType) 
   atn2499d7d93ffa468fbd8861780677ee41.XmlSerializationWriter1.Write9_Object(Object o) 
   at System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o,
 XmlSerializerNamespaces namespaces) 
   at System.Xml.Serialization.XmlSerializer.Serialize(TextWriter textWriter, Object o) 
   at System.Web.Services.Protocols.XmlReturnWriter.Write(HttpResponse response, Stream
 outputStream, Object returnValue) 
   at System.Web.Services.Protocols.HttpServerProtocol.WriteReturns(Object[] returnValues,
 Stream outputStream) 
   at System.Web.Services.Protocols.WebServiceHandler.WriteReturns(Object[] returnValues) 
   at System.Web.Services.Protocols.WebServiceHandler.Invoke() 
   at System.Web.Services.Protocols.WebServiceHandler.CoreProcessRequest() 

If you get either of those messages, whether while your service is just starting or as you invoke the method that returns the data that caused the error, most likely you are trying to return a complex data set or array that the system cannot serialize. If you take a look at Listings 13.5 and 13.6, you can see that it would be easy to overlook what type of data the system can return.

Listing 13.5. Complex Return Type (C#)
[WebMethod] 
             public DirectoryInfo[] Dir(string dir) 
             {
                   DirectoryInfo di = new DirectoryInfo(dir); 

                   DirectoryInfo[] diList = di.GetDirectories("*.*"); 

                   return diList; 

             } 

Listing 13.6. Complex Return Type (Visual Basic .NET)
<WebMethod()> Public Function Dir(ByVal dir As String) As DirectoryInfo() 

    Dim di As New DirectoryInfo(dir) 

        Dim diList as di.GetDirectories("*.*") 

    Return diList 
End Function 

The code in Listings 13.5 and 13.6 looks fine, but it won’t work. So now what do you do? Well, one way to work around this is to build your own array and then pass it back to the client. If you do this, you must make sure that the array structure is published to public so that the users know what they are working with. This gets accomplished in Listings 13.7 and 13.8.

Listing 13.7. Custom Return Type (C#)
using System; 
using System.Collections; 
using System.ComponentModel; 
using System.Data; 
using System.Diagnostics; 
using System.Web; 
using System.Web.Services; 
using System.Xml.Serialization; 
using System.IO; 

namespace DirectoryTools 
{
      /// <summary> 
      /// Summary description for Service1. 
      /// </summary> 
      public class Service1 : System.Web.Services.WebService 
      {
            public Service1() 
            {
                  //CODEGEN: This call is required by the ASP.NET Web 
Services Designer 
                  InitializeComponent(); 
            } 

            #region Component Designer generated code 
            /// <summary> 
            /// Required method for Designer support - do not modify 
            /// the contents of this method with the code editor. 
            /// </summary> 
            private void InitializeComponent() 
            {
            } 
            #endregion 

            /// <summary> 
            /// Clean up any resources being used. 
            /// </summary> 
            protected override void Dispose( bool disposing ) 
            {
            } 
            // WEB SERVICE EXAMPLE 
            // The HelloWorld() example service returns the string Hello World 
            // To build, uncomment the following lines and then save and build the project 
// To test this web service, press F5 

            [WebMethod] 
            public string HelloWorld() 
            {
                  return "Hello World"; 
            } 

            [WebMethod()] 
            [XmlInclude(typeof(DirObject))] 
            public DirObject Test( string sPath) 
            {
                  DirectoryInfo di = new DirectoryInfo(sPath); 
                  DirectoryInfo[] diList = di.GetDirectories("*.*"); 
                  DirObject temp = new DirObject(); 
                  int x = 0; 
                  foreach ( DirectoryInfo d in diList) 
                  {
                        temp[x] = d; 
                        x++; 
                  } 
                  return temp; 
            } 
      } 

      [XmlInclude(typeof(DirItem))] 
      public class DirObject 
      {
            [XmlElement("Item")] 

            public ArrayList Data 
            {
                  get { return data;} 
                  set { data = value;} 
            } 
            protected ArrayList data = new ArrayList(); 

            public object this [int idx] 
            {
                  get 
                  {
                         if (idx > -1 && idx < data.Count) 
                         {
                               return (data[idx]); 
                         } 
                         else 

                               return null; 
                         } 
                  } 

                  set 
                  {
                         if (idx > -1 && idx < data.Count) 
                         {
                               data[idx] = value; 
                         } 
                         else if (idx == data.Count) 
                         {
                               DirItem x = new DirItem(); 
                               DirectoryInfo temp = (DirectoryInfo)value; 
                               x.FileName = temp.FullName; 
                               data.Add(x); 

                         } 
                         else 
                         {
                               //Possibly throw an exception here. 
} 
                  } 
            } 

      } // MyClass 

      public class DirItem 
      {
            protected string filename; 

            public DirItem() 
            {
            } 

            [XmlAttribute("FileName")] 
            public string FileName 
            {
                  get { return filename;} 
                  set { filename = value;} 
            } 
      } 

} //Name space 

Listing 13.8. Custom Return Type (Visual Basic .NET)
Imports System.Web.Services 
Imports System.IO 
Imports System.Xml 
Imports System.Xml.Serialization 

<WebService(Namespace:="http://microsoft.com/webservices/")> Public Class Service1 
    Inherits System.Web.Services.WebService 

#Region " Web Services Designer Generated Code " 

    Public Sub New() 
        MyBase.New() 

        'This call is required by the Web Services Designer. 
        InitializeComponent() 

        'Add your own initialization code after the InitializeComponent() call 

    End Sub 
    'Required by the Web Services Designer 
    Private components As System.ComponentModel.Container 

    'Do not modify it using the code editor. 
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent() 

        components = New System.ComponentModel.Container() 

    End Sub 

    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean) 
        'Do not modify it using the code editor. 
    End Sub 

#End Region 

    ' 
    <WebMethod()> Public Function Test(ByVal path As String) As DirObject 
        Dim di As DirectoryInfo = New DirectoryInfo(path) 
        Dim diList() As DirectoryInfo 
        Dim d As DirectoryInfo 
        Dim temp As DirObject = New DirObject() 
        Dim x As Integer = 0 

        diList = di.GetDirectories("*.*") 

        For Each d In diList 
            temp(x) = d 
            x = x + 1 
        Next 
        Return temp 
    End Function 


    <XmlInclude(GetType(DirItem)), XmlRoot("Root")> Public Class DirObject 
        Private pdata As ArrayList = New ArrayList() 

        <XmlElement("Item")> Public Property Data() As ArrayList 
        Get 
            Return pdata 
        End Get 

        Set(ByVal Value As ArrayList) 
            pdata = Value 
        End Set 
    End Property 

    Default Public Property base(ByVal idx As Integer) As Object 
        Get 
            If (idx > -1 And idx < Data.Count) Then 

                Return pdata(idx) 

            Else 

                Return Nothing 

            End If 

        End Get 

        Set(ByVal Value As Object) 
            If (idx > -1 And idx < pdata.Count) Then 
                pdata(idx) = Value 

            ElseIf (idx = pdata.Count) Then 
                Dim x As DirItem = New DirItem() 
                Dim temp As DirectoryInfo 

                temp = CType(Value, DirectoryInfo) 
                x.FileName = temp.FullName 
                x.LastAccessDate = temp.LastAccessTime 
                pdata.Add(x) 

            Else 
                'Possibly throw an exception here. 
            End If 

        End Set 

    End Property 
    End Class 

    Public Class DirItem 

        Private pfilename As String 
        Private pLastAccessDate As Date 

        Sub DirItem() 

        End Sub 

        <XmlElement("FileName")> Public Property FileName() As String 
            Get 
                Return pfilename 
            End Get 

            Set(ByVal Value As String) 
                pfilename = Value 
            End Set 

        End Property 

     <XmlElement("LastAccessDate")> Public Property LastAccessDate() As Date 
            Get 
                Return pLastAccessDate 
            End Get 

            Set(ByVal Value As Date) 
                pLastAccessDate = Value 
            End Set 

        End Property 

    End Class 

End Class 

In Listings 13.7 and 13.8, you will notice a few new elements that you might not have seen before: <XmlAttribute> and <XmlInclude>. These additional features define the output when this class is serialized. This is a great way to rename elements in the XML structure to something more meaningful.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset