Friday, 30 October 2009

MySQL Connector - Error with Multiple Versions on Dev Machine - "...column 'InvariantName' is constrained to be unique..."

I installed another version of the MySQL connector on my development machine yesterday, parallel to my existing version - so I now have both 5.0.6 and 5.07 installed. I use these two different versions of it for a couple of different applications I work with. Now however I find that I’m unable to open EDMX files in projects using Entity Framework. I get the following error when I double click on the designer file:



Looking at the machine.config file, I can see there are 2 entries in there for MySQL and sure enough, the invariant names are the same:



<DbProviderFactories>
...
<add name="MySQL Data Provider" invariant="MySql.Data.MySqlClient" description=".Net Framework Data Provider for MySQL" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data, Version=5.0.7.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" />
<add name="MySQL Data Provider" invariant="MySql.Data.MySqlClient" description=".Net Framework Data Provider for MySQL" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data, Version=5.0.6.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" />
...
</DbProviderFactories>



The solution - basically instead of uninstalling one of the MySQL Connectors, I just commented one of them out in the machine.config file. Now my EDMX designer works again ;-)

Thursday, 29 October 2009

The potential PROs and CONs of using ASP.NET MVC 1.0 for your next web project...

PROS:

  • Properly testable and allows you to develop more elegant code.
  • You are ‘forced’ to apply the MVC design pattern by the framework, so the only option is to have a properly defined data model + business logic layer (Model), presentation layer (View) and controller to manage their interaction.
  • You also don’t have to deal with the ASPX page lifecycle.
  • Because ASP.NET MVC is RESTful also, it can be used easily with jQuery/JSON, etc - the way the application is organised is more like a RESTful service. The ‘Views’ are like enhanced transforms, layered across the top of the service, that convert the dynamic application output into HTML (if that’s how you choose to define your View), rather than a series of concrete ‘pages’.
  • Because of the way the URLs are put together (i.e. you mostly don’t need to use a suffix - like .aspx - especially under IIS7), the style is better aligned for web search engine optimisation.
  • Web design is much easier - if you get a nice HTML page from a designer, it’s much easier to integrate with the application.
  • You don’t end up with crazy HTML element names, view state in the page, etc - there appears to be much less ‘behind-the-scenes’ messing around with the output HTML by the ASP.NET process than there is with WebForms.

CONS:

  • It’s a different way of thinking than WebForms, from a Microsoft web-dev perspective - almost completely. So there’s a learning curve. When you get used to it however, it does seem more ‘natural’ approach than WebForms.
  • It’s new, so although MVC version 1.0 is integrated into .NET 3.5 SP1 (although I understand MVC 2.0 is now available - with VS2010 Beta...?); you need to know a few special tricks to get things up and running in production. You need to download some ‘futures’ resources from CodePlex, etc.
  • There are not that many people out there using it yet, so there’s less support and material out there, if you need help.

SQL Server - database mail - just “because you can”, doesn’t make it right!!

Was thinking the other day (discussing across the office with a couple of colleagues actually ;-) about using database mail out of SQL Server in relation to using .NET components to send mail – kind of a hot topic for us, or at least one that's heating up.

 

My opinion on this type of thing (thankfully shared by our DBA) is that despite the fact that SQL Server provides a very adequate email platform, and there are lots of MSDN type examples out there showing you how do this type of thing, sending bulk email from the database server (for – e.g. – an email marketing campaign type stuff) is bad form.

 

For one thing you're putting unnecessary load on the server and slowing down applications that are using the server for doing what it's designed to do (manage and serve up relational data), and for another thing – there is simply much better support for doing this type of thing outside of the database, in application code.

 

Here's my analogy; say you want to do some work on your car – among other tools, you have an adjustable spanner and a professional socket set. Using database mail for everything is like using the adjustable spanner for everything "because you can". You save overhead by not having to change tools here and there, but you spend much more time overall trying to get to places in the car that a professional socket set could reach with ease. And your mate who you asked to help you ends up standing around because he wants to use the spanner too…

 

The moral of the story - just "because you can", doesn't make it right!!

 

 

Sunday, 18 October 2009

Using ASP.NET MVC 1.0 with Dynamic Data...

Getting Started:

Dynamic data is part of 3.5 SP1, but if you want to use MVC you need to specify that the DLLs should be copied to your \bin folder:




Setting “Copy Local” to True for the highlighted DLLs will copy them to the output folder automatically when you build and publish. Makes a bin-deploy of the MVC project easier.


...And Then:


Then, go to this site:

...and get this sample:

