Blog Stats
  • Posts - 17
  • Articles - 2
  • Comments - 16
  • Trackbacks - 1

 

Friday, April 07, 2006

XML attributes may not be specified for the type - Serialization Error

"XML attributes may not be specified for the type"
XmlSerializer and CollectionBase derived classes

I get this error when I try to serialize an object that is based upon the CollectionBase class and has an XmlRoot attribute.

The solution is to provide hints in the Serialization method to add a defined root in the generated XML. Thanks to user "armanddp" http://dotnet.org.za/armand/archive/2004/09/21/4164.aspx, I have beautified his solution as shown below:


Step 1: Create an attribute class that you can use to specifiy the root attribute.

[AttributeUsage(AttributeTargets.Class)]
     public class XmlRootNameAttribute : Attribute
     {
          public XmlRootNameAttribute()
          {}
          public XmlRootNameAttribute(string name)
          {
               this.name = name;
          }
          public string name = string.Empty;
     }

Step 2: Add the attribute to your own class.

[Serializable]
[XmlRootName("StepClassConfigurationCollection")]
public class MyCollection : CollectionBase, IList
     {}

Step 3: Create a Serializer method to read the extra attribute, if it exists, otherwise serialise as per normal.

/// <summary>
          /// Serialize the given object into a string
          /// </summary>
          /// <param name="o"></param>
          /// <returns></returns>
          public string SerializeObject(object o)
          {
               string ret = string.Empty;
               Stream writer = new MemoryStream();
               XmlSerializer ser = null;
               XmlRootAttribute ra = new XmlRootAttribute();
               Type objectType = o.GetType();
               // determines if the custom attribute was found
               bool bAttFound = false;

               ra.Namespace = string.Empty;               
               // try and find the custom attribute that will determine the root namespace.
               object [] oAtt = objectType.GetCustomAttributes(typeof(PMPDO.XmlRootNameAttribute), false);
               if (oAtt != null)
               {
                    if (oAtt.Length > 0)
                    {
                         bAttFound = true;
                         // use the given root name
                         ra.ElementName = ((PMPDO.XmlRootNameAttribute)oAtt[0]).name;
                    }
               }

               if (!bAttFound)
               {
                    // if there is no root name provided, then just use the default
                    ser = new XmlSerializer(objectType);
               }
               else
               {
                    // otherwise use the provided root name
                    ser = new XmlSerializer(objectType, ra);
               }

               XmlSerializerNamespaces ns = new XmlSerializerNamespaces();

               ns.Add("","");  

               if (bAttFound)
               {
                    // use the given root when provided
                    ser.Serialize(writer, o, ns);
               }
               else
               {               
                    // otherwise use the default (no root provided)
                    ser.Serialize(writer, o);
               }
  
               // read the string from the serialized stream
               writer.Position = 0;
               StreamReader sr = new StreamReader(writer,System.Text.Encoding.ASCII);
               ret = sr.ReadToEnd();

               return ret;
          }

Logging Block Type Initializer Error

MS Logging and Instrumentation Block

Error: The type initializer for "Microsoft.Practices.EnterpriseLibrary.Data.Instrumentation.DataConnectionFailedEvent" threw an exception.

Repeat the following for all the code blocks you are using:

C:\WINNT\Microsoft.NET\Framework\v1.1.4322\InstallUtil.exe <destinationfolder>\Microsoft.Practices.EnterpriseLibrary.Common.dll

Intermittent Web Services Error

Intermittent Web Services Error

I have a proxy class that performs a large number of calls on a web service.
It fails intermittently with the following error:

System.Net.WebException: The request failed with HTTP status 401:
Unauthorized. at System.Web.Services.Protocols.SoapHttpClientProtocol.
ReadResponse(SoapClientMessage message, WebResponse response,
Stream responseStream, Boolean asyncCall)
at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke
(String methodName, Object[] parameters)

To fix this, you should disable the Keep Alive feature on IIS and the proxy class.

Disable Keep Alive in IIS
To disable go to the Web site tab of the Web site properties window and uncheck the Keep Alive options.

