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

 

Tuesday, May 08, 2007

TO Get the App.Config file from another Assembly

public

{

 

 

fName +=

 

xDoc.Load(fName);

 

 

 

}

static string GetAppConfig(string key)string fName = Assembly.GetExecutingAssembly().Location.Substring(0,Assembly.GetExecutingAssembly().Location.LastIndexOf("\\"));"\\MyApp.exe.config";XmlDocument xDoc = new XmlDocument();XmlNode xNode = xDoc.SelectSingleNode("/configuration/appSettings");XmlNode keyNode = xNode.SelectSingleNode(string.Format("//add[@key='{0}']", key));return keyNode.Attributes["value"].Value;

Monday, November 27, 2006

CData sections not appearing with XML Transform ( XSLT ) ( applies to XslCompiledTransform class )

I have noticed an anamoly with doing XML Transformations in .Net. If the XSLT marks specific sections as CDATA, the output seems to missing that.  

Example:

XSLT:

<xsl:output method="xml" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" cdata-section-elements="EMPLAST EMPFIRST"/>

 

We would expect output to be of the format:

<Employee>

<EMPLAST><![CDATA[John]]></EMPLAST>

and so on...

</Employee>

However, the standard XSLT transformation does not output the CDATA bit, when done through .Net, so what you get is

<EMPLAST>John</EMPLAST>

This because the default example on MSDN uses an XmlWriter that will, guess what, write the xml text as, well ... xml and hence ignore the CDATA sections!! To properly write out the transformed text, use a TextWriter and all will be well again....

A complete example is given below:

using System;

using System.Collections.Generic;

using System.IO;

using System.Text;

using System.Xml;

using System.Xml.XPath;

using System.Xml.Xsl;

using System.Xml.Schema;

....

public static string TransformXml(string xml, string xsl)

{

/* Load the xml into an XmlReader*/

XmlReader rXml = CreateXmlReaderFromString(xml);

/* Load the xsl into an XmlReader*/

XmlReader rXsl = CreateXmlReaderFromString(xsl);

Stream oStream = new MemoryStream();

using (TextWriter tr = new StreamWriter(oStream, outputEncoding))

{

/* Create a XslCompiledTransform class to do the transformation */

XslCompiledTransform trans = new XslCompiledTransform();

trans.Load(rXsl);

trans.Transform(rXml, null, tr);

// declare a buffer to hold the contents of the stream

byte[] arrBuffer = new byte[oStream.Length];

// we have to set the position to 0 so that it moves the pointer back to

// the start of where we want to read

oStream.Position = 0;

// read from the stream to our buffer

int iLastLength = oStream.Read(arrBuffer, 0, (int)oStream.Length);

// have we read anything

if (iLastLength > 0)

{

// get our transformed xml using our encoder and the buffer

xml = outputEncoding.GetString(arrBuffer);

}

else

{

xml = string.Empty;

}

}

return xml;

}

private static XmlTextReader CreateXmlReaderFromString(string XML)

{

XmlTextReader xmlReader = null;

StringReader sReader = new StringReader(XML);

xmlReader = new XmlTextReader(sReader);

return xmlReader;

}

Friday, November 24, 2006

Helper code to extract embedded resource from project into Assembly

The following is a handy piece of code for extracing an embedded stream of characters from your assembly and saving to a text file.

1. Set the resource to Embedded.

2. Copy the following piece of code:

public static void WriteResourceToFile(string resourceName, string fileName)

{

      using (Stream s = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))

      {

         if (s != null)

         {

               byte[] buffer = new byte[s.Length];

               char[] sb = new char[s.Length];

               s.Read(buffer, 0, (int)(s.Length));

               /* convert the byte into ASCII text */

               for (int i = 0; i <= buffer.Length - 1; i++)

               {

                  sb[i] = (char)buffer[i];

               }

               using (StreamWriter sw = new StreamWriter(fileName))

               {

                  sw.Write(sb);

                  sw.Flush();

               }

      }   

   }

}

Wednesday, October 11, 2006

How to get the target directory (TARGETDIR) in a customer windows installer

I hope the following will save you some time when dealing with custom windows installers.

If you want to access the installation path in your customer installer class, your first instinct might be to use a [TARGETDIR] or [INSTALLDIR]

as a custom action (for example /DIR=[TARGETDIR]) and attempt to access that in your custom installer class (for example. dir = Context.Parameters[“DIR”]).  This will fail, since the TARGET is populated AFTER the custom action is executed.

I printed out the contents of the Context's parameter collection, that is available to the Custom Action, as shown below:

Writing the contents of the Installation Context
------------------------------------------------------------

Key: [dir] Value:
Key: [action] Value: install
Key: [installtype] Value: notransaction
Key: [assemblypath] Value: C:\Program Files\Company\Company Product\CompanyProduct.exe
Key: [logfile] Value:
------------------------------------------------------------

As seen above, you do have access to the [AssemblyPath] in the Custom Action and by stripping of the product.exe filename,

