NAnt (for those of you who don’t know) is the .NET version of Ant. It’s very similar to Ant, but has some nice extensions, like xmlpoke, which replaces text in an XML file at the location specified by an XPath expression. I’ve used xmlpoke a couple different times, usually to meddle with web.config but today I ran into an issue where I need to change a .cs file, which I’m sure raises a red flag for alot of you. But Microsoft left me know choice. See, in order to create a WSE compliant webservice client, you’re supposed to simply:
add a reference to Microsoft.Web.Services2 to your assembly…[and then]… change the base class from SoapHttpClientProtocol to the WebServicesClientProtocol class from the Microsoft.Web.Services2 namespace.
[source]
Now that would be all fine and dandy if I used $isualStudio to create my webservices, but I’d rather use Eclipse and NAnt. So NAnt has this great task called a <script> which allows you to plug in any C# code you want and make a task out of it. So here’s a task I made called filepoke:
<script language="C#">
<code>
<![CDATA[
[TaskName("filepoke")]
public class FilePoke : Task {
private string _file;
private string _target;
private string _value;
[TaskAttribute("file", Required=true)]
public string TargetFile {
get { return _file; }
set { _file = value; }
}
[TaskAttribute("target", Required=true)]
public string Target {
get { return _target; }
set { _target = value; }
}
[TaskAttribute("value", Required=true)]
public string Value {
get { return _value; }
set { _value = value; }
}
protected override void ExecuteTask() {
string path = _file;
StringBuilder filecontents = new StringBuilder();
using (StreamReader sr = File.OpenText(path)) {
string s = "";
while ((s = sr.ReadLine()) != null) {
filecontents.Append(s.Replace(_target, _value) + "\n");
}
}
using (StreamWriter sw = new StreamWriter(path)) {
sw.Write(filecontents.ToString());
}
}
}
]]>
</code>
</script>
which you can use (like I did) while looping over all the generated proxy .cs files to replace all instances of x with y:
<filepoke file="${filename}" target="System.Web.Services.Protocols.SoapHttpClientProtocol" value="Microsoft.Web.Services2.WebServicesClientProtocol" />
Seems like it would make way more sense for the wsdl.exe tool to give you the option of overriding the base class of the generated proxy, but this’ll get’er done.