Disable Keep Alive in Proxy
You need to override the default handling of WebRequest as shown below:

protected override System.Net.WebRequest GetWebRequest(Uri uri)
{
System.Net.HttpWebRequest webRequest =
(System.Net.HttpWebRequest) base.GetWebRequest(uri);
webRequest.KeepAlive = false;
return webRequest;
}

More Information on Keep Alive
Keep alive keeps the connection open across multiple requests.
To find out more, see: https://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/59e9c2d2-b772-4c43-82f0-e669427eeb89.mspx

and

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemnethttpwebrequestclasskeepalivetopic.asp

Sql Server DTC Error

SQL Server DTC Error

Error Message:

Server: Msg 7391, Level 16, State 1, Procedure p_SP1, Line XThe operation could not be performed because the OLE DB provider 'SQLOLEDB' was unable to begin a distributed transaction.[OLE/DB provider returned message: New transaction cannot enlist in the specified transaction coordinator. ]OLE DB error trace [OLE/DB Provider 'SQLOLEDB' ITransactionJoin::JoinTransaction returned 0x8004d00a].

Resolution

See http://support.microsoft.com/default.aspx?scid=kb;en-us;329332
and
http://support.microsoft.com/?kbid=899191

Here is an excellent explanation from David Adamson’s blog (http://www.dotnetjunkies.com/WebLog/daveadamson/archive/2005/11/22/133928.aspx).

Web Service Inheritance Error

Web Service Inheritance Error

We have a bunch of web services that are derived from a base web service class.

When running one of the derived web services, I got the following error:

“Server did not recognize the value of HTTP Header SOAPAction:”

The error was caused by not providing an explicit namespace for the derived web service class. The following attribute fixed the error:

[WebService(Namespace="someuri")]
Class DerivedWebService : BaseWebService
{

Enterprise Library WMI and Event Log Errors

EntLib WMI and Event Log Errors

(taken from http://blog.hishambaz.com/archive/2005/02/02/240.aspx)

“Immediately after installing Enterprise Library, you MUST install the instrumentation and performance counters.

start\All Programs\Microsoft p&p\Enterprise Library\Install Services

This will execute installutil on each of the assemblies and register the performance counters.  I would hope that in the next version of the installer, this option will be automatically executed after the solution is compiled.  Many of you are getting SecurityExceptions caused by not performing this required step.  Please let me know if this fixes the problem for you.

Disabling Instrumentation
I don't recommend it, but if you really want to you can also disable all of the WMI and performance counter instrumentation in Enterprise Library.  This requires a recompile of Enterprise Library, and you will lose valuable performance monitoring data.  

To make the change, Open up the EnterpriseLibrary.sln and modify the Configuration Properties\Build\Conditional Constants of the EnterpriseLibrary.Common project.  Remove the USEWMI;USEEVENTLOG;USEPERFORMANCECOUNTER constants.  By removing these constants, all of the internal Enterprise Library instrumentation will be disabled.  Recompile.”

I had SUCH a nightmare with the logging application block because my client required that the Web Service and Windows Service run under a user account that had lower permissions.

The problem was that the Logging block kept raising Performance counters and this kept slowing down the application because it was trying to write to the Event Log on errors. The above solution helped me to turn off WMI altogether and the application speed improved dramatically!!

InstallUtil

InstallUtil

Installutil seems to have stuffed up on my computer. It gives the following error whenever I try to start it, even without parameters:





















The Application log contains the following dump:
Faulting application installutil.exe, version 1.1.4322.573, faulting module codecoverage.dll, version 1.0.0.1, fault address 0x0000639b.
For more information, see Help and Support Center at http://go.microsoft.com/fwlink/events.asp.

SOLUTION

The problem was caused by the Code Coverage tool I was using (Coverage Eye.Net) (see http://www.gotdotnet.com/Community/UserSamples/Details.aspx?SampleGuid=881a36c6-6f45-4485-a94e-060130687151).

I renamed the code coverage directory and viola, all was well again.
 

 

Copyright © Shailen Sukul