you can get the directory.

Here is a simple function that will achieve this:

private string StripDir(string fullPath)

{

string retValue = default(string);

if (fullPath != null && fullPath != string.Empty && fullPath != default(string))

{

retValue = fullPath.Substring(0, fullPath.LastIndexOf(@"\"));

}

return retValue;

}

So the final code will look like this:

string installDir = StripDir(Context.Parameters[“AssemblyPath“]);

Thursday, September 07, 2006

How to use FOR XML to return an Xml Document with a root element

The query below shows how to create an XML document using FOR XML from a table (based on Sql Server 2000). To start with, run the sql script further below to create the sample table, and populate it with some data. Once the select script is run, data will be returned in the form:

<Employees>

<Employee>

<field1></field1>

...

</Employee>

</Employees>

Query

select 1 as Tag,
 NULL as Parent,
 NULL as [Employees!1!Employee!xml],
 NULL as [Employee!2!OfficerId!xml],
 NULL as [Employee!2!GivenName!xml],
 NULL as [Employee!2!Surname!xml],
 NULL as [Employee!2!LoginCode!xml],
 NULL as [Employee!2!IsActive!xml]

UNION ALL

select 2,
 1,
 NULL,
 Officer_ID,
 Officer_Given_Names,
 Officer_Surname,
 CRTS_Login_Code,
 Is_Active
from  staging.dbo.tbl_Officer
for xml explicit

Table

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[tbl_Officer]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[tbl_Officer]
GO

CREATE TABLE [dbo].[tbl_Officer] (
 [Officer_ID] [int] NOT NULL ,
 [Officer_Given_Names] [varchar] (20) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
 [Officer_Surname] [varchar] (20) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
 [CRTS_Login_Code] [varchar] (20) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
 [Is_Active] [tinyint] NOT NULL
) ON [PRIMARY]
GO

 

Sunday, July 30, 2006

Things to watch out for when implementing a custom role provider

I recently implemented a custom role provider for an asp.net project and discovered an interesting point.

I had to instantiate a role business component in the custom provider class like so:

public class MyRoleProvider : RoleProvider

{

BLRole blRole = null;

public MyRoleProvider()

{

blRole = new BLRole();

}

All I could see on at runtime was:

Parser Error Message: Exception has been thrown by the target of an invocation.

I moved the instantiation code into the Initialize block and hey pretso, the IDE now told what was causing my error, ie the precached version of my business logic component was throwing the error!

public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)

{

// Verify that config isn't null

if (config == null)

throw new ArgumentNullException("config");

// instantiate the role business component

blRole = new BLRole();

Tuesday, June 27, 2006

Unable to get installer types

I got the above error message when uninstalling a Windows Service setup from the Add/Remove option.

If you ever get an error message like above, then one or dependent assemblies for your installed application may be missing. Try to locate and install the dependent assemblies manually and then Remove the project using the Add/Remove option.

Tuesday, June 13, 2006

REST style urls not working in IIS

HTTP GET/POST are disabled by default on web servers in the new .NET 1.1 which could make creating REST-type web services more difficult. The error message you get is:

Request format is unrecognized.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
The fix is to enable GET/POST. See http://support.microsoft.com/default.aspx?scid=kb;en-us;819267 to enable it.

Friday, May 26, 2006

Script to search in Stored Proces

Script to search in stored procs

select  upper(SysObjects.Name),SysComments.Text
from  SysObjects, SysComments  
where  SysObjects.type='P'
and (SysObjects.ID = SysComments.ID)
and SysComments.Text like '%SearchString%'

Monday, May 08, 2006

Sql Server Stored Procedure oddity

I ran across this weird problem while debugging a stored procedure in Sql Server 2000.

Here's a sample stored procedure:

drop procedure p1
go
create procedure p1
as
 
create table #t1(
 col1 int identity(1,1),
 col2 datetime,
 col3 int
)
 
select *
from #t1

return

update #t1
set col3 = col2

return

Ok, notice that I have a return statement after the first select. That is my exit point for now because I am debugging so I am not interested in the section after that. Also notice that the update statement will throw an error like so:

Disallowed implicit conversion from data type datetime to data type int, table 'tempdb.dbo.#t1_________________________________________________________________________________________________________________000100004066', column 'col3'. Use the CONVERT function to run this query.

Now, logically if I run my stored procedure, I know that I will return after the first select statement and I should not get a runtime error at all, but what really happens, is that executing the stored proc throws an error at runtime on a block of code that will never be run! Go figure!

The obvious solution is to either comment out the offending code, or to fix it first before running the SP.

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.

/// &lt;summary&gt;
          /// Serialize the given object into a string
          /// &lt;/summary&gt;
          /// &lt;param name="o"&gt;&lt;/param&gt;
          /// &lt;returns&gt;&lt;/returns&gt;
          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 &gt; 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 &lt;destinationfolder&gt;\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
{
 

 

Copyright © Shailen Sukul