0

System.TypeLoadException: Method does not have an exception

Sometimes you hit smack in to a runtime exception that requires a weekend off to get your head straight again to tackle come Monday morning.  That was my experience today, as I wrangled with an unexpected exception when doing something I’d done plenty of times before.

Our app has the following structure:

  • Interfaces assembly
  • Business Logic assembly (where interfaces are implemented)
  • Web Application (where Interface and Business Logic are married using the Unity Framework)

We have a build script that copies the latest version of the Business Logic assembly in to the /bin directory of the Web Application, since that app does not reference the assembly directly.

It has been fairly routine for us, when adding or extending functionality, to add methods to our Interfaces library, implement the corresponding method in the Business Logic library, then use that method in our Web app.  But this time around, even after clean builds, we’d get a runtime error when the Unity framework would try to initialize.

A bit of searching online revealed that this error occurs often when you’re not looking at the most recent version of an assembly that is implementing the Interface, and so to the Framework, it appears that the implementation is missing, even though your compiler will run clean.

As a step to make sure that there were no residual versions of previously built assemblies, I went through Windows Explorer to purge the /bin directories.  Something caught my eye as I was looking at the /bin directory for the Business Logic library – an extra subdirectory names ‘x86′.  In this directory were the Debug and Release subdirectories, and then the new build of the assembly.

So, it appeared the problem was that our build script was not in fact getting the latest version of our assembly since it was in a different (unexpected) location.

The x86 name was a clue to look at the Configuration Manager in Visual Studio.  Sure enough, somehow the Business Logic project got set explicitly to x86 rather than ‘Any CPU’.

I changed the target platform for that project, did a new clean and rebuild, and this time through, the app loaded up without error.

Thankfully I didn’t spend an unrecoverable amount of time trying to sort this out, but I still thought it may be helpful to record for others who run in to that error and, as I did, mistakenly believe that nothing has changed to trigger the new runtime exception.

1

Filtering the SharePoint 2010 Blog Posts web part

Sometimes it’s the little things that drive you mad.

We got a report from a customer following a SharePoint 2007 to 2010 upgrade that their Blog site was showing too many posts, and they wanted to filter it by category.  That’s a simple enough request, right?

In 2007, the user explained, she’d Edit the Page, Edit Web Part, then click on the ‘Edit the current view’ to get the ability to set the filter criteria.  However, in 2010, the ‘Edit the current view’ link never appeared.

I set off to confirm what she was seeing.

In my 2010 development lab, I created a new site using the Blog site template.

As advertised, the default view of the site showed the ‘Posts’ web part showing all the approved posts from the blog.  I added a few other posts, and set one of the categories to be called ‘Announcements’.

So, as the user did, I went to Edit the web part.

Sure enough, the ‘Edit the current view’ was notably absent.

I was able to get the link to s how up, by changing the Selected View, clicking ‘Apply’, then re-selecting ‘<Summary View>’ and clicking ‘Apply’ again.

However, when I clicked on the link, I got a whole lot of nothing.

So, on to plan B as it was evident this was not to be done through the Browser UI.  I launched SharePoint Designer and loaded up the Blog site.

Then clicked on ‘Edit site home page’ to load up the web part page.  There was my Posts web part.

By selecting the Web Part, I got a ‘List View Tools’ ribbon with a nice big ‘Filter’ button on it.

Clicking the Filter button brings up the ‘Filter Criteria’ dialog, where I could add my category filters.

After adding the additional criteria, the Posts web part showed the filtered list of entries.

Save the page in SharePoint Designer, which will automatically publish the changes to the server.

Now, when I go back to the Blog site, I see the filtered list of entries.

0

Add root certificate as trusted source in SharePoint 2010

Following a recent SharePoint 2007 to 2010 upgrade, we got a report of an RSS Viewer that was not displaying any content.

After confirming for myself, I checked the feed that the RSS Viewer was pulling, and found it was from the Cisco support forums at https://supportforums.cisco.com/community/feeds/video?community=2004.

Next we checked the SharePoint Logs to find the following entry:

04/02/2012 10:17:05.24         w3wp.exe (0×4610)                               0x3D3C        SharePoint Portal Server              Web Parts                             8imh        High            RssWebPart: Exception handed to HandleRuntimeException.HandleException System.Net.WebException: The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel. —> System.Security.Authentication.AuthenticationException: The remote certificate is invalid according to the validation procedure. at System.Net.Security.SslState.StartSendAuthResetSignal(ProtocolToken message, AsyncProtocolRequest asyncRequest, Exception exception)     at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)     at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)     at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRe…        193b14f8-f282-438d-bf91-36bb7c640d03

A corresponding entry in the Event log was also a clue.

An operation failed because the following certificate has validation errors:\n\nSubject Name: CN=supportforums.cisco.com, OU=Communications and Collaboration Team, O=Cisco Systems, L=San Jose, S=CALIFORNIA, C=US\nIssuer Name: CN=VeriSign Class 3 Secure Server CA – G3, OU=Terms of use at https://www.verisign.com/rpa (c)10, OU=VeriSign Trust Network, O=”VeriSign, Inc.”, C=US\nThumbprint: CAF5027FDDE630D4AC3FFB1000FC2E09B18249A3\n\nErrors:\n\n The root of the certificate chain is not a trusted root authority..

What was going on?

The Cisco site had a chain of SSL certificates that was 3 layers deep.

  1. A root certificate
  2. An intermediate or secondary certificate
  3. A site certificate

As the RSS Viewer attempted to connect to this location, it connects as the SharePoint service, not as a browser.  SharePoint then tried to travel up the certificate chain to confirm the authenticity of each layer. When it got to the intermediate certificate, it choked, not able to validate it as a legitimately trusted source.

How do we fix it?

In order for SharePoint to recognize the Verisign certificates chained together and used by the Cisco site, we need to explicitly tell SharePoint they are trustworthy.  Thankfully, there is a simple to use UI as part of Central Administration where we can do just that.

First, log in to Central Administration, then click on the ‘Security’ menu item.

Then, select ‘Manage Trust’ from the ‘General Security’ section.

Before we can add the Verisign certificates as trusted relationships, we have to retrieve them from the Verisign website.  All of Verisigns root and secondary certificates can be found at http://www.verisign.com/support/roots.html

By examining the certificate details in the Browser, we can determine which root certificate to download and add to SharePoint.  In our case, there needed root was:

Root 3
VeriSign Class 3 Primary CA – G5
Description:
This root CA is the root used for VeriSign Extended validation Certificates and should be included in root stores. During Q4 2010 this root will also be the primary root used for all VeriSign SSL and Code Signing certificates.

Download the Root Certificate file.

Now, add the Trust Relationship to SharePoint

After that certificate is in place, you can return to the page with the RSS Viewer and confirm it is able to retrieve the results.

If not, then there may be additional certificates in the chain that you would need to retrieve and add to SharePoint.

The Trust Relationships in SharePoint are also used when calling out to an external web service from a web part.

Thanks to http://blog.mattsampson.net/index.php/calling-a-webservice-over-ssl-in-sharepoint-ssl?blog=1 for helping guide the way.

0

Rejected but encouraged

A few weeks ago I applied for a grant offered by a local Venture Capital firm.  The grant application is essentially an abbreviated business plan, and finalists compete for several awards.

Today I received my rejection letter.  Complete with the classic “we regret to inform you” clause.

However, they attached a remarkably polished PDF analysis of my application compared to the 183 other submissions.

The analysis gave me a unique insight to my own idea-making.  Here was an objective evaluation of my idea (related to offering HomeSpot in a unique way to home improvement companies) and some direct feedback from people who look at entrepreneurial ideas for a living.

Across the seven scoring categories, our application performed above average in all seven.  This is more clearly seen in graphical form.

I assume, but do not know for sure, that the selected finalists exceeded some established threshold for their total score.  So, while our application was 30 points off of the maximum score, it may have only be 10 points off of the threshold.  I’ll never know.

Here is some of the feedback from the reviewers:

This is an interesting service, but it feels like an ultra specialized solution. It is addressing a real need, but it is another website that consumers need to log into. It is not unique and it is very difficult to differentiate. Ultimately the success will obviously depend on execution.

What I take from this is the validation that we are addressing a real need.  Finding a solution for a existing problem is key to success as an entrepreneur.  I agree fully with the reviewer here that execution will be the determining factor on our success.

Great platform with promising customer feedback. I am wondering, however, what the long term competetive response and market growth will be. How are you planning to grow your platform outside of local handymans? What is your growth strategy serving as an anonymous service provider?

