Thursday, May 24, 2007

asp:FileUpload not posting back?

This is fun.

Didn't really find a whole lot out there on this so I figured I'd post it just in case I ever forget :)
We had a little upload pop-up in an ASP.NET application. We are just using the 'asp:FileUpload' control for this. We have another regular ASP button that has a server-side click event that will perform some validation and then save the file into a database and a few other things. Well someone reported a bug stating that if you just typed in anything (ie 'asdf') then it wouldn't let you know that it was an invalid file. No validation would be performed. We'll I started looking into this and noticed that the button click event wouldn't even post back? It would only post back if you had something that was somewhat valid entered in. (ie. 'c:\bob.txt').
Well here's the reason. This happens only when using IE. This is an IE specific issue. If you try this same thing in FireFox or Opera you'll notice that the post back will be fire off just as expected. IE trys to validate this before calling back. So if you enter something in that is just invalid IE wont even bother posting back, thus you'll never see your lovely button click event ever being called.

Don't believe me. Try it for yourself. Here's a link to a site that already has a sample 'asp:FileUpload' control loaded. Try it in IE and then in some other browser both with valid files and some junk like 'asdf'. You'll notice you only get the postback with the junk data on non-IE browsers.

Tuesday, May 22, 2007

Silverlight Airlines

I stumbled across this today and had to link it here. It's just a cool Silverlight demo application from Microsoft that shows a few of the new really cool things you can accomplish with the new Silverlight (previously WPF/E) project.

If you don't already have the Silverlight 1.1 installed you'll need it before the demo will work. You can download it here.

Monday, May 21, 2007

.NET ActiveX Example. Javascript event wireup. SSL

Okay if you read my last post and are wanting some answers (visual ones that is) then here ya go! :)

Skipping along to step#2
Here's an example of an interface used for events that you wanna hook up with in JS

    [Guid("00000000-0000-0000-0000-000000000000")]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
[ComVisible(true)]
public interface IExposedEvents{
[DispId(0x60050000)]
void DoSomething(string someString);
[DispId(0x60050001)]
void DoItAgain(int someInt);
}

Obviously you're gonna wanna put a valid GUID in there. So basically the second attribute, after the GUID, just says that this is a dispatch interface that will be exposed to COM. The second line is just re-iterating that this will be visible to COM. The [DispID]'s are used to uniquely identify the events to COM. These id's can be simple ints '[DispID(0)]' if you'd like, just make sure they're unique. You don't wanna have 2 events with the same dispId.

Next is the interfaces used to expose properties/methods...

    [Guid("00000000-0000-0000-0000-000000000000")]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
[ComVisible(true)]
public interface IExposedMethods{
void SetSomeVariable(string newVar);
string GetSomeVariable();
}

Again you want a unique GUID. This interface is nearly identical to the Events interface. The only difference is that you don't need the dispId's for the properties/methods that will be exposed.

Now here is the UserControl class

    [Guid("00000000-0000-0000-0000-000000000000")]
