Asp.Net url rewriting and postbacks
JK | Mon, 2009/03/09 - 22:47
When you use url rewriting in combination with asp.net, postbacks tend not to go to the rewritten url but to the real url, which is then shown in the browser. .NET 3.5 SP1 includes new functionality on the Form-object which makes it easy to change that behaviour.
Given a normal serverside form:
<form runat="server" id="form1"></form>
all you have to do is add a single line of code to the Page_Load event handler:
form1.Action = Request.RawUrl;
Request.RawUrl contains the rewritten url. Setting the Action property on the form to that value makes the form post back to the rewritten url.
Merging collections
JK | Thu, 2008/12/04 - 14:44
ICollection does not offer a method for merging two collections. As merging collections was exactly what I needed, I wrote a bit of code for it. An extension method seemed to offer the most elegant solution:
public static ICollection<T> Add<T>(this IList<T> self, IList<T> input)
{
foreach (T item in input)
{
self.Add(item);
}
return self;
}
Because I've overloaded the Add method, this will now work:
IList<string> list1 = new IList<string>(); IList<string> list2 = new IList<string>(); string name = 'J2'; list1.Add(list2); list1.Add(name);
For the license to this code, see http://creativecommons.org/licenses/by/3.0/
XmlDocument improved
JK | Fri, 2008/08/29 - 22:10
On a nice summerday I set out to write a command line tool that would change values in xml documents. You would pass it a document name, an xpath query, and a value, and it would update the element found in the document through the query, and set its content to the new value.
So I created this tool, and all was fine. That is, until I encountered a document that contained namespaces. I created a namespace manager, figured out how to dynamically get the namespace information from the xml document, and now I could use the namespaces in the xpath expression.
Not an impressive feat, but it left me wondering why System.Xml.XmlDocument doesn't do the "heavy" lifting for us. I decided it should, and you'll find my fix after the break.
using System;
namespace J2.Xml
{
/* created by http://j2solutions.nl - 20080824
* XmlDocument that automatically loads all namespaces.
* The default namespace, if present, gets the prefix 'default'.
* license: http://creativecommons.org/licenses/by/3.0/
*/
public class XmlDocument : System.Xml.XmlDocument
{
private const string DEFAULT_DEFAULT_NS_PREFIX = "default";
System.Xml.XmlNamespaceManager nsmgr = null;
public string DefaultNsPrefix { get; set; }
public XmlDocument()
{
DefaultNsPrefix = DEFAULT_DEFAULT_NS_PREFIX;
}
#region Load
public new void Load(string filename)
{
base.Load(filename);
nsmgr = CreateNamespaceMgr(DefaultNsPrefix);
}
public new void Load(System.IO.Stream inStream)
{
base.Load(inStream);
nsmgr = CreateNamespaceMgr(DefaultNsPrefix);
}
public new void Load(System.IO.TextReader txtReader)
{
base.Load(txtReader);
nsmgr = CreateNamespaceMgr(DefaultNsPrefix);
}
public new void Load(System.Xml.XmlReader reader)
{
base.Load(reader);
nsmgr = CreateNamespaceMgr(DefaultNsPrefix);
}
#endregion
#region LoadXml
public new void LoadXml(string xml)
{
base.LoadXml(xml);
nsmgr = CreateNamespaceMgr(DefaultNsPrefix);
}
#endregion
#region SelectSingleNode
public new System.Xml.XmlNode SelectSingleNode(string xpath)
{
return (null != nsmgr) ? base.SelectSingleNode(xpath, nsmgr) : base.SelectSingleNode(xpath);
}
private new System.Xml.XmlNode SelectSingleNode(string xpath, System.Xml.XmlNamespaceManager nsmgr)
{
throw new NotSupportedException();
}
#endregion
#region SelectNodes
public new System.Xml.XmlNodeList SelectNodes(string xpath)
{
return (null != nsmgr) ? base.SelectNodes(xpath, nsmgr) : base.SelectNodes(xpath);
}
private new System.Xml.XmlNodeList SelectNodes(string xpath, System.Xml.XmlNamespaceManager nsmgr)
{
throw new NotSupportedException();
}
#endregion
private System.Xml.XmlNamespaceManager CreateNamespaceMgr(string prefixForDefaultNS)
{
System.Collections.Specialized.NameValueCollection namespaces = GetNamespaces(base.DocumentElement, prefixForDefaultNS);
System.Xml.XmlNamespaceManager namespaceMgr = null;
if (0 != namespaces.Count)
{
namespaceMgr = new System.Xml.XmlNamespaceManager(base.NameTable);
for (int i = 0; i < namespaces.Count; i++)
{
namespaceMgr.AddNamespace(namespaces.Keys[i], namespaces[i]);
}
}
return namespaceMgr;
}
private System.Collections.Specialized.NameValueCollection GetNamespaces(System.Xml.XmlElement doc, string prefixForDefaultNS)
{
System.Collections.Specialized.NameValueCollection ret = new System.Collections.Specialized.NameValueCollection();
foreach (System.Xml.XmlAttribute attr in doc.Attributes)
{
if (-1 < attr.Name.IndexOf("xmlns"))
{
// xmlns=<uri> is the default namespace, xmlns:<name>=<uri> is a named namespace
string key = (-1 < attr.Name.IndexOf("xmlns:")) ? attr.Name.Replace("xmlns:", "") : prefixForDefaultNS;
ret.Add(key, attr.Value);
}
}
return ret;
}
}
}
For the license to this code, see http://creativecommons.org/licenses/by/3.0/
