Troubleshooting!

1. m_safeCertContext is an invalid handle

I got this issue when try to assign a X509SigningCredentials to the custom STSConfiguration.


this.SigningCredentials = new X509SigningCredentials(cert);

Solutions:

Make sure don’t call cert.Reset() before passing the cert to X509SigningCredentials constructor

2. Keyset does not exist

Solutions:

http://stackoverflow.com/questions/602345/cryptographicexception-keyset-does-not-exist-but-only-through-wcf

http://msdn.microsoft.com/en-us/library/aa702621.aspx

3. A potentially dangerous Request.Form value was detected from the client (wresult=”<trust:RequestSecuri…”).

Solutions:

Make sure you have this setting in your web.config (under system.web)


<httpRuntime requestValidationMode="2.0"/>

http://social.msdn.microsoft.com/Forums/en-US/Geneva/thread/b6428ea6-e705-4c66-a6fe-8e9f51f73311

http://volkanuzun.com/blog/post/2010/10/14/A-potentially-dangerous-RequestForm-value-was-detected-from-the-client-(wresult3d3ctrustRequestSecuri).aspx

Generating Federation Metadata using WIF APIs

Just like all the Service Oriented approaches, metadata is the key, for example, with web services, you just have to build the service (using ASMX file or WCF) it will generate the WSDL file for your service automatically, so the client code can easily consume. We expect the same thing with WIF, unfortunately, we cannot just build a STS and then somehow it exposes the federation metadata for that.

Most of the samples in WIF SDK and the Programming WIF book are showing you how to generate the metadata from a Visual Studio template. But there is almost no documentation on how to create the federation metadata manually (or dynamically), especially when you build a custom STS using MVC (hopefully we will have the template for MVC soon, but still not solving the dynamic issue).

WIF itself does provide APIs for this task, below are some very simple codes (I copy most of them from http://netpl.blogspot.com/2011/08/quest-for-customizing-adfs-sign-in-web.html). I just tried to put thing together and see how to use the WIF metadata API. For a more complete sample, please see the link above.


const string _endpoint = "http://yoursts.com";

static void Main(string[] args)
{
 string endpointId = _endpoint;
 EntityDescriptor entityDescriptor = new EntityDescriptor(
 new EntityId(endpointId));

 // Signature, I created a certificate using portecle and installed
 // it under TrustedPeople/CurrentUser
 X509Certificate2 cert =
 CertificateUtil.GetCertificate(
 StoreName.TrustedPeople, StoreLocation.CurrentUser, "CN=HoaSTSCert, C=US");

 entityDescriptor.SigningCredentials = new X509SigningCredentials(cert);

 SecurityTokenServiceDescriptor roleDescriptor = new SecurityTokenServiceDescriptor();

 // required protocols supported
 roleDescriptor.ProtocolsSupported.Add(new Uri(WSFederationMetadataConstants.Namespace));
 roleDescriptor.Contacts.Add(new ContactPerson(ContactType.Administrative));

 // This section is for key descriptor
 SecurityKeyIdentifierClause clause = new X509RawDataKeyIdentifierClause(cert);
 SecurityKeyIdentifier ski = new SecurityKeyIdentifier(clause);
 KeyDescriptor signingKey = new KeyDescriptor(ski);
 signingKey.Use = KeyType.Signing;
 roleDescriptor.Keys.Add(signingKey);

// This section is for endpoint
 string activeSTSUrl = _endpoint;
 EndpointAddress endpointAddress = new EndpointAddress(
 new Uri(activeSTSUrl),
 null,
 null,
 (XmlDictionaryReader)null,
 null);

 // Active endpoint
 roleDescriptor.SecurityTokenServiceEndpoints.Add(endpointAddress);
 // Passive endpoint
 roleDescriptor.PassiveRequestorEndpoints.Add(endpointAddress);

 roleDescriptor.ClaimTypesOffered.Add(new DisplayClaim(ClaimTypes.Role));
 roleDescriptor.ClaimTypesOffered.Add(new DisplayClaim(ClaimTypes.Name));

 entityDescriptor.RoleDescriptors.Add(roleDescriptor);

 // Serialize process...
 MetadataSerializer serializer = new MetadataSerializer();

 //MemoryStream stream = new MemoryStream();
 string fileName = @"FederationMetadata.xml";
 XmlWriter writer = XmlWriter.Create(fileName);
 XmlWriterSettings settings = new XmlWriterSettings();
 settings.Indent = true;

 serializer.WriteMetadata(writer, entityDescriptor);

 writer.Flush();

 Console.WriteLine("done...");
 Console.WriteLine(string.Format("Output: {0}",
 Path.Combine(Environment.CurrentDirectory, fileName)));
}

ASP.NET Error pages

That is interesting that my previous post talked about error pages in asp.net and yesterday I got this (see image below) when I tried to access blackberry online shopping site

That is good to know that this website is built using ASP.NET MVC, WCF and a Controller-Service-Repository pattern, so instead of disappointed cause the website crashed, I felt like this is built by some of my “friends” :)

PS: the good news is it was fixed right after that!

