Author Archive
Could not load file or assembly ‘apache fop.net’ or one of its dependencies
By George Zheng
When we deploy one of our web sites to a 64 bit web server, we get following error: “Could not load file or assembly ‘apachefop.net’ or one of its dependencies. An attempt was made to load a program with an incorrect format.”
This web site is using fop.net to generate the PDF for printing. After investigation, we realize the fop.net can’t run on IIS with 64-bit version of ASP.NET.
IIS 6.0 on a 64-bit hardware supports both the 32-bit version of ASP.NET and the 64-bit version of ASP.NET. However IIS 6.0 does not support running both modes at the same time on a 64-bit version of Windows. Here are the steps to run the 32-bit version of ASP.NET 2.0 on IIS:
- Click Start, click Run, type cmd, and then click OK.
- Type the following command to enable the 32-bit mode:
cscript %SYSTEMDRIVE%\inetpub\adminscripts\adsutil.vbs SET W3SVC/AppPools/Enable32bitAppOnWin64 1 - Type the following command to install the version of ASP.NET 2.0 (32-bit) and to install the script maps at the IIS root and under:
%SYSTEMROOT%\Microsoft.NET\Framework\v2.0.50727\aspnet_regiis.exe -i - Make sure that the status of ASP.NET version 2.0.50727 (32-bit) is set to Allowed in the Web service extension list in Internet Information Services Manager.
Useful Links
Process XML in C#.net
By George Zheng
XML has been used in a lot of places for transferring data because of its platform independence and its simple, text-based, self-describing format. It is a common requirement for preparing and consuming XML data. Microsoft provides several convenience tools to help developers deal with XML under .NET platform.
- System.Xml.XmlTextReader/System.Xml.XmlTextWriter
- System.Xml.Serialization.XMLSerializer
- System.Xml.Linq
XmlTextReader/XmlTextWriter
XmlDocument objects are easy to use for navigating the DOM copying, modifying, or inserting nodes. However, they can also use a large amount of memory to store the entire DOM of a large XML string in memory. Because of this, the XmlTextReader and XmlTextWriter classes can be used for stream based manipulation of an XML string.
Let’s say you have an XML as:
<?xml version=“1.0“ encoding=“utf-8“ ?>
<user id=“1“>
<firstname>George</firstname>
<lastname>Zheng</lastname>
</user>
Following code will read it into a user object.
User user = new User();
XmlTextReader reader = new XmlTextReader(“user.xml”);
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element)
{
if (reader.Name == “user”)
{
user.Id = Convert.ToInt32(reader.GetAttribute(“id”));
}
if (reader.Name == “firstname”)
{
user.Firstname = reader.ReadElementContentAsString();
}
if (reader.Name == “lastname”)
{
user.Lastname = reader.ReadElementContentAsString();
}
}
}
With XmlTextWriter, following code will generate XML string:
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
XmlTextWriter writer = new XmlTextWriter(sw);
writer.WriteStartElement(“user”);
writer.WriteAttributeString(“id”, user.Id.ToString());
writer.WriteElementString(“firstname”, user.Firstname);
writer.WriteElementString(“lastname”, user.Lastname);
writer.WriteEndElement();
return sb.ToString();
XMLSerializer
If you don’t want to deal with the XML element by element, .NET provides an alternative approach to convert object instance to XML and read the data back – XML Serialization. This is more convenience for a complex object.
TextReader tr = new StringReader(xml);
XmlSerializer s = new XmlSerializer(typeof(User));
User user = (User)s.Deserialize(tr);
Following code can be used to serialize the object:
XmlSerializer s = new XmlSerializer(typeof(User));
TextWriter writer = new StringWriter();
s.Serialize(writer, user);
writer.Flush();
string xml = writer.ToString();
writer.Close();
The object can be a complex object like:
public class User
{
[XmlAttribute("id")]
public int Id { get; set; }
[XmlElement("firstname")]
public string Firstname { get; set; }
[XmlElement("lastname")]
public string Lastname { get; set; }
[XmlArray("projects")]
[XmlArrayItem("project", typeof(Project))]
public List<Project> Projects { get; set; }
}
public class Project
{
[XmlAttribute("id")]
public int Id { get; set; }
[XmlElement("name")]
public string Name { get; set; }
}
As you can see, serializer attributes can be used to specify how the object’s properties map to XML entities. I’m not going to discuss these attributes here. Details can be found from Useful Links below.
LINQ
In some case, convert the whole XML may not be a good idea. Linq provides a convenience approach to query a complex XML.
Here is the example account feed response from Google Analytics API
<?xml version=‘1.0‘ encoding=‘UTF-8‘?>
<feed xmlns=‘http://www.w3.org/2005/Atom‘ xmlns:openSearch=‘http://a9.com/-/spec/opensearchrss/1.0/‘ xmlns:dxp=‘http://schemas.google.com/analytics/2009‘>
<id>http://www.google.com/analytics/feeds/accounts/abc@test.com</id>
<updated>2009-06-25T03:55:22.000-07:00</updated>
<title type=‘text‘>Profile list for abc@test.com</title>
<link rel=‘self‘ type=‘application/atom+xml‘ href=‘http://www.google.com/analytics/feeds/accounts/default‘/>
<author>
<name>Google Analytics</name>
</author>
<generator version=‘1.0‘>Google Analytics</generator>
<openSearch:totalResults>12</openSearch:totalResults>
<openSearch:startIndex>1</openSearch:startIndex>
<openSearch:itemsPerPage>12</openSearch:itemsPerPage>
<entry>
<id>http://www.google.com/analytics/feeds/accounts/ga:1174</id>
<updated>2009-06-25T03:55:22.000-07:00</updated>
<title type=‘text‘>www.googlestore.com</title>
<link rel=‘alternate‘ type=‘text/html‘ href=‘http://www.google.com/analytics‘/>
<dxp:tableId>ga:1174</dxp:tableId>
<dxp:property name=‘ga:accountId‘ value=‘30481‘/>
<dxp:property name=‘ga:accountName‘ value=‘Google Store‘/>
<dxp:property name=‘ga:profileId‘ value=‘1174‘/>
<dxp:property name=‘ga:webPropertyId‘ value=‘UA-30481-1‘/>
<dxp:property name=‘ga:currency‘ value=‘USD‘/>
<dxp:property name=‘ga:timezone‘ value=‘America/Los_Angeles‘/>
</entry>
<entry>
<id>http://www.google.com/analytics/feeds/accounts/ga:6284812</id>
<updated>2009-01-06T17:39:33.000-08:00</updated>
<title type=‘text‘>www.googlestore.com (Test Team)</title>
<link rel=‘alternate‘ type=‘text/html‘ href=‘http://www.google.com/analytics‘/>
<dxp:tableId>ga:6284812</dxp:tableId>
<dxp:property name=‘ga:accountId‘ value=‘30481‘/>
<dxp:property name=‘ga:accountName‘ value=‘Google Store‘/>
<dxp:property name=‘ga:profileId‘ value=‘6284812‘/>
<dxp:property name=‘ga:webPropertyId‘ value=‘UA-30481-1‘/>
<dxp:property name=‘ga:currency‘ value=‘USD‘/>
<dxp:property name=‘ga:timezone‘ value=‘America/Los_Angeles‘/>
</entry>
</feed>
With following code, you will get ID, Title and AccountName for each entry.
XDocument doc = XDocument.Parse(xml);
XNamespace dxpSpace = doc.Root.GetNamespaceOfPrefix(“dxp”);
XNamespace defaultSpace = doc.Root.GetDefaultNamespace();
IEnumerable<Account> entries =
from en in doc.Root.Descendants(defaultSpace + “entry”)
select new Account
{
ID = en.Element(defaultSpace + “id”).Value,
Title = en.Element(defaultSpace + “title”).Value,
AccountName =
en.Elements(dxpSpace + “property”).Where(
xe => xe.Attribute(“name”).Value == “ga:accountName”).First().
Attribute(“value”).Value
};
Useful Links
Insert XML Nodes Using XmlTextReader and XmlTextWriter
Using the XmlSerializer Attributes
Added Google Analytics Reader for .NET
Download source code
Maintaining the Active Tab in TabContainer Control
by George Zheng
Problem
AJAX Control Toolkit has a neat control – TabContainer, to allow you create tabs on your web page easily. However, one problem with it is that when user refreshes the page, it defaults back to the first tab. This will cause user confusion if you have pagination in third tab let’s say. Every time, when user click a page number on third tab. Page get refreshed and it should show third tab, not the first tab.
Solution
The reason refreshed page always show the first tab is, in fact, one of the benefits of the tab control – switching between tabs doesn’t cause a post back. This is a pure client activity. When server prepares the page, it has no idea which tab is the active tab on client side. So server will set first tab as active tab by default.
Read the rest of this entry »