[ProgId("WindowsFormsUserControl.UserControl")]
[ClassInterface(ClassInterfaceType.None), ComSourceInterfaces(typeof(IExposedEvents))]
[ComVisible(true)]
public partial class MyControl: UserControl, IExposedMethods { //your code }

Okay so this one is a little different now. You still need the GUID (Well you don't HAVE to, read my last post. But if you wanna expose events in JS and use SSL then you need it). The ProgID is used to simply return the programmatic identifier for the specified COMAddin object. The next line starts off by saying what kind of interface is going to be generated for the exposed COM object. Here we are saying we don't want to generate one 'ClassInterfaceType.None'. The other 2 options are AutoDispatch and AutoDual which will auto generate an interface to expose for you (If you don't have any events to expose you could just write the user control with no interfaces and select one of these 2 options). The last part of this line is saying we want to use a specific type to expose this attributed class's events to COM.

So once you've got your control ready to go (created strong name, regasm'd it, etc) then you're ready to write the Javascript code in your .asmx file.

<object id="Bob" classid="clsid:00000000-0000-0000-0000-000000000000"></object>

This will place the custom control onto your form (if it's within the right tags, ie <div> <body> etc.). Next all you need to do is hook the event

<script for="Bob" event="DoSomething(someString)">
//Some code here... whatever you want to do :)
</script>

Like I said in my previous post you could also do it this way

<script>
function Bob::DoSomething(someString) {
//some code
}
</script>
I've had more success with the first approach, but it's silent so if you have a problem you wont know until you fire your event and it simply doesn't work.
Now you should be able to write some Custom Controls that you can hook up to JS events AND work with over SSL (Just make sure you register the assembly on the machine you want to see the controls on)
And again this is for SSL/event controls. If you just want to make a control for a public site over non-ssl without registering the controls on the clients then you don't have to take this exact approach. There is another way! Hopefully I can get some time and I'll do another post or two on this topic..

.NET and ActiveX

Wow, what a lot of trouble it can be to just get some ActiveX going in ASP.NET. Some may ask why you would want to even incorporate this technology which is only supported in Internet Explorer and which opens up a can of security worms. Well sometimes you gotta do what you gotta do and this is the best thing to use for some situations. The project I'm currently working on is a web based customer service type application and one request from one of our customers is that they would like our application to respond to their phone IVR. So that when employees receive calls, our web app will automatically respond by loading the customers info before the agent answers the phone. Hey it's nice to be greeted by 'Good morning Mr. Wilson what can I help you with". This is a situation where we kinda needed to use ActiveX. Well the good news is is that you can do this in .NET, the bad news is is that it can be very picky sometimes and it seems there isn't a whole lot of info out there about this topic (There is on Win32, but not .NET).

 

Okay, so here's the good stuff you came here for :)
First - you're gonna want to create a custom control that you can drop somewhere on your ASP page. We kept ours out of our existing solution and made a new solution just for our ActiveX stuff. (new class library solution -> new user control)
Second - If you're gonna want to be able to call methods / set variables etc AND respond to events (like mouse click, or custom events like the IVR is sending you a call) you MUST create two interfaces. One for events only and the other for methods/properties etc. These interfaces will be exposed to COM and will be the things your web page / other applications will communicate with. (example of all this will be on the next post)
Third - You will need to give all of your events [DispId(some unique int)] attributes
Fourth- You need GUIDs for your interfaces and custom control class/object. If you're using VS2005 it's easy just do 'Tools -> Create GUID'. (You don't HAVE to have GUIDs if you're making a plain jane control.. But if you want to use it over SSL and hook up events in JavaScript then you're gonna need to use them for sure)
Fifth - Right click on your the project your custom control is within and select 'Properties', go the the 'Build' settings and check the 'Register for COM interop' box. If you wanna be able to respond to COM you gotta set it.
Sixth - Register your new dll created when you compiled your new custom control. The old way, Win32 way, to do this was with 'regsvr32.exe'. The way you do it in .NET is to open up the VS Command Prompt, navigate to your .dll and type 'regasm /codebase customControl.dll'. Regasm is short for 'RegisterAssembly'. The '/codebase' will set the codebase in the registry. (Now you don't HAVE to do this step either... But again, if you wanna use it over SSL and respond to events and things your gonna need to register. Otherwise you don't have to)
Seventh - Add your new custom control to your ASP page. '<object id="Bob" classid="clsid:00000000-0000-0000-0000-000000000000"></object>'. Replace the 000... GUID with the one you used for your custom control. If all went well you should be able to see your custom control on your page. There is another approach to this, you could use 'classid="customControl.dll#namespace.classname' but then the dll has to reside in your ASP site, AND the KICKER is that this will NOT work if you plan on using SSL. So it's just easier to use the GUID :)... (But you don't HAVE to do it this way, you can use the second way 'dll#namespace.class' but.. it just wont work with SSL :)
Eigth - To wire up your events there are also two approaches. The first '<script for="Bob" event="yourEvent(args)"> some script </script>' is the the approach that seems to work the best. This will also not throw JS exceptions if it doesn't hook/sink correclty. The second approach which may let you know there are problems is '<script> function Bob::yourEvent(args) { } </script>'. I would recommend the first since it seems to work a little more often.
Ninth - Okay the last step is to strong name your assembly. This is pretty easy. Just right click on your project -> properties. Go to the bottom tab 'Signing' and check the box 'Sign the assembly'. Then in the drop down select 'New'. This will bring up a pop-up. Type in a name for your key file (this can be anything you'd like) and you can supply a password or uncheck the 'Protect my key file with password' if you don't want a password. Click 'okay' and you're done!
So there are the basics. Now we'll do some code examples in the next post, if you're a visual kinda person like me :)

Also check out Eber's blog to. We both worked on many of the ActiveX problems so we'll both be posting about some of the issues. So if I don't answer you question he may have it in his blog :)

Tuesday, May 08, 2007

Ignoring SSL Certificate Problems

Have you ever run across these problems when trying to connect to a secure web service?

"The remote certificate is invalid according to the validation procedure",
"The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel."

Usually this is caused by a bad certificate on the server side, but what if you want to connect anyway, maybe you trust the remote system and just don't care. How do you get around this? How do you get your code to ignore these warnings and continue? We'll if you're using .NET 2.0 it's really easy (still pretty easy in .NET 1 but it takes a little more work). You'll need to use the ServicePointManager class, and add this using statement (if you don't want to use the fully qualified names anyway).

using System.Security.Cryptography.X509Certificates;
Now all you need to do is add this bit of code somewhere before you make the call to the web service.
ServicePointManager.ServerCertificateValidationCallback = delegate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors policyErrors) {
return true;
};
The 'ServerCertificateValidationCallback' is used to custom validate server certificates. By default it is null, and since the above code just returns 'true' all certificates will be valid now. You could add some more custom code to this if you wanted to do your own validation, say you only want it to be valid if the cert comes from a specific place etc.
You can also check out this MS link as well that has the same code as above

Tuesday, May 01, 2007

F#... Hot or Not?

Eber and I recently decided we wanted to play around with a new language. We looked into a few of the current popular ones like Ruby or Python (Since we can use them in VS, IronRuby / IronPython), but they are all 'fairly' similar. (I put in IronRuby instead of Ruby in Steel because one is $199 and the other is not, and hey... free is good ;)  ) So we decided to go somewhere new, a language that is quite a bit different, F#. F# is an experimental language from Microsoft that shares the same syntax style as OCAML (Object CAML). It's a functional language which made it different enough for us.

