<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>typeof(Blog); &#187; coding problems</title>
	<atom:link href="http://blog.reveille.org.uk/category/coding-problems/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.reveille.org.uk</link>
	<description>.net development thoughts and others</description>
	<lastBuildDate>Sat, 11 Sep 2010 15:48:08 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.5</generator>
		<item>
		<title>A generic WCF service client</title>
		<link>http://blog.reveille.org.uk/2010/03/a-generic-wcf-service-client/</link>
		<comments>http://blog.reveille.org.uk/2010/03/a-generic-wcf-service-client/#comments</comments>
		<pubDate>Tue, 16 Mar 2010 14:18:36 +0000</pubDate>
		<dc:creator>Graham Clark</dc:creator>
				<category><![CDATA[coding problems]]></category>
		<category><![CDATA[wcf]]></category>

		<guid isPermaLink="false">http://blog.reveille.org.uk/?p=89</guid>
		<description><![CDATA[Once you&#8217;ve used svcutil to create proxy classes for a service (or created a Service Reference in Visual Studio), it&#8217;s often a bit of a pain to write the wrapper code that needs to instantiate the client, call the service operation, and close or abort the client as appropriate. So I wrote a generic ServiceClient [...]]]></description>
			<content:encoded><![CDATA[<p>Once you&#8217;ve used <code>svcutil</code> to create proxy classes for a service (or created a Service Reference in Visual Studio), it&#8217;s often a bit of a pain to write the wrapper code that needs to instantiate the client, call the service operation, and close or abort the client as appropriate. So I wrote a generic <code>ServiceClient</code> class which will hopefully help to eliminate some boiler-plate code &#8211; it&#8217;s shown below.</p>
<pre class="brush: csharp; collapse: true; light: false; title: ; toolbar: true; wrap-lines: true;">
/// &lt;summary&gt;
/// A WCF service client.
/// &lt;/summary&gt;
/// &lt;typeparam name=&quot;TContract&quot;&gt;The type of the service contract.&lt;/typeparam&gt;
internal class ServiceClient&lt;TContract&gt; : IDisposable
	where TContract : class
{
	/// &lt;summary&gt;
	/// The service client object.
	/// &lt;/summary&gt;
	private TContract client;

	/// &lt;summary&gt;
	/// Initializes a new instance of the ServiceClient class.
	/// &lt;/summary&gt;
	/// &lt;param name=&quot;endpointName&quot;&gt;The name of the endpoint to use.&lt;/param&gt;
	public ServiceClient(string endpointName)
	{
		ChannelFactory&lt;TContract&gt; f = new ChannelFactory&lt;TContract&gt;(endpointName);
		this.client = f.CreateChannel();
	}

	/// &lt;summary&gt;
	/// Calls an operation on the service.
	/// &lt;/summary&gt;
	/// &lt;typeparam name=&quot;TResult&quot;&gt;The type of the object returned by the service operation.&lt;/typeparam&gt;
	/// &lt;param name=&quot;operation&quot;&gt;The operation to call.&lt;/param&gt;
	/// &lt;returns&gt;The results of the service operation.&lt;/returns&gt;
	public TResult ServiceOperation&lt;TResult&gt;(Func&lt;TContract, TResult&gt; operation)
	{
		return operation(this.client);
	}

	/// &lt;summary&gt;
	/// Calls an operation on the service.
	/// &lt;/summary&gt;
	/// &lt;param name=&quot;operation&quot;&gt;The operation to call.&lt;/param&gt;
	public void ServiceOperation(Action&lt;TContract&gt; operation)
	{
		operation(this.client);
	}

	/// &lt;summary&gt;
	/// Disposes this object.
	/// &lt;/summary&gt;
	public void Dispose()
	{
		try
		{
			if (this.client != null)
			{
				IClientChannel channel = this.client as IClientChannel;
				if (channel.State == CommunicationState.Faulted)
				{
					channel.Abort();
				}
				else
				{
					channel.Close();
				}
			}
		}
		finally
		{
			this.client = null;
			GC.SuppressFinalize(this);
		}
	}
}
</pre>
<p>With this class, you can call an operation <code>SaveEmployee</code> on a service with an <code>IEmployeeService</code> interface like this:</p>
<pre class="brush: csharp; title: ;">
using (var client = new ServiceClient&lt;IEmployeeService&gt;(&quot;EmployeeEndpoint&quot;))
{
	var response = client.ServiceOperation&lt;EmployeeResponse&gt;(
		c =&gt; c.SaveEmployee(request));
}
</pre>
<p>Wrapping the call in a <code>using</code> block means the client object is correctly closed and disposed, using the <code>IDisposable</code> interface. And if you&#8217;re calling an operation that doesn&#8217;t return anything, you can use the overload of <code>ServiceOperation</code> that takes in an <code>Action</code>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.reveille.org.uk/2010/03/a-generic-wcf-service-client/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using Extension Methods for WCF Service Translators</title>
		<link>http://blog.reveille.org.uk/2010/03/extension-methods-for-wcf-service-translators/</link>
		<comments>http://blog.reveille.org.uk/2010/03/extension-methods-for-wcf-service-translators/#comments</comments>
		<pubDate>Wed, 10 Mar 2010 12:19:04 +0000</pubDate>
		<dc:creator>Graham Clark</dc:creator>
				<category><![CDATA[coding problems]]></category>
		<category><![CDATA[extension methods]]></category>
		<category><![CDATA[wcf]]></category>

		<guid isPermaLink="false">http://blog.reveille.org.uk/?p=78</guid>
		<description><![CDATA[A common task when consuming a WCF service is translating your business objects into the proxy objects used in a service operation call. As an example, say you&#8217;ve got a Person class, and you&#8217;re calling a WCF service operation called SaveEmployee(). When creating a reference to this service, the svcutil program will have created some [...]]]></description>
			<content:encoded><![CDATA[<p>A common task when consuming a WCF service is translating your business objects into the proxy objects used in a service operation call. As an example, say you&#8217;ve got a <code>Person</code> class, and you&#8217;re calling a WCF service operation called <code>SaveEmployee()</code>. When creating a reference to this service, the <a href="http://msdn.microsoft.com/en-us/library/aa347733.aspx"><code>svcutil</code></a> program will have created some proxy classes. To call the <code>SaveEmployee()</code> operation, you&#8217;ll need to translate your local <code>Person</code> object into the proxy object. Extension methods provide a nice clear way of doing this.</p>
<p>So, the local Person business class will be something like this:</p>
<pre class="brush: csharp; title: ;">
public class Person
{
    public string Forename { get; set; }

    public string Surname { get; set; }

    public int Age { get; set; }
}
</pre>
<p>We want to call a WCF service called <code>EmployeeService</code>, which has an operation <code>SaveEmployee()</code>. This operation takes a person to save as a parameter. The type of this parameter is <code>Employee</code>, which <code>svcutil</code> has created for us in the service proxy. This may look something like this:</p>
<pre class="brush: csharp; title: ;">
internal partial class Employee :
    object, System.Runtime.Serialization.IExtensibleDataObject
{
    private string FirstNameField;
    private string LastNameField;
    private int AgeField;

    [System.Runtime.Serialization.DataMemeberAttribute()]
    internal string FirstName
    {
        get { return this.FirstNameField; }
        set { this.FirstNameField = value; }
    }

    [System.Runtime.Serialization.DataMemeberAttribute()]
    internal string LastName
    {
        get { return this.LastNameField; }
        set { this.LastNameField = value; }
    }

    [System.Runtime.Serialization.DataMemeberAttribute()]
    internal int Age
    {
        get { return this.AgeField; }
        set { this.AgeField = value; }
    }
}
</pre>
<p>As the service operation <code>SaveEmployee</code> needs an <code>Employee</code> and we have a <code>Person</code>, we need to translate from the latter to the former. An extension object can do this for us nicely:</p>
<pre class="brush: csharp; title: ;">
internal static class PersonTranslator
{
    public static Employee TranslateToEmployee(this Person person)
    {
        return new Employee()
        {
            FirstName = person.Forename,
            LastName = person.Surname,
            Age = person.Age
        };
    }
}
</pre>
<p>Now the call to the service operation is nice and clear:</p>
<pre class="brush: csharp; title: ;">
public SaveEmployee(Person person)
{
    var client = new EmployeeServiceClient();
    client.SaveEmployee(person.TranslateToEmployee());
    client.Close();
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.reveille.org.uk/2010/03/extension-methods-for-wcf-service-translators/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using Impersonation and Delegation in ASP.Net &#8211; part 2</title>
		<link>http://blog.reveille.org.uk/2010/01/asp-net-impersonation-delegation-2/</link>
		<comments>http://blog.reveille.org.uk/2010/01/asp-net-impersonation-delegation-2/#comments</comments>
		<pubDate>Thu, 28 Jan 2010 09:31:12 +0000</pubDate>
		<dc:creator>Graham Clark</dc:creator>
				<category><![CDATA[coding problems]]></category>
		<category><![CDATA[hardware pain]]></category>
		<category><![CDATA[asp.net]]></category>
		<category><![CDATA[delegation]]></category>
		<category><![CDATA[iis]]></category>
		<category><![CDATA[impersonation]]></category>

		<guid isPermaLink="false">http://blog.reveille.org.uk/?p=68</guid>
		<description><![CDATA[In a previous post I explained how to configure Impersonation and Delegation in ASP.Net (for the Windows Server 2008 and IIS7 case at least). Turns out there&#8217;s one extra little step required. After all that setup, I could use Internet Explorer to browse to the site fine &#8211; integrated Windows Authentication would let me in. [...]]]></description>
			<content:encoded><![CDATA[<p>In a <a title="part 1" href="http://blog.reveille.org.uk/2010/01/asp-net-impersonation-delegation/">previous post</a> I explained how to configure Impersonation and Delegation in ASP.Net (for the Windows Server 2008 and IIS7 case at least). Turns out there&#8217;s one extra little step required.</p>
<p>After all that setup, I could use Internet Explorer to browse to the site fine &#8211; integrated Windows Authentication would let me in. However, as the DNS had yet to be set up, and the web server and the website had the same IP address, I was browsing using the <em>machine name</em>, e.g. <code>http://machine.domain/website</code> instead of <code>http://dnsname.co.uk/website</code>.</p>
<p>When the DNS was set up and I tried to browse to the website, I got a Windows user name &amp; password box popping up. After 3 tries I was denied access (a 401 error). Just changing the DNS name to the machine name in the location bar let me in, even though they were both the same IP address!</p>
<p>Using <a title="Fiddler" href="http://www.fiddler2.com/fiddler2/">Fiddler</a>, I could see the initial client GET request, and the server&#8217;s 401 challenge response, including a WWW-Authenticate header set to “Negotiate”. This occurred in both cases (browsing to the DNS name and to the machine name). However, the client response to this challenge was different in each case. The Negotiate token the client sent to the DNS name was much shorter than the one sent to the machine name. Clearly something was telling the client not to send the proper Kerberos authentication token to the DNS name.</p>
<p>Just looking at the HTTP traffic was not enough here &#8211; for cases like these a lower-level tool like Microsoft&#8217;s <a title="NetMon" href="http://www.microsoft.com/downloads/details.aspx?FamilyID=983b941d-06cb-4658-b7f6-3088333d062f&amp;displaylang=en">Network Monitor</a> is required, or <a title="Wireshark" href="http://www.wireshark.org/">Wireshark</a> if you&#8217;re feeling hardcore. This showed that the client was encountering a Kerberos error. A bit of searching around this and&#8230;</p>
<p>A magic SPN setting will solve this, all explained in a handy <a title="Kerberos &quot;technical supplement&quot;" href="http://msdn.microsoft.com/en-us/library/aa480609.aspx">MSDN article</a>. You will need to run this command (I ran it on the web server itself, however this may not be necessary):</p>
<p><code>setspn -A HTTP/[dns name of the site] [machine name]</code></p>
<p>Then a reboot of the web server, and a few hours&#8217; wait for the settings to propagate around the domain. This will allow clients to send complete Kerberos authentication tokens to the website. Problem solved!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.reveille.org.uk/2010/01/asp-net-impersonation-delegation-2/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>WCF Configuration &#8211; Referencing certificates with long subjects</title>
		<link>http://blog.reveille.org.uk/2010/01/wcf-configuration-certificates/</link>
		<comments>http://blog.reveille.org.uk/2010/01/wcf-configuration-certificates/#comments</comments>
		<pubDate>Fri, 22 Jan 2010 11:09:20 +0000</pubDate>
		<dc:creator>Graham Clark</dc:creator>
				<category><![CDATA[coding problems]]></category>
		<category><![CDATA[certificates]]></category>
		<category><![CDATA[wcf]]></category>

		<guid isPermaLink="false">http://blog.reveille.org.uk/?p=63</guid>
		<description><![CDATA[I was trying to set up a WCF net-tcp service on a test environment, but kept getting an error saying the certificate could not be found. The problem was down to a slight difference between the test certificates we were using locally, and the certificate we were given for the test environment. We&#8217;re using FindBySubjectDistinguishedName [...]]]></description>
			<content:encoded><![CDATA[<p>I was trying to set up a WCF net-tcp service on a test environment, but kept getting an error saying the certificate could not be found. The problem was down to a slight difference between the test certificates we were using locally, and the certificate we were given for the test environment. We&#8217;re using FindBySubjectDistinguishedName in the config.</p>
<p>The test certificate&#8217;s subject looked like this:</p>
<p><code>CN = TestCertName</code></p>
<p>Whereas the environment certificate&#8217;s subject looked like:</p>
<p><code>CN = CertName<br />
OU = Company Ltd.<br />
O = Company<br />
L = Town<br />
S = County<br />
C = Country Code</code></p>
<p>All the examples I&#8217;ve seen just cover certificates with the <code>CN</code> part. This is straightforward to reference in the WCF config:</p>
<pre class="brush: xml; light: true; title: ;">
&lt;serviceCredentials&gt;
   &lt;serviceCertificate
            storeLocation=&quot;LocalMachine&quot;
            storeName=&quot;My&quot;
            findValue=&quot;CN=TestCertName&quot;
            x509FindType=&quot;FindBySubjectDistinguishedName&quot; /&gt;
&lt;/serviceCredentials&gt;
</pre>
<p>However, when the certificate subject has multiple parts (i.e. more than just <code>CN</code>), you need to put all of them in the <code>findValue</code> attribute. But how to separate them? I tried several characters &#8211; space, comma, semicolon, colon &#8211; none worked. The certificate could not be found! Finally I noticed that in the top part of the certificate&#8217;s properties window, the values are separated by a comma <em>and</em> a space. Unbelievably, this also applies to the config! How intuitive. So for the &#8220;CertName&#8221; certificate above, here&#8217;s how to reference it in the WCF config:</p>
<pre class="brush: xml; light: true; title: ;">
&lt;serviceCredentials&gt;
   &lt;serviceCertificate
            storeLocation=&quot;LocalMachine&quot;
            storeName=&quot;My&quot;
            findValue=&quot;CN=TestCertName, OU=Company Ltd., O=Company, L=Town, S=County, C=Country Code&quot;
            x509FindType=&quot;FindBySubjectDistinguishedName&quot; /&gt;
&lt;/serviceCredentials&gt;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.reveille.org.uk/2010/01/wcf-configuration-certificates/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Using Impersonation and Delegation in ASP.Net</title>
		<link>http://blog.reveille.org.uk/2010/01/asp-net-impersonation-delegation/</link>
		<comments>http://blog.reveille.org.uk/2010/01/asp-net-impersonation-delegation/#comments</comments>
		<pubDate>Thu, 21 Jan 2010 14:04:04 +0000</pubDate>
		<dc:creator>Graham Clark</dc:creator>
				<category><![CDATA[coding problems]]></category>
		<category><![CDATA[hardware pain]]></category>
		<category><![CDATA[active directory]]></category>
		<category><![CDATA[asp.net]]></category>
		<category><![CDATA[delegation]]></category>
		<category><![CDATA[iis]]></category>
		<category><![CDATA[impersonation]]></category>

		<guid isPermaLink="false">http://blog.reveille.org.uk/?p=53</guid>
		<description><![CDATA[ASP.Net exposes a handy Windows feature called Impersonation. This lets an application access local resources using the credentials of the current user. Local resources is important &#8211; if you want to access some files, then that&#8217;s fine, but if you want to access a remote database, you&#8217;re going to need Delegation as well. It&#8217;s fairly [...]]]></description>
			<content:encoded><![CDATA[<p>ASP.Net exposes a handy Windows feature called <a title="Microsoft" href="http://msdn.microsoft.com/en-us/library/aa376391(VS.85).aspx">Impersonation</a>. This lets an application access local resources using the credentials of the current user. <strong>Local</strong> resources is important &#8211; if you want to access some files, then that&#8217;s fine, but if you want to access a remote database, you&#8217;re going to need Delegation as well.</p>
<p>It&#8217;s fairly simple to set this up once you know what needs doing. Getting to that stage wasn&#8217;t the most fun I&#8217;ve ever had &#8211; the MSDN articles on the subject are useful, but they seem to want to cover at least 3 topics at a time, which can be a little confusing.</p>
<p>The scenario was this: an intranet web application would authenticate users using Windows Authentication, granting access based on their Active Directory roles. The application would access the back-end SQL Server database using Integrated Security, with the credentials of the current user.  This gives two main advantages &#8211; you don&#8217;t have to setup or administer a separate account or accounts for the database, and auditing via SQL triggers is easy. However, this approach is only really suited to an intranet scenario, as database connection pools are used on a per-user basis. Too many users and the database will not be happy.</p>
<p>The setup is in four parts.</p>
<h2>ASP.Net</h2>
<p>Under the <code>&lt;system.web&gt;</code> section of your <code>web.config</code>, add the following:</p>
<pre class="brush: xml; light: true; title: ;">
&lt;authentication mode=&quot;Windows&quot;/&gt;
&lt;identity impersonate=&quot;true&quot;/&gt;
</pre>
<p>Also, make sure you&#8217;re using a connection string that uses Integrated Security.</p>
<h2>IIS</h2>
<p>I&#8217;m using IIS7, which has some more detailed settings than IIS6. In the website or virtual directory, ensure that Anonymous Authentication and Forms Authentication are disabled, and ASP.Net Impersonation and Windows Authentication are enabled. IIS should pick this up from <code>web.config</code>.</p>
<p><img class="alignnone size-full wp-image-56" title="IISAuthentication" src="http://blog.reveille.org.uk/wp-content/uploads/2010/01/IISAuthentication.jpg" alt="IIS Authentication section" width="464" height="182" /></p>
<p>IIS7 lets you specify &#8220;providers&#8221; for Windows Authentication. You must use the <em>Negotiate:Kerberos</em> provider. Choosing this provider will mean that &#8220;Kernel-mode authentication&#8221; cannot be used. This is disabled under the Advanced Settings within the Authentication section.</p>
<h2>Active Directory</h2>
<p>The <em>web</em> server&#8217;s Active Directory properties must be edited to enable Delegation of credentials onto the SQL server. There&#8217;s a great explanation with a screen grab of the Active Directory property page in a <a title="Ken Schaefer's blog" href="http://www.adopenstatic.com/cs/blogs/ken/archive/2007/01/28/1282.aspx">post from Ken Schaefer</a>.</p>
<p>Windows Server 2003 domains and later support <em>Constrained Delegation</em>, which can constrain the delegation to a specific service on the target machine. This is obviously more secure. To delegate to SQL Server, <em>MSSQLSvc</em> is the service you need.</p>
<h2>SQL Server</h2>
<p>All you need to do at the database level is grant the relevant permissions for the users or roles you want accessing the database.</p>
<p>Now it should all magically work!</p>
<p>UPDATE: That might not be all! See <a title="Part 2" href="http://blog.reveille.org.uk/2010/01/asp-net-impersonation-delegation-2/">Part 2</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.reveille.org.uk/2010/01/asp-net-impersonation-delegation/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Dangers of binary serialization</title>
		<link>http://blog.reveille.org.uk/2009/11/dangers-of-binary-serialization/</link>
		<comments>http://blog.reveille.org.uk/2009/11/dangers-of-binary-serialization/#comments</comments>
		<pubDate>Fri, 06 Nov 2009 22:37:55 +0000</pubDate>
		<dc:creator>Graham Clark</dc:creator>
				<category><![CDATA[coding problems]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[serialization]]></category>

		<guid isPermaLink="false">http://blog.reveille.org.uk/?p=28</guid>
		<description><![CDATA[A system at work stores big object graphs in the database as varbinary(MAX). To do this, the BinaryFormatter class is used. When my new version of the system was installed, the objects would be retrieved out of the database as normal, but after deserialization, they were empty &#8211; all properties had default values (i.e. null [...]]]></description>
			<content:encoded><![CDATA[<p>A system at work stores big object graphs in the database as varbinary(MAX). To do this, the <a href="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.formatters.binary.binaryformatter.aspx">BinaryFormatter</a> class is used. When my new version of the system was installed, the objects would be retrieved out of the database as normal, but after deserialization, they were empty &#8211; all properties had default values (i.e. null for reference types, 0 for ints, etc). This was a bit of mystery, as no exceptions were being thrown, and all I thought I&#8217;d done was add a new property to the bottom of one of the classes.</p>
<p>I realised I&#8217;d also employed my anal side to change the names of the private backing fields for the properties. Might as well try out the code plugin here, so&#8230; I changed this:</p>
<pre class="brush: csharp; light: true; title: ;">
private int SomePropertyField;

public int SomeProperty {
   get { return SomePropertyField; }
   set { SomePropertyField = value; }
}
</pre>
<p>to this:</p>
<pre class="brush: csharp; light: true; title: ;">
private int someProperty;

public int SomeProperty {
   get { return someProperty; }
   set { someProperty = value; }
}
</pre>
<p>I was under the mad impression that changing private fields was ok. Not so when using binary serialization &#8211; the entire oject graph is serialized, including both public and private members.</p>
<p>If you&#8217;re going to use binary serialization, it&#8217;s probably wise to prevent any private fields from being serialized, like so:</p>
<pre class="brush: csharp; light: true; title: ;">
[NonSerialized]
private int someProperty;
</pre>
<p>If this wasn&#8217;t considered though, it&#8217;s too late. It seems like using binary serialization is painting yourself into a corner. Once you&#8217;re saving and retrieving binary, it&#8217;s difficult to change the format, apart from adding fields or changing enumerations. Adding the [NonSerializable] attribute after you&#8217;ve started saving stuff away will break compatibility, so you&#8217;re pretty stuck. This seems to destroy the whole concept of using public properties with private backing fields &#8211; you&#8217;re supposed to be able to keep a consistent public interface whilst maintaining control over the internal implementation.</p>
<p>From my brief foray into the world of binary serialization, I&#8217;d say it&#8217;s best to thoroughly plan out exactly what you need to be serialized, or it will be too late to change anything. Either that or don&#8217;t bother and save a big headache.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.reveille.org.uk/2009/11/dangers-of-binary-serialization/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