You need to reference system.web.dynamicdata:

Here's what needs to be done to enable configuration of DD for a new site:

Need to use entities data source DD project if using entities:

Need to reference the System.Web.Entity assembly:

...or you get this error message: “The type or namespace name 'EntityDataSource' does not exist in the namespace 'System.Web.UI.WebControls'”

Copy the following code into your Global.asax.cs file in order to get your Dynamic Data working in the original MVC project, with your existing entities:


MetaModel model = new MetaModel();
model.RegisterContext(typeof(), new ContextConfiguration() { ScaffoldAllTables = true });
routes.Add(new DynamicDataRoute("{table}/{action}.aspx")
{
Constraints = new RouteValueDictionary(new { action = "List|Details|Edit|Insert" }),
Model = model
});


Authentication – good article:

Dynamic Data – displaying database errors:

Entities Framework: If/When you get this error - “Unable to create a constant value of type 'Closure type'. Only primitive types ('such as Int32, String, and Guid') are supported in this context.”:

Need Dynamic Data Futures DLL

Handling DD custom views:


Other Tips:

File upload field template:

If you put html tags into any of the fields you want to edit in your dynamic data views, you will cause it to stop working.

Good link for DD date formatting:




Saturday, 17 October 2009

Web.Config Inheritence to Virtual Directory Application - 'inheritInChildApplications' Attribute...

Had a problem recently where an ASP.NET MVC 1.0 site was not reading the web.config in the virtual directory that we has created for it (using Helm). It was defaulting back to the main site's web.config file (in the wwwroot directorty). The error message we got was like this:

============================================================

Server Error in '/blah' Application.

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 'MagicAjax' or one of its dependencies. The system cannot find the file specified. (<path_to_folder>\wwwroot\web.config line 133)

============================================================

...so, (FYI, this has nothing to do with MagicAjax, just using this error as an example of the type of problem that can crop up) the site is trying to read '<path_to_folder>\wwwroot\web.config', instead of the web.config file in the virtual directory we had setup, which was  '<path_to_folder>\wwwroot\blah\web.config'. 

This problem is something that can be handled in the top level (wwwroot) config file by using the 'inheritInChildApplications' attribute – the following article provides further detail:


I encountered this error on the evening of deployment – a couple of long hours of tense Googling yielded this result, which worked...

Monday, 14 September 2009

Dynamically Alter a PDF in ASP.NET Using iTextSharp...

Here's a class/method that can be used to generate a PDF order form on the fly, on your website.

It's only really applicable in the current state if you had a site that was selling a single product at a time, but this provides a proof-of-concept which you could extend/evolve to do more-or-less whatever you want, within reason. You wouldn't want to be (re)generating the PDF each time an order was placed for example, but it could be useful if you had a fax order form for a product(s) and their price(s) needed to be changed by (e.g.) 10%:


using System;
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;

namespace YourProject.Utils
{
public class PDFGeneration
{
public static void RegenerateFaxOrderForm(
string title,
string rrp,
string price)
{
// get the filename
#if DEBUG
string fileNameFaxOrderForm =
@"\Content\Images\FaxOrderForm\FaxOrderForm.pdf";
string fileNameFaxOrderFormOriginal =
@"\Content\Images\FaxOrderForm\FaxOrderFormOriginal.pdf";
#else
string fileNameFaxOrderForm = HttpContext.Current.Server.MapPath("~/Content/Images/FaxOrderForm/FaxOrderForm.pdf");
string fileNameFaxOrderFormOriginal = HttpContext.Current.Server.MapPath("~/Content/Images/FaxOrderForm/FaxOrderFormOriginal.pdf");
#endif
PdfReader pdfReader = null;
PdfStamper pdfStamper = null;
try
{
pdfReader = new PdfReader(fileNameFaxOrderFormOriginal);
pdfStamper = new PdfStamper(pdfReader, new FileStream(fileNameFaxOrderForm, FileMode.Create));
BaseFont bf = BaseFont.CreateFont("Helvetica", BaseFont.CP1252, BaseFont.NOT_EMBEDDED);

PdfContentByte overContent = pdfStamper.GetOverContent(1);

Rectangle pageSize = pdfReader.GetPageSize(1);
Rectangle cropBox = pdfReader.GetCropBox(1);

overContent.BeginText();
// titles
overContent.SetFontAndSize(bf, 11);
overContent.SetTextMatrix(60, 583);
overContent.ShowText(title);
// RRP
overContent.SetFontAndSize(bf, 11);
overContent.SetTextMatrix(270, 583);
overContent.ShowText(rrp);
// prices
overContent.SetFontAndSize(bf, 11);
overContent.SetTextMatrix(345, 583);
overContent.ShowText(price);
// write it out
overContent.EndText();
}
catch (Exception ex)
{
// do what you like with the exception
Console.WriteLine(ex.Message);
}
finally
{
if (pdfStamper != null)
{
pdfStamper.Close();
}

if (pdfReader != null)
{
pdfReader.Close();
}
}
}
}
}


