Archive for category .net
Making your WCF Service compatible with legacy .net 1.1 applications
Posted by shawson in .net, C#.net, WCF, Web Services on December 7th, 2009
I’m building an error tracking service which all our future web project will report to, so we can track and tag all our various systems problems from one place- this is currently done with email which is a bit of a nightmare!
According to Microsoft, traditional ASMX web services are now considered “Legacy technology” (!) so I thought I would buite the bullet and build the new services using WCF.
This was fairly painless until I tried to consume the web service in some old .net 1.1 web apps- when trying to add the web reference I received this error message;
Web ReferenceslocalhostReference.map(1): Custom tool warning: DiscoCodeGenerator unable to initialize code generator. No code generated.
I found a great article over on the MSDN – and all it takes is a small change to the web.config, fiddling with, my old friend, the httpBindings.
I had to swap out the default bindings put in by .net;
<endpoint address="" binding="wsHttpBinding" contract="HachetteErrorTracker.IErrorLog">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
For this one;
<endpoint
address=""
binding="basicHttpBinding" bindingNamespace="http://errortracker.localhost/"
contract="HachetteErrorTracker.IErrorLog"
/>
How to: Configure WCF Service to Interoperate with ASP.NET Web Service Clients.
Stop the “web.config” being inherited by child applications in sub folders
We recently had an issue setting a .net microsite live off the back of an existing domain, hosting another .net site.
This was due to the web.config being inherited to the child- we would be hit with errors like this;
Configuration Error
Description: An error occurred during the processing of a configuration file required to service this request. Please review the specific error details below and modify your configuration file appropriately.
Parser Error Message: Could not load file or assembly ‘UrlRewritingNet.UrlRewriter’ or one of its dependencies. The system cannot find the file specified. (d:ProjectsVSAspDotNetFaqProjectWebsiteweb.config line 89)
Source Error:
Line 88: <httpModules> Line 89: <add name="UrlRewriteModule" type="UrlRewritingNet.Web.UrlRewriteModule, UrlRewritingNet.UrlRewriter"/> Line 90: <add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> Line 91: </httpModules>
This is because a module was defined in the parent site which doesn’t exist in the child, but because it’s inheriting it still tries to load it. We would also get errors complaining that modules have already been defined.
I tried initially, manually adding <remove name=”blah” /> to the child web.config to remove the entries in the child web.config it thought were defined twice, but after putting in about 10 of these and it still not working it started to get a bit ridiculous!
The trick, we found on google (How to disable web.config Inheritance for Child Applications in Subfolders in ASP.NET?) is to stop the web.config from inheriting in the top level web.config;
<location path=“.“ inheritInChildApplications=“false“>
<system.web>
…
</system.web>
</location>
This stops anything being migrated down to the children, allowing you to have your full web.config in the child site, unaffected by the parent! — Make sure you don’t put this around anything else though; just the system.web section!
URL Routing with ASP.NET 4 Web Forms (VS 2010 and .NET 4.0 Series) – ScottGu’s Blog
I was quite excited (what have I become!?) to read about the URL Routing stuff from MVC, which is now available in WebForms as of ASP.net 4.0- specifically the ability to retreive a URL back from the Route engine from the code behind!
URL Routing with ASP.NET 4 Web Forms (VS 2010 and .NET 4.0 Series) – ScottGu’s Blog.
Linq Distinct!
I have a List of books- each book has a category – i want to find out all the unique categories involved, given a list of books- i knew i could do this with linq, but not quite sure how!
It turned out to be easy..
List<Category> categories = _books.Select(i => i.Category).Distinct();
There was a minor complication however- Distinct obviously needs to be able to compare different instances of Category- you can supply a delegate to a custom EquityComparer class- otherwise it will simply check if this is the same instance of the object, which will (probably) always come back false rendering your distinct useless. So i created this;
public class CategoryComparer : IEqualityComparer<Category>
{
public bool Equals(Category x, Category y)
{
return x.Id == y.Id;
}
public int GetHashCode(Category obj)
{
return obj.Id.GetHashCode();
}
}
then updated my linq to use it..
List<Category> categories = _books.Select(i => i.Category).Distinct(new CategoryComparer());
A complete list of .NET Serializers in 3.5
Just saw this pop up in my Google Reader and though I would blog it as it is tres useful!
.NET Serializers – Development With A Dot.
As of version 3.5 SP1, .NET comes along with the following serializers:
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter: binary serializer used in .NET Remoting, type information is included, understands System.Runtime.Serialization.ISerializable; System.Runtime.Serialization.Formatters.Soap.SoapFormatter: SOAP (XML) serializer used in .NET Remoting, includes type information, understands System.Runtime.Serialization.ISerializable; System.Runtime.Serialization.DataContractSerializer: XML serializer used in WCF, does not include type information; System.Runtime.Serialization.Json.DataContractJsonSerializer: JSON serializer used in WCF, does not include type information; System.Runtime.Serialization.NetDataContractSerializer: binary serializer used in WCF, includes type information; System.Xml.Serialization.XmlSerializer: XML serializer used in ASP.NET Web Services (ASMX), type information is not included, understands System.Xml.Serialization.IXmlSerializable; System.Web.UI.LosFormatter: uses ObjectStateFormatter internally, does not account by itself; System.Web.UI.ObjectStateFormatter: binary serializer used in ASP.NET for storing items in view state, control state and session, type information is included, understands System.Runtime.Serialization.ISerializable.There isn’t, however, a common interface for all of these serializers, and, in fact, they have quite different requirements.
The base interfaces are:
- System.Runtime.Serialization.IFormatter: for BinaryFormatter, SoapFormatter, NetDataContractSerializer and ObjectStateFormatter;
- System.Runtime.Serialization.XmlObjectSerializer: for DataContractSerializer, DataContractJsonSerializer and NetDataContractSerializer;
- XmlSerializer doesn’t have any interface that specifies its behavior.
The interfaces that can be used to control the serialization process are:
- System.Runtime.Serialization.ISerializable: for all the IFormatter serializers;
- System.Xml.Serialization.IXmlSerializable: for XmlSerializer.
Also, there are a couple of attribute classes that can be used to control the serialization process:
- System.Xml.Serialization.SoapAttributeAttribute (XmlSerializer)
- System.Xml.Serialization.SoapElementAttribute (XmlSerializer)
- System.Xml.Serialization.SoapEnumAttribute (XmlSerializer)
- System.Xml.Serialization.SoapIgnoreAttribute (XmlSerializer)
- System.Xml.Serialization.SoapIncludeAttribute (XmlSerializer)
- System.Xml.Serialization.SoapTypeAttribute (XmlSerializer)
- System.Xml.Serialization.XmlAnyAttribute (XmlSerializer)
- System.Xml.Serialization.XmlAnyElementAttribute (XmlSerializer)
- System.Xml.Serialization.XmlArrayAttribute (XmlSerializer)
- System.Xml.Serialization.XmlArrayItemAttribute (XmlSerializer)
- System.Xml.Serialization.XmlAttributeAttribute (XmlSerializer)
- System.Xml.Serialization.XmlChoiceIdentifierAttribute (XmlSerializer)
- System.Xml.Serialization.XmlElementAttribute (XmlSerializer)
- System.Xml.Serialization.XmlEnumAttribute (XmlSerializer)
- System.Xml.Serialization.XmlIgnoreAttribute (XmlSerializer)
- System.Xml.Serialization.XmlIncludeAttribute (XmlSerializer)
- System.Xml.Serialization.XmlRootAttribute (XmlSerializer)
- System.Xml.Serialization.XmlTypeAttribute (XmlSerializer)
- System.Runtime.Serialization.CollectionDataContractAttribute (XmlObjectSerializer)
- System.Runtime.Serialization.DataContractAttribute (XmlObjectSerializer)
- System.Runtime.Serialization.DataMemberAttribute (XmlObjectSerializer)
- System.Runtime.Serialization.EnumMemberAttribute (XmlObjectSerializer)
- System.Runtime.Serialization.IgnoreDataMemberAttribute (XmlObjectSerializer)
Note that the Soap* attributes are only considered if the SoapBindingStyle.Document is set for the Style property of the binding, in ASP.NET Web Services, otherwise, its the Xml* attributes.
Deep Copy Array/ Collection/ etc using serialization
A useful snippet of code I used in a web services project a while ago which i just stumbled back across recently- allows you to make a deep copy of an array, where you would normally get a shallow copy, stopping you from manipulating it independently from the source. This gives you a completely fresh and separate copy. The original is serialised to a memory, then a new instance created from the serialised representation (so obviously if it’s an array of custom objects, those objects will need to be marked serializable)
OrderItem[] order_items_clone;
using( MemoryStream ms = new MemoryStream())
{
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
formatter.Serialize(ms,order_items);
ms.Seek(0 , SeekOrigin.Begin);
order_items_clone = (OrderItem[])formatter.Deserialize(ms);
}
Scott Klueppel’s Blog – Error Log RSS Feed
Sam pointed me to an article showing a really nice way to deal with error logging; as opposed to filling a debug mail box with 100’s of mails that will soon become unmanageably large, have the error’s logged to a database, then published via RSS!
Synchonous Yield messing up my foreach loop!
I recently got stung while debugging a colleagues code, by my lack of understanding of the Yield keyword! We had a foreach loop which looks like this;
foreach (PurchaseOrderLine aLine in PurchaseOrderLine.LoadExtractLines(extractTime, systemId)) {
//do some processing stuff...
PurchaseOrder.MarkAsExported(lastId, extractTime);
}
The LoadExtractLines returns an IEnumerable and uses yield to return each line- the stored proc it runs is quite intensive- the whole thing looks like this;
public static IEnumerable<PurchaseOrderLine> LoadExtractLines(DateTime cutOff,int systemId)
{
using (SqlConnection conn = new SqlConnection(SingleAccess.Instance.ConnectionToUse))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand("Get_PurchaseOrderLinesToExtract", conn))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@CutOff", cutOff.ToString("dd MMM yyyy HH:mm:ss"));
cmd.Parameters.AddWithValue("@SystemId", systemId);
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
yield return LoadLine(reader);
}
}
}
}
}
MarkAsExported runs quite an intensive update procedure on the database. As more and more data came into the system we started to see Sql Timeouts, and upon running a trace noticed something strange. Logging the RPC:Start and Completed events of the stored procs, the Get_PurchaseOrderLinesToExtract proc which feed’s the for loop was starting, then the update was starting before the Get_ had finished- the two were running side by side, causing the timeout’s!
Turns out the foreach loop started the moment it received it’s first row, yielded back from the LoadExtractLine method- which in retrospect does make sense! The solution was to convert the Load method to populate a local List<> then return the whole thing once complete, removing the yield statement alltoghether and forcing the process to wait for the entire result set to be complete before starting the loop.
Where did my Immidiate window go!?
I’ve had this trouble on my home machine and occasionally at work- my immediate window seems to just disappear! All trace of it gone, and no sign of it in it’s usual location in the menu- however the command window is still available. Turns out that you can invoke the immidiate window from a command window by typing;
immed
It’s that simple!!
Premailer — preflight for HTML e-mail
Stumbled across a handy on-line tool for processing html used in email’s- which is notoriously picky. This tool converts all your css declarations to be inline as well as update all your links and image paths to be absolute- not masses but saves you picking through and doing it manually.
Premailer — preflight for HTML e-mail — dunae.ca.
There’s another site up which guides you through standards which should help you get the best results from your email across all the main email clients ; www.email-standards.org