So if you wanna play along here's what you're gonna need:

1-Visual Studio 2005 (does not currently work on Orcas)
2-F# (download the newest version (1.9.1) here, the F# home page currently doesn't have the newest release listed)
3-Some patience since there is not a whole lot of stuff out there about F#. But there is quite a bit of stuff out there for OCAML (Which is where I've been getting most of my info since most of it will work in F#)
One other things that led us to F# was the amount of influence it has had on C#. What you say? Well yes there are many things from F# that have made their way into C# from this experimental language. One of the newest things are Lambdas, as of C# 3.0, which make the new LINQ possible (where they are used everywhere!). So if all of this hasn't gotten you the least bit excited it's also a type safe language, you can do scripting, or objects, and since it's a .NET supported language you can access your F# DLL's from your C# projects, and vice-versa. Since it is a .NET supported language and it isn't widely used you will find lots of examples out there that use quite a bit of the .NET librarys.

ex. You may see quite of bit of this

Console.WriteLine("Hello");; // Looks familiar if you use C#

instead of this

print_string("Hello");; // This is the F# stuff (which is also the same in OCAML)

print_newling();;

So one thing you may notice right of the bat is the double ';' at the end of the lines. This is one of the first things that had stumped me, and I was hard pressed to find anything on the F# website. So I started looking around the OCAML pages and found this nice explanation of when to use no ';' when to use a single ';' and when to use double ';' (scroll down a little over half way down the page until you find 'Using and omitting ;; and ;')

So far I give F# a potential 'HOT' vote, since I haven't done a lot with it as of yet. It's a different way of thinking, since it is a functional language, and it's also a pretty flexible language. Eber and I plan on doing more with F# so expect more blogs from the both of us in the future, if you're interested in F# if not keep checking our blogs for other fun stuff :)