...obviously using iTextSharp here, which is IMHO a truly excellent library!

Monday, 17 August 2009

Using jQuery to make HTTP GET requests for JSON functions in ASP.NET MVC ...

Doesn't work for IE...because IE caches the results of the $.getJSON(...) HTTP GET query and you end up with the appearance of the same response every time

For example, I was writing some code that required a countdown this-evening and everytime I refreshed my IE window, I was starting from the same place I sarted before - e.g. if there were 32 minutes 7 seconds remaining on the counter, the counter counts down 10 seconds and you refresh the browser, you end up back at 32 minutes 7 seconds...frustrating, cause (of course) the problem only occurs in IE!

Way to solve it is the use a POST request. Go into your jquery-1.3.2.js file (or whatever version you're using), and find the getJSON method that you're using the make the GET request. Underneath that, paste in the following code:

postJSON: function(url, data, callback) { 
   return jQuery.post(url, data, callback, "json");
},

...then simply change the javascript methodcall you're making to postJSON instead of getJSON. Oh, and you'll need to decorate the method you had exposed in your ASP.NET MVC controller with the [AcceptVerbs(HttpVerbs.Post)] attribute, so as it knows it's a POST method. Apparently it's officially acceptable to cache the output of the HTTP GET command, because of it's idempotent nature: http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html

So I guess despite my frustration, I learnt two new things today; the real intention of the HTTP GET command and the word 'idempotent' ;-)

Monday, 27 July 2009

How to Prevent Debugger Step-Thru Spontaneously Dying in IIS 7.0 ...

This frustrated me for a while until I Googled it and discovered it’s a preventable thing.


I guess there’s a good reason for it (somewhere), but when your stepping through debugging your ASP.NET website and just getting to the bottom of an issue when the debugger quits saying that the web server was unresponsive for 59.999 seconds, it can get on your nerves ;-) Here’s how to prevent that from happening…


Go to the application pool for the app you’re debugging and check out the ‘Advanced Settings’:



… set ‘Ping Enabled’ to false and you will find you can leave your debugger hanging as long as you like (again) while you dig through stuff…

Friday, 3 July 2009

ASP.NET MVC + Dynamic Data ... <tagMapping /> and App_Code folder

If I have a <tagMapping /> config file entry associated with a class in the App_Code folder, I seem to get the following error message without fail, at runtime:

Parser Error Message: The type 'MyNamespace.CustomDynamicValidator' is ambiguous: it could come from assembly 'C:\Windows\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\root\50512c51\4b64a02d\App_Code._ejsf967.DLL' or from assembly 'C:\WebApps\MyApp\ MyApp\bin\MyAssembly.DLL'. Please specify the assembly explicitly in the type name.

No biggie, just kind of a PITA actually. Now I need to put any code I'm using <tagMapping /> with in the root directory, and then it works fine.


Wednesday, 20 May 2009

net time

Sync the time on your local machine with a network server's:

net time \\timesrv /set /yes



Monday, 18 May 2009

Google - microsoft related information only switch

Limit your search to MS related stuff only!

 

http://www.google.com/microsoft.html

 

(I'm not sure what other Google switches are out there)

Sunday, 17 May 2009

ASP.NET MVC v1.0 - Generic Html.ActionLink(...)

... was removed for release of version 1.0.

This has been documented in about a million other places, but not many posts reference where to get the 'ASP.NET MVC v1.0 Futures' DLL (as opposed to the BETA Futures).

It's here:


You need this DLL if you want to use the generic version of the ActionLink - which can be used like this:

==================================================================

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
<%@ Import Namespace="Bernard.Controllers"%>
<%@ Import Namespace="Microsoft.Web.Mvc"%>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Index
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

    <h2>Index</h2>
    
    <ol>
        <li>
            <%= Html.ActionLink<MyController>(c => c.Index(), "MyStuff")%>
        </li>
    </ol>

</asp:Content>

==================================================================

As per the above example - remember to throw the additional 'import' statement in ...

Monday, 23 February 2009

My First Lambda Expression ...

Instead of using the following code to bypass an invalid site certificate for the HTTPS web-service I'm using:

System.Net.ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CertificateValidation);
...
private bool CertificateValidation(
            Object sender,
            X509Certificate cert,
            X509Chain chain,
            SslPolicyErrors Errors)
        {
            return true;
        }