Again, affirmation on the product idea itself and the feedback we have received already.  But the challenge is put forth – how do we grow, scale and sustain ourselves beyond our initial markets? The third review also shared this concern:

The problem, market, and technology are all very clearly presented. It is difficult to see how this really scales to a company with significant revenue…

In the eyes of a Venture Capitalist, “significant revenue” has lots of zeroes following it.  For me as the entrepreneur, my standards of significance are no doubt different.  My definition for success may well come in being able to first hit “insignificant revenue” having started with “zero revenue”.  But for the reviewer, and the investor alike, the criteria for growth and scale are well understood.

The last reviewer was the most critical.

I think it’s good that there’s a competitor, but I’m slightly concerned that your product (as described) appears to be very similar, yet you describe your product as “revolutionary”. Honestly, this hurt the credibility a bit, at least in my eyes. If successful, there are likely to be other revenue stream opportunities. I’m not sure if you considered any, as they’re not included in the proposal. You indicated that the product is already on the market, but that you have no sales and don’t expect any for 12 months. Why? Also, pricing was not indicated.

This reveals much to me about how we presented ourselves in the application.  We obviously (at least in this reviewer’s eyes) lacked differentiation and clarity on our current status and future growth.  Our exclusion of other revenue streams was not because we are not keenly aware of them, but had to choose carefully our statements in the limited format of the application.  Questions about our sales efforts and pricing are also in our minds constantly, but we chose not to put them forth in the application.

What is important is that these things that I deem to be secondary or even trivial are clearly not thought of the same way by the reviewer.

All told, I am encouraged by this feedback.  It was a solid helping of affirmation, with some key calls to address the perceived challenges in a product we have yet to fully bring to market.  I am motivated to prove these skeptics wrong, execute, achieve significant revenue, and capture all the opportunity before me.

0

Override ASP.NET Membership Password Generation rules

I am a real fan of the ASP.NET Membership system as a way to deliver a basic account management and log in mechanism to a web application.  I have used it in both ASP.NET and ASP.NET MVC applications, using both SQL and Active Directory as the backing identity store.

One nuance of the Membership provider when using SQL is how it generates new passwords when the user requests their password be reset.  By default, the generated password is a whopping 14 characters in length, with no clear way to adjust the format.  (The MSDN page for SqlMembershipProvider.ResetPassword describes this behavior.)

Thankfully, it is fairly easy to create a new MembershipProvider and override the GeneratePassword method with your own rules.

First, we’ll create a new class that inherits SqlMembershipProvider.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace MyNamespace
{
public class MyMembershipProvider:System.Web.Security.SqlMembershipProvider
{

public MyMembershipProvider()
: base()
{ }

}

Then we’ll override the GeneratePassword() method to use our own rules for creating a new password value.  In this case we assemble an 8 character string of upper and lower case letters, numbers, and a few symbols.

public override string GeneratePassword()
{
    string newRandomPassword = string.Empty;
    int passwordLength = 8;
    Random random = new Random();

    while (newRandomPassword.Length != passwordLength )
    {
        int randomNumber = random.Next(48, 122);
        if (randomNumber != 95 && randomNumber != 96)
            newRandomPassword += Convert.ToChar(randomNumber);
    }

    return newRandomPassword;
}

Next, we need to update the web.config file to define our new class as a provider for the Membership system.

<membership defaultProvider="MySqlProvider">
<providers>
<add name="MySqlProvider" type="MyNamespace.MyMembershipProvider" connectionStringName="MyConnectionString" applicationName="My Application" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" maxInvalidPasswordAttempts="1000" passwordAttemptWindow="5" minRequiredPasswordLength="4" minRequiredNonalphanumericCharacters="0" />

</providers>

</membership>

Finally, we tell the included PasswordRecovery control to use our provider class, using the name specified in the web.config entry.

<asp:PasswordRecovery ID="PasswordRecoveryControl" runat="server" Width="385px" UserNameLabelText="" OnSendingMail="PasswordRecoveryControl_SendingMail" MembershipProvider="MySqlProvider"
OnUserLookupError="ShowPasswordRecoveryError" UserNameInstructionText="Enter your Email Address to receive your password">
</asp:PasswordRecovery>

This is a great testimony to the Provider pattern as a way to quickly reconfigure a system.

Pages ... 1 2 3 4 5 6