Test Expected Exception with NUnit 2.5

Testing the expected exceptions has been improved a lot by NUnit 2.5, let says you have a scenario that a method checks for the input parameters and throws some ArgumentNullException exceptions, it was kind of cumbersome to cover all those cases in your tests, normally, you will have multiple test methods using ExpectedExceptionAttribute. But with NUnit 2.5.x, we can write something likes


[Test]

public void AndSpecification_Construction_With_Null_Inputs_Test()

{

   // Arrange
   ISpecification<MockEntity> spec = new Moq.Mock<ISpecification<MockEntity>>().Object;

   // Passing null for the left specification
   Assert.That(() => new AndSpecification<MockEntity>(null, spec),
      Throws.TypeOf<ArgumentNullException>()
         .With.Property("ParamName").EqualTo("left"));

   // Passing null for the right specification
   Assert.That(() => new AndSpecification<MockEntity>(spec, null),
      Throws.TypeOf<ArgumentNullException>()
         .With.Property("ParamName").EqualTo("right"));

}

One single method can handle multiple cases.

You can find more details information from http://nunit.net/blogs/?p=63

Crystal Reports 64 bits issue

The error below happen on a 64 bits web server that tries to load the crystal reports run-time. If this sounds familiar with you and you already installed the “CRRedist2008_x64.msi”.  But it still didn’t work and you starting to get tired with google :-)

You should look into your application pools settings, make sure you set the “Enable 32 bits Applications” to FALSE

How to add a line-break (\n) in a resource string?

This sounds like a very simple question but it turns out to be not quite trivial (at lease for me). Anyways, I found the answer from the internet!

You really shouldn't add the new lines programmatically - because when
you come to localize your application to another language you may want
to have the line breaks in different positions.  The best way is to
include the new lines in your actual resources.   You can do this in
one of two ways:

1.  Open the resx file in the VS designer and use Shift+Enter when you
want want a line break.   You will need to resize the row using the
grab bars to make it big enough to see multiple lines.

2.  Open the resx file as code and add the line breaks directly in the
XML.

The Visual Studio Resource editor really is fairly basic and quite
irritating to use for large amounts of text when localizing so you
could also consider using a tool like our Globalizer.NET that allows
you to see and edit all your resources (for all languages) in a single
easy to edit form (see http://www.infralution.com/globalizer.html).

Regards
Grant Frisken
Infralution
www.infralution.com

Globalizer.NET - makes localizing .NET Application easy
You really shouldn't add the new lines programmatically - because when
you come to localize your application to another language you may want
to have the line breaks in different positions.  The best way is to
include the new lines in your actual resources.   You can do this in
one of two ways:

1.  Open the resx file in the VS designer and use Shift+Enter when you
want want a line break.   You will need to resize the row using the
grab bars to make it big enough to see multiple lines.

2.  Open the resx file as code and add the line breaks directly in the
XML.

The Visual Studio Resource editor really is fairly basic and quite
irritating to use for large amounts of text when localizing so you
could also consider using a tool like our Globalizer.NET that allows
you to see and edit all your resources (for all languages) in a single
easy to edit form (see http://www.infralution.com/globalizer.html).

Regards
Grant Frisken
Infralution
www.infralution.com

Globalizer.NET - makes localizing .NET Application easy

Object to String – String to Object

Sometime, you just want to quickly serializes an object to string and deserializes from a string to object. Below are the codes
(If you don’t like the generic version of StringToObject, you can pass the object type as an addition parameter)

public static string ObjectToString(object obj) 
{
   XmlSerializer serializer = new XmlSerializer(obj.GetType()); 
   string result; 
   using (MemoryStream stream = new MemoryStream()) 
   {
      serializer.Serialize(stream, obj);
      StreamReader reader = new StreamReader(stream); 
      stream.Flush();
      stream.Position = 0;
      result = reader.ReadToEnd();
      reader.Close();
   }
   return result; 
}

public static TEntity StringToObject<tentity>(string stringValue) 
{
   XmlSerializer serializer = new XmlSerializer(typeof(TEntity)); 
   object result; 
   using (StringReader reader = new StringReader(stringValue)) 
   {
      result = serializer.Deserialize(reader);
   }
   return (TEntity)result; 
}

Enumerating AppDomains for a Process

It turns out to not trivial if you want to enumerating the AppDomains, below is the sample code

(The same has been mentioned here and here)

public static IList GetAppDomains()
{
   List appDomains = new List();
   IntPtr enumHandle = IntPtr.Zero;

   CorRuntimeHostClass host = new CorRuntimeHostClass();
   try
   {
      host.EnumDomains(out enumHandle);
      while (true)
      {
         object domain = null;
         host.NextDomain(enumHandle, out domain);
         if (domain == null)
         {
            break; // exits the while (true)
         }
         appDomains.Add((AppDomain)domain);
      }
      return appDomains;
   }
   catch (Exception ex)
   {
      Debug.WriteLine(ex.Message);
      return null;
   }
   finally
   {
      if (host != null)
      {
         host.CloseEnum(enumHandle);
         Marshal.ReleaseComObject(host);
      }
   }
}