You can use a lambda expression to do the same thing - like this:

System.Net.ServicePointManager.ServerCertificateValidationCallback = ((sender, cert, chain, Errors) => true);

Sweet ;-)

Thursday, 12 February 2009

Creating New User in SQL Server 2K5 and 2K8

Basically the GUI doesn't work properly - so just script it! Like this:

CREATE USER [NT AUTHORITY\NETWORK SERVICE]
FOR LOGIN [NT AUTHORITY\NETWORK SERVICE]
WITH DEFAULT_SCHEMA=[your_schema]
GO

The problem is when you want to assign a default Schema to your User - it just won't do it. You select 'your_schema', and hit 'Ok':



... only to find that your queries don't run as expected and when you go back into the settings GUI, the default Schema has gone back to 'dbo'. Grrrr ...

Thursday, 22 January 2009

Building SOAP Web-Service Clients in .NET 2.0 - Notes To Self ...

This post is a few notes to help me next time I come across issues building a web-service client ...

Some often used code snippets:

For completeness, init the client proxy:

If you are using WSE: ServiceWse svc = new ServiceWse();

Else: Service svc = new Service();

Set the web-proxy to null, so as to bypass a firewall:

svc.Proxy = new System.Net.WebProxy();

Set the version of SOAP - by default .NET uses 1.1 - incase you need another version, you can do this:

svc.SoapVersion = System.Web.Services.Protocols.SoapProtocolVersion.Soap12;

Code to use if your client needs to use UsernameToken authentication (WSE 3.0):

Microsoft.Web.Services3.Security.Tokens.UsernameToken usrToken = new Microsoft.Web.Services3.Security.Tokens.UsernameToken("UID", "PW", Microsoft.Web.Services3.Security.Tokens.PasswordOption.SendHashed); svc.RequestSoapContext.Security.Tokens.Add(usrToken);

Code to use if you need to bypass an invalid certificate:

System.Net.ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(myCertificateValidation); ... public bool myCertificateValidation(Object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors Errors) { return true; //You should check the cert yourself here }

This all relates back to a couple of previous posts that I have made on this matter:

http://bernard-on-technology.blogspot.com/2007/12/how-to-change-version-of-http-that-your.html
http://bernard-on-technology.blogspot.com/2008/02/add-or-remove-web-service-protocols-at.html

Error messages when instantiating the generated client proxy, such as:


WCF Service Reference: "The XML element 'BlahResponse' from namespace 'http://namespace' references a method and a type. Change the method's message name using WebMethodAttribute or change the type's root element using the XmlRootAttribute."

.NET 2.0 Web Reference: "Method webServiceClient.Blah can not be reflected."

Can be from any number of issues. However, first port of call should be to pick a function that you are confident works on the web-service (use soapUI to establish this), then comment out the code in Reference.cs (or Reference.vb) for all other web-methods. Retry instantiating the client proxy with only the web-method that works implemented. It could be that you have some web-methods in there that are not properly implemented at the web-server and are causing a bit of chaos in the generated client code.

Error messages in response to a request to the web-service:

In your SOAP envelope response (received from a Java web-service): "Error reading XMLStreamReader."

In this case, check the protocol versions for HTTP and SOAP that your client is using. You will definitely get this message if your SOAP version is not the same as that of the service, and I think the message is similar if the HTTP version is different(?).

Diagnosis tools to use:

Fiddler: for diagnosis of HTTP traffic - picks up incoming and outgoing XML - http://www.fiddlertool.com/fiddler/

soapUI: highly configurable test client for web-services - http://www.soapui.org/

SoapExtension class: allows you to capture incoming and outgoing SOAP traffic - http://msdn.microsoft.com/en-us/library/system.web.services.protocols.soapextension.aspx

Auckland SQL Server User Group

Did a talk at last night's meeting of the Auckland SQL Server User Group.

My slides can be found here: http://www.aucklandsql.com/Library/Presentations.aspx

My talk was on the new SQL Server 2008 Spatial Data Types.

When I figure out how to blog things like .ppt files, I'll put it up here too!

Migrating (and Open-Sourcing) an Historical Codebase: SVN-to-Git

I have a SVN repo on my local machine that I have been shoving stuff into since before I knew how to use revision control systems properly (...