Monday, November 21, 2005
March to final install of RSG
After a week’s relax, here I go again, march to the final install of this long, long project. Expecting R4 to be installed by Jan 15th . Should be offline for some more months…
Labels:
RSG
Friday, November 04, 2005
Hurray! End of Prod Support.
I have to agree, you can be a expert in architecting systems, but knack of fixing a production issue can't be compared to that. If you think zeroing in the problem code is tough, the tougher part is yet to come, no isn’t fixing the code, fixing the corrupted data, i was so lucky that i had to meet this scenario more than once.
Whatever today is end of 45 day support for R2/3, meaning no more calls from operators during nights and weekends! If we find bugs in production after so much testing, one should understand the fact, bug free system is more a difficult task as the size and complexity of the system increases. NUnit/TDD power is only as good as test fixture's strength.
But after initial hiccups, the system did come back and stabilize pretty well, may be it will become as good as mainframe as time goes, okay, at least before this becomes legacy hahaha...
Whatever today is end of 45 day support for R2/3, meaning no more calls from operators during nights and weekends! If we find bugs in production after so much testing, one should understand the fact, bug free system is more a difficult task as the size and complexity of the system increases. NUnit/TDD power is only as good as test fixture's strength.
But after initial hiccups, the system did come back and stabilize pretty well, may be it will become as good as mainframe as time goes, okay, at least before this becomes legacy hahaha...
Labels:
RSG
Saturday, September 10, 2005
Finally the Big day is here !!!
After more than 11/2 year of designing/developing/testing/testing/testing/... finally i reach the end of tunnel for Release 2/3.
Release2/3 is going live tomorrow,..
hopefully the light at the end of tunnel is not an incoming train ;-)
Release2/3 is going live tomorrow,..
hopefully the light at the end of tunnel is not an incoming train ;-)
Labels:
RSG
Sunday, August 28, 2005
.NET Logging Framework (Options)
After seeing the limitations with EIF, i would like to see other logging options.
Will update this post, once i get full details ...
okay for now the issues we face with EIF,
EIF configuration for COM+ and GAC components (esp we have a lot of common components) is not deployment friendly;
No option to log to a text file;
No decent tracelogs viewer utility, one that comes with install is kids play;
CustomSink seems to be really costly if used with full force
But i have to agree, EIF's configuration power meets any enterprise demands, but i heard there won't be a version for Whidbey.
Will update this post, once i get full details ...
okay for now the issues we face with EIF,
EIF configuration for COM+ and GAC components (esp we have a lot of common components) is not deployment friendly;
No option to log to a text file;
No decent tracelogs viewer utility, one that comes with install is kids play;
CustomSink seems to be really costly if used with full force
But i have to agree, EIF's configuration power meets any enterprise demands, but i heard there won't be a version for Whidbey.
Labels:
.NET
Friday, July 01, 2005
p&p CMAB encryption feature
I still don't find time to put down my ramblings on CMAB, but today i was asked to tweak the block to use client's encryption helper component instead of out-of-box encryption. Unlike other blocks, I have a great respect to this block for its sound design (as usual no COM+ support).
I wonder why didn't MSFT create a encryptionHelper component, that can be used across other blocks or a stand alone encryption application block, instead of implementing the algorithm in the CMAB block itself???
I wonder why didn't MSFT create a encryptionHelper component, that can be used across other blocks or a stand alone encryption application block, instead of implementing the algorithm in the CMAB block itself???
Thursday, May 19, 2005
Do Yourself Mainframe Interop in 1 Day !!!
Mainframe Interop with Avalon.
Cool Avalon frontend for green-on-black mainframe screen. Must see all new avalon Carousel control, you should see the vector graphic in work when he zooms in-out. But i don't believe this can be good way to show a hierarchical data {may be for simpler stuff's}. But i like to see it used in user navigation.
SwankyUI aside, we can see the microsoft strategic lean towards interoping with PlatformX.
What next, ... platform neutral Office suite :-)
Cool Avalon frontend for green-on-black mainframe screen. Must see all new avalon Carousel control, you should see the vector graphic in work when he zooms in-out. But i don't believe this can be good way to show a hierarchical data {may be for simpler stuff's}. But i like to see it used in user navigation.
SwankyUI aside, we can see the microsoft strategic lean towards interoping with PlatformX.
What next, ... platform neutral Office suite :-)
Labels:
Scraps
Tuesday, May 10, 2005
Visual Web Developer 2005 Express Edition demo by Scott G
*Demo of next version of ASP.NET*, i was expecting some ASP.Net show, but anyhow Scott G, showed some of the feature additions in the new Visual Web Developer 2005 Express Edition, really a lot of improvements {may be lot of *bug-fixes* too}. Some of the feature i liked, Code refactor-ing option, debug mode code change, improvement in design/source mode of page, auto compile of changes, help on exception causes, ...
But when VS.NET was released, i was told it will be one tool for all, but why now a spl edition for web development tool, are we going back to the age of launching multiple apps to work on different projects???
But when VS.NET was released, i was told it will be one tool for all, but why now a spl edition for web development tool, are we going back to the age of launching multiple apps to work on different projects???
Labels:
.NET
Monday, May 09, 2005
Avalon says "Hello World"
After fighting for more than an hour, I was able to develop a *Hello World* win app in Avalon {March ’05 CTP}, it was tough to get help online as so much changes are happening to the framework, it took me some time and guessing to find the PresentationCore assembly and really tough time understanding what msbuild was expecting in the .proj. I am still yet to find how to use XAML with msbuild.
Long way to go…..
Long way to go…..
Labels:
Scraps
Wednesday, May 04, 2005
Joint system testing completed
As i am wrapping-up the final program validation, i should thank everyone of offshore team. I happen to dig out some statistics of the work we completed,
7 online process 15 batch/components
~51,335 Lines of Code excluding comments, white lines
0 defects, 6 Accepted changes
I would have been happy if we had a chance to repeat this in FundRaiser, if not for that CR, that scoped out the application.
Here goes the list of dedicated team members,
Arumugam, Praveen
Raja Simman, Kamalesh Kumar
Chinnasamy, Ramesh babu
Elumalai, Dhanasekar
Sampathkumar, MuthuAnitha
Prasanna Subramanian;
Sundaresan, Raghuraman;
Cuppala Janakiram, Roopesh Kumar
Elwin, Annecca
Kandimalla, Neeraja
Karthikeyan, Ramesh Kulothunan
Narayanan, Sajitha
Seethapathy, Ganesan
Selvakumar, Annam
And my thoughts,
7 online process 15 batch/components
~51,335 Lines of Code excluding comments, white lines
0 defects, 6 Accepted changes
I would have been happy if we had a chance to repeat this in FundRaiser, if not for that CR, that scoped out the application.
Here goes the list of dedicated team members,
Arumugam, Praveen
Raja Simman, Kamalesh Kumar
Chinnasamy, Ramesh babu
Elumalai, Dhanasekar
Sampathkumar, MuthuAnitha
Prasanna Subramanian;
Sundaresan, Raghuraman;
Cuppala Janakiram, Roopesh Kumar
Elwin, Annecca
Kandimalla, Neeraja
Karthikeyan, Ramesh Kulothunan
Narayanan, Sajitha
Seethapathy, Ganesan
Selvakumar, Annam
And my thoughts,
The worker becomes all the poorer the more wealth he produces, the more his production increases in power and range. The worker becomes an ever cheaper commodity the more commodities he creates. With the increasing value of the world of things proceeds in direct proportion to the devaluation of the world of men. Labour produces not only commodities; it produces itself and the worker as a commodity -- and does so in the proportion in which it produces commodities generally.
Karl Marx, Economic and Philosophic Manuscripts (1844)
Labels:
RSG
Friday, March 11, 2005
Interactive india map
waited for something like this for long time, http://mapmyindia.com
Labels:
Scraps
Wednesday, March 09, 2005
thnx guys :-)
It’s high time that i should appreciate my offshore designer/developers/future architects in Chennai, TN, India. We are about to test our new system in onsite and its better i thank them now, before we get to usual onsite-offshore conflict. As i recollect, actually i don't remember any such incidents, may be i am lucky or guys were so tolerant to my crap comments on their design/code ;-)
Being a first project in their career for many, everybody put up a great show. All the best of your future endeavors and of course to our upcoming testing phase. Enough blabber, here goes my offshore development team, following the tradition; it was not intentional if i leave any name here and the list is not sorted in any order of preference.
Annecca E, Praveen A, Ramesh babu C, Roopesh Kumar CJ, Dhanasekar E, Neeraja K, Ramesh Kulothungan K, Muthu Anitha SK, Sajitha N, Ganesan S, Annam S, Prasanna S, Sonu S, Kamalesh Kumar & Suhanya J
If i had to tell anything, it would be, "There is always a better design!" (may be not from me) Good luck and happy .netting
Being a first project in their career for many, everybody put up a great show. All the best of your future endeavors and of course to our upcoming testing phase. Enough blabber, here goes my offshore development team, following the tradition; it was not intentional if i leave any name here and the list is not sorted in any order of preference.
Annecca E, Praveen A, Ramesh babu C, Roopesh Kumar CJ, Dhanasekar E, Neeraja K, Ramesh Kulothungan K, Muthu Anitha SK, Sajitha N, Ganesan S, Annam S, Prasanna S, Sonu S, Kamalesh Kumar & Suhanya J
If i had to tell anything, it would be, "There is always a better design!" (may be not from me) Good luck and happy .netting
Labels:
RSG
Tuesday, March 08, 2005
ultimate VS.NET addins
Happen to browse thro' Scott's list of ultimate VS.NET addins, CodeRush is really a *bomb*, a flash preview of one of the feature
Labels:
.NET
go google ...
If you are using yahoo maps/driving directions, then you should see google stuff, AFAIK, interactivity & super fast refresh blows you away. btw have u tried google local.
Labels:
Scraps
Monday, March 07, 2005
Yahoo ad-impression - cached but counted
explains a very clever technique, Michael Radwin from Yahoo on cache-busting technique (slides) they are using, more details in Scott's blog
Labels:
Web
Saturday, March 05, 2005
asp.net webservice output caching options and issues
We use WS as a fa·çade to underlying enterprise service components which handles all biz logic. And it was found some of the calls were to fetch some data that can be cached. So i thought of list out caching options i have,
1. Cache at client
2. HTTP 1.1 cache-capable device in the call path (Proxy server?)
3. Cache at WS layer
4. Use caching application block to cache data in ES
I am skiping the usual issues like caching in distributed environment, cache volatility, cache expiration policy, etc, just to concentrate on cache storage options.
Client cache is technique that i use in almost all apps i design. Hands down i should say a pretty simple approach, client had to be designed cache-aware and it will own all caching and its issues. Depending on cache data size and complexities; rich/smart or web app client will reap benefits accordingly.
HTTP 1.1 cache-capable devices, i haven't used this in any of my projects and i'll have to drill further to know the pro/cons on this one. But i heard there are some limitations to use HTTP cache for asp.net webservices
I'll defer the WS layer cache for a paragraph
Only way i see of caching in COM+ is using caching block, i can store cache with help of
Memory mapped file stream (it's an unmanaged code, do i like to use an unmanaged code? but if u think a while, windows is not a managed code that doesn't mean it is bad. If in next update of caching application block, p&p group implements a managed version of mmf storage, the client will no way know about this change and everybody is happy. Win FX (all new Win32 API) is all managed, ASP.NET 2.0 is 90% managed code, is looks like the trend will continue, its just a matter of perception)
SQL database (do i want to take the overhead of network? anyone has to weigh the benefits of caching over the network overhead)
Singleton object (Remoting? The popular and untruthful myth that remoting is hard, bad and its going away. I am no more going to reiterate, there will be a clear path of migration to Indigo and p&p or GDN will take care of this)
Ok now the fun of caching in WS, options ...
1. CacheDuration attribute, ok i set this for 60 secs and open the WS test page in IE and invoke the webmethod and i invoke again to see it output is cached, NO it was not cached. I google a bit and find it’s not me alone who is stumped by this.
**Webmethod caching doesn't work in WS test page in IE and works if used with a proxy class**, i had a strange feeling whether client proxy is somehow returning the data and not making the WS call, actually it not doing any of those WS call is actually made and its WS is the one which returns the cached output.
2. Applciation/Cache object, can use a Application or System.Web.Cache class and i have a feeling that CacheDuration attribute will in turn use one of this internally.
3. [Credits: Senthil] Having a private static variable in the WS class, this one bowls me out, somehow i was blind folded by words *HTTP is stateless* and I illiterately assumed that is applicable to WS. But i have to a doubt on how this will work in IIS process recycling, either in IIS5 (aspnet_wp) or IIS6 (w3wp.exe), will this static member data go away or retained during process recycling?
1. Cache at client
2. HTTP 1.1 cache-capable device in the call path (Proxy server?)
3. Cache at WS layer
4. Use caching application block to cache data in ES
I am skiping the usual issues like caching in distributed environment, cache volatility, cache expiration policy, etc, just to concentrate on cache storage options.
Client cache is technique that i use in almost all apps i design. Hands down i should say a pretty simple approach, client had to be designed cache-aware and it will own all caching and its issues. Depending on cache data size and complexities; rich/smart or web app client will reap benefits accordingly.
HTTP 1.1 cache-capable devices, i haven't used this in any of my projects and i'll have to drill further to know the pro/cons on this one. But i heard there are some limitations to use HTTP cache for asp.net webservices
I'll defer the WS layer cache for a paragraph
Only way i see of caching in COM+ is using caching block, i can store cache with help of
Memory mapped file stream (it's an unmanaged code, do i like to use an unmanaged code? but if u think a while, windows is not a managed code that doesn't mean it is bad. If in next update of caching application block, p&p group implements a managed version of mmf storage, the client will no way know about this change and everybody is happy. Win FX (all new Win32 API) is all managed, ASP.NET 2.0 is 90% managed code, is looks like the trend will continue, its just a matter of perception)
SQL database (do i want to take the overhead of network? anyone has to weigh the benefits of caching over the network overhead)
Singleton object (Remoting? The popular and untruthful myth that remoting is hard, bad and its going away. I am no more going to reiterate, there will be a clear path of migration to Indigo and p&p or GDN will take care of this)
Ok now the fun of caching in WS, options ...
1. CacheDuration attribute, ok i set this for 60 secs and open the WS test page in IE and invoke the webmethod and i invoke again to see it output is cached, NO it was not cached. I google a bit and find it’s not me alone who is stumped by this.
**Webmethod caching doesn't work in WS test page in IE and works if used with a proxy class**, i had a strange feeling whether client proxy is somehow returning the data and not making the WS call, actually it not doing any of those WS call is actually made and its WS is the one which returns the cached output.
2. Applciation/Cache object, can use a Application or System.Web.Cache class and i have a feeling that CacheDuration attribute will in turn use one of this internally.
3. [Credits: Senthil] Having a private static variable in the WS class, this one bowls me out, somehow i was blind folded by words *HTTP is stateless* and I illiterately assumed that is applicable to WS. But i have to a doubt on how this will work in IIS process recycling, either in IIS5 (aspnet_wp) or IIS6 (w3wp.exe), will this static member data go away or retained during process recycling?
Labels:
ASP.net
Monday, February 28, 2005
Future of .NET Remoting
Is .NET Remoting a dying technology? or Evolving to a unified distributed computing technology?
I heard that Ingo Rammer quoted "i havewasted two years of my life on .net remoting" in a conference in Frankfurt last year. Whether this is from a credible source or not, it looks like remoting is slated to go into second class technology, with flashy n sexy Indigo entering the scene.
[Ingo, offcially confirmed that *wasted* is not quoted by him]
In MSDN article "Introducing Longhorn for Developers" & Introducing Indigo: An Early Look,
Indigo is a set of .NET technologies for building and running connected systems, best of ASMX + Remoting. Indigo service applications support two main communications types: a stateless model (Indigo Web Services), in which messages are received with few if any guarantees, and a stateful model (Indigo RemoteObject Services), which creates a communication session between two service objects. The stateless model is equivalent to current-day Web services and is useful when broadcasting noncritical information. The stateful model, on the other hand, uses session state to enable Web services to provide functionality across the Internet, including callback methods, events, widely distributed transactions, and reliability and durability guarantees that enterprise applications require.
Indigo RemoteObject applications are built using the Indigo SOAP messaging infrastructure; therefore, they support end-to-end security features, including authentication and encryption, widely distributed and long-running transactions, automatic activation, and a robust management infrastructure, in addition to providing the ability to perform interface-based remoting and use asynchronous server methods.
I'm still not sure if Indigo RemoteObject will work behind a firewall, if you know pls let me know. Happen to view the msdn channel 9 video of Richard Turner {Indigo Program Manager} looks like, stage is all set for Indigo and we know about that so called *support* he is talking about and as a matter of fact Indigo will NOT support Windows 2000 either.
With all the performance the remoting framework suppose to deliver, it looks like somebody throwed the baby out with the bathwater. Looking at MSDNtv, Matt Tavis was demonstrating some of the feature enhancements to remoting infrastructure in Whidbey, my guess nothing will be added in Orcas version of .NET.
IpcChannel - for inter process communication in same box, avoids the overhead of network stack
Secure TcpChannel - built-in support for encryption, signing and authentication
Version Tolerant Serialization - more a serialization feature but this allows for versioning of types without worrying about failing to de/serialize when communicating with older versions on the client/server
some more that i didn't understand
Finally a word from Ingo about this
"The role of Remoting after Indigo? Hmm ... it will be the same role as the one of ASP.NET Web services, WSE 2.0, MSMQ, and Enterprise Services/COM+: Existing apps will continue to work (you can even run Indigo and any of these previous technologies in the same application and AppDomain). New apps (or parts thereof) will however quite likely be developed directly based on Indigo. (If running on Windows XP, Windows Server 2003 or - future - Longhorn as these are the only platforms which will be supported). "Normal" apps with the previous technologies (Remoting, ASP.NET, ...) will be quite easy to migrate. Custom transport channels and custom sinks will be harder to move ... i.e. they will have to be rewritten using the new extensibility models. Oh btw: Remoting will also continue to exist for areas which are not addressed by Indigo like cross-AppDomain communication. After all: Indigo is based on Remoting's __TransparentProxy architecture anyway ;-) "
No, there is no need to push the panic button and stop using remoting in new projects, a Prescriptive Guidance for Today's Technologies by Richard Turner's Tech-Ed session.
I heard that Ingo Rammer quoted "i have
[Ingo, offcially confirmed that *wasted* is not quoted by him]
In MSDN article "Introducing Longhorn for Developers" & Introducing Indigo: An Early Look,
Indigo is a set of .NET technologies for building and running connected systems, best of ASMX + Remoting. Indigo service applications support two main communications types: a stateless model (Indigo Web Services), in which messages are received with few if any guarantees, and a stateful model (Indigo RemoteObject Services), which creates a communication session between two service objects. The stateless model is equivalent to current-day Web services and is useful when broadcasting noncritical information. The stateful model, on the other hand, uses session state to enable Web services to provide functionality across the Internet, including callback methods, events, widely distributed transactions, and reliability and durability guarantees that enterprise applications require.
Indigo RemoteObject applications are built using the Indigo SOAP messaging infrastructure; therefore, they support end-to-end security features, including authentication and encryption, widely distributed and long-running transactions, automatic activation, and a robust management infrastructure, in addition to providing the ability to perform interface-based remoting and use asynchronous server methods.
I'm still not sure if Indigo RemoteObject will work behind a firewall, if you know pls let me know. Happen to view the msdn channel 9 video of Richard Turner {Indigo Program Manager} looks like, stage is all set for Indigo and we know about that so called *support* he is talking about and as a matter of fact Indigo will NOT support Windows 2000 either.
With all the performance the remoting framework suppose to deliver, it looks like somebody throwed the baby out with the bathwater. Looking at MSDNtv, Matt Tavis was demonstrating some of the feature enhancements to remoting infrastructure in Whidbey, my guess nothing will be added in Orcas version of .NET.
IpcChannel - for inter process communication in same box, avoids the overhead of network stack
Secure TcpChannel - built-in support for encryption, signing and authentication
Version Tolerant Serialization - more a serialization feature but this allows for versioning of types without worrying about failing to de/serialize when communicating with older versions on the client/server
some more that i didn't understand
Finally a word from Ingo about this
"The role of Remoting after Indigo? Hmm ... it will be the same role as the one of ASP.NET Web services, WSE 2.0, MSMQ, and Enterprise Services/COM+: Existing apps will continue to work (you can even run Indigo and any of these previous technologies in the same application and AppDomain). New apps (or parts thereof) will however quite likely be developed directly based on Indigo. (If running on Windows XP, Windows Server 2003 or - future - Longhorn as these are the only platforms which will be supported). "Normal" apps with the previous technologies (Remoting, ASP.NET, ...) will be quite easy to migrate. Custom transport channels and custom sinks will be harder to move ... i.e. they will have to be rewritten using the new extensibility models. Oh btw: Remoting will also continue to exist for areas which are not addressed by Indigo like cross-AppDomain communication. After all: Indigo is based on Remoting's __TransparentProxy architecture anyway ;-) "
No, there is no need to push the panic button and stop using remoting in new projects, a Prescriptive Guidance for Today's Technologies by Richard Turner's Tech-Ed session.
Labels:
.NET
Saturday, February 26, 2005
p&p Updater Application Block - Analysis and Review
Prior to including this application block as part of your enterprise architecture, do check out the architectural alternative of push technology, using Systems Management Server or group policy of active directory. Apart from server cost this may turn out to be information overload, but provides lot of benefits with simplified application deployment and administration, like ability to rollout to specific group, incremental updates greatly reducing network traffic and reduces the operational costs of developing software for deployment.
We can also look at another technical alternative that is shipped with .NET 1.0, HREF-EXE AKA Zero-touch deployment {sounds very similar to JAVA Web Start ;-)}. It might turn to be simplest of all deployment models, you deploy the application in any web server and user clicks on the link to the application .NET downloads the application and executes it. The update mechanism is like updating web applications, simply have to replace the file on the Web server and from that point on everyone launching your application will get the newest version.
But HREF-EXE come with an inherent limitations like, No offline support (always connected to web server), No desktop integration (user has to manually create an shortcut to exe), Runs in a sandbox with restricted semi-trust security (will not be able to call a web service in different machine from where exe is downloaded) and network delay (fat smart client apps will be more impacted).
Some of these limitations are overcome in next generation of this technology, ClickOnce shipping with .NET 2.0, with features like offline support, rolling back to previous versions of an application, and listing an application in the Windows Start menu & Add/Remove Programs catalog, HTTP compression support, simpler deployment packaging with help of "Whidbey". But if you are looking at capabilities like install to GAC, manage ODBC or COM+, registry write, setting up permissions (File/Folder/Registry) or any custom actions at install/uninstall, Install On Demand
Transactional Installation and Source Resiliency, only option is MSI.
The Updater Application Block helps to detect, validate, and download application updates deployed in a central location, using a "pull" model, with minimal coding and ability to configure externally and extend it for any special reqt.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnbda/html/updater.asp
1. All applications will have a boot strap application (AppStart.exe) which will use its configuration file to identify the latest and greatest version of the application and launch it.
2. The Updater Application Block requires a controller application to start/stop the update process and handle the various events that occur when application update tasks are performed. There are three distinct types of controller, each with their own considerations: Computer-Wide Controllers, Application Launcher Controllers and Self-Updating Applications. This controller app will get the server manifest for the application, connecting to the web server and check if there is any updated version available.
3. If new version is found, it will download the latest version using an downloader (Background intelligent transfer service (BITS) downloader comes out-of-the-box)
4. Uses and validates binaries (basically an crypto hash check with RSA algorithm) to ensure authenticity of the binaries
5. Updates the boot strap application configuration to the new version and runs the post-installation tasks if specified in manifest.
6. Depending on the type of controller, the new version is launched, if its a self updating controller, all the update happens in background and application gets notified of the successful completion of updating, which can take action like popping up a form to confirm with user on launching updated version.
As with other application blocks everything is customizable and out-of-the-box ships with a standard binaries that can be used for 90% of cases. Its one of the simpler and easy to use blocks of what i have seen. There is no sample provided for Application Launcher Controllers, although it should be easier to modify application launcher to make the asynchronous update process as a synchronous one, i got a very good sample for this one from Chris L. Kinsman http://www.vergentsoftware.com/downloads/uabsamples.zip.
Some of the features that i wish/expect to be in next release,
- Make mandatory updates, in most of cases you might want to make the update mandatory instead of user opting for an update
- Incremental update, i would prefer to publish only modified binaries and application block should be able to take the other files from the previous version of application
- Manage staged rollouts, to be able to control which clients update and when. Found a simple and good solution in net, modify the manifest retrieval code so that it can call an ASP.NET page, which returns different manifests based on the user's credentials (so you can have a group of users who are given one version, and everyone else gets the last major release or a one department can be given one version that is different from another department)
- Compression on the wire, this will help reduce a lot of network traffic
- Rollback update, only way to do that out-of-the-box is to release a new version with older binaries, works perfect but may be we can do that better
- Cleanup old versions, which should be simpler with some code in post processor
- May be i'm more user friendly, i would like to have a "what's new" or more accurately "what's the fix" information for the updated version to be available in manifest
The soon be released Updater Application Block 2.0, focuses on simplification of use, adherence to the Enterprise Library specification, and alignment with .NET 2.0 ClickOnce.
We can also look at another technical alternative that is shipped with .NET 1.0, HREF-EXE AKA Zero-touch deployment {sounds very similar to JAVA Web Start ;-)}. It might turn to be simplest of all deployment models, you deploy the application in any web server and user clicks on the link to the application .NET downloads the application and executes it. The update mechanism is like updating web applications, simply have to replace the file on the Web server and from that point on everyone launching your application will get the newest version.
But HREF-EXE come with an inherent limitations like, No offline support (always connected to web server), No desktop integration (user has to manually create an shortcut to exe), Runs in a sandbox with restricted semi-trust security (will not be able to call a web service in different machine from where exe is downloaded) and network delay (fat smart client apps will be more impacted).
Some of these limitations are overcome in next generation of this technology, ClickOnce shipping with .NET 2.0, with features like offline support, rolling back to previous versions of an application, and listing an application in the Windows Start menu & Add/Remove Programs catalog, HTTP compression support, simpler deployment packaging with help of "Whidbey". But if you are looking at capabilities like install to GAC, manage ODBC or COM+, registry write, setting up permissions (File/Folder/Registry) or any custom actions at install/uninstall, Install On Demand
Transactional Installation and Source Resiliency, only option is MSI.
The Updater Application Block helps to detect, validate, and download application updates deployed in a central location, using a "pull" model, with minimal coding and ability to configure externally and extend it for any special reqt.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnbda/html/updater.asp
1. All applications will have a boot strap application (AppStart.exe) which will use its configuration file to identify the latest and greatest version of the application and launch it.
2. The Updater Application Block requires a controller application to start/stop the update process and handle the various events that occur when application update tasks are performed. There are three distinct types of controller, each with their own considerations: Computer-Wide Controllers, Application Launcher Controllers and Self-Updating Applications. This controller app will get the server manifest for the application, connecting to the web server and check if there is any updated version available.
3. If new version is found, it will download the latest version using an downloader (Background intelligent transfer service (BITS) downloader comes out-of-the-box)
4. Uses and validates binaries (basically an crypto hash check with RSA algorithm) to ensure authenticity of the binaries
5. Updates the boot strap application configuration to the new version and runs the post-installation tasks if specified in manifest.
6. Depending on the type of controller, the new version is launched, if its a self updating controller, all the update happens in background and application gets notified of the successful completion of updating, which can take action like popping up a form to confirm with user on launching updated version.
As with other application blocks everything is customizable and out-of-the-box ships with a standard binaries that can be used for 90% of cases. Its one of the simpler and easy to use blocks of what i have seen. There is no sample provided for Application Launcher Controllers, although it should be easier to modify application launcher to make the asynchronous update process as a synchronous one, i got a very good sample for this one from Chris L. Kinsman http://www.vergentsoftware.com/downloads/uabsamples.zip.
Some of the features that i wish/expect to be in next release,
- Make mandatory updates, in most of cases you might want to make the update mandatory instead of user opting for an update
- Incremental update, i would prefer to publish only modified binaries and application block should be able to take the other files from the previous version of application
- Manage staged rollouts, to be able to control which clients update and when. Found a simple and good solution in net, modify the manifest retrieval code so that it can call an ASP.NET page, which returns different manifests based on the user's credentials (so you can have a group of users who are given one version, and everyone else gets the last major release or a one department can be given one version that is different from another department)
- Compression on the wire, this will help reduce a lot of network traffic
- Rollback update, only way to do that out-of-the-box is to release a new version with older binaries, works perfect but may be we can do that better
- Cleanup old versions, which should be simpler with some code in post processor
- May be i'm more user friendly, i would like to have a "what's new" or more accurately "what's the fix" information for the updated version to be available in manifest
The soon be released Updater Application Block 2.0, focuses on simplification of use, adherence to the Enterprise Library specification, and alignment with .NET 2.0 ClickOnce.
Labels:
.NET
Thursday, February 24, 2005
int division in SQLServer T-SQL
Today, I'm trying to use T-SQL to do a calculation something like this
Declare @a intDeclare @b int
select @a=1, @b=2
select (@a/@b)*100
No the result was not 50, it was 0.Thats 'coz SQL Server performs an implicit data-type conversion and converts the resulting value of 1/2 as integer. Fix is to cast the operands to decimal
select ( cast(@a as decimal)/ cast(@b as decimal) )*100
Labels:
Sql
Tuesday, February 22, 2005
sizeof (.net object) ?
Some time back, I was asked a way to find memory footprint of a dataset and my first thought was, a simple method call that .NET might provide, (No, sizeof operator only works with value types and not reference types) but life is not that eazy, there isn't any magic object that will let me do this.
After some googling found the following piece of code
long bytecount = System.GC.GetTotalMemory(true);
DataSet1 ds = new DataSet1();
ds.EnforceConstraints = false;
ds.Order_Details.BeginLoadData();
ds.Orders.BeginLoadData();
ds.ReadXml("c:\\test.xml");
bytecount = System.GC.GetTotalMemory(true) - bytecount;
MessageBox.Show("Loaded - Waiting. Total K = " + (bytecount/1024).ToString());
long bytecount = System.GC.GetTotalMemory(true);
System.Xml.XmlDocument xmlDoc = new System.Xml.XmlDocument();
xmlDoc.Load("c:\\test.xml");
bytecount = System.GC.GetTotalMemory(true) - bytecount;
MessageBox.Show("Loaded - Waiting. Total K = " + (bytecount/1024).ToString());
Thanks Barry Gervin, http://objectsharp.com/Blogs/barry/archive/2004/02/24/284.aspx
Thank god, Java developers too, doesn't have a simpler option for this and a solution i found thats used in Java world is much like Barry's code.
Not being skeptical here, but we tried using a memory analysis tool (Compuware's DevPartner) and also used the windows perfmon to cross check the value. Oops, none of the value match, no not some minor differences, it differed by a huge numbers. We had to take a expert guess, one which closely matched the memory size calculated from database columns being fetched, no i am not going to disclose which method was close, as i'm myself not sure which one is.
If you can think of something of perfect way to get the memory foot print of a .NET object, pls let me know with your comments here. I appreciate your help.
After some googling found the following piece of code
long bytecount = System.GC.GetTotalMemory(true);
DataSet1 ds = new DataSet1();
ds.EnforceConstraints = false;
ds.Order_Details.BeginLoadData();
ds.Orders.BeginLoadData();
ds.ReadXml("c:\\test.xml");
bytecount = System.GC.GetTotalMemory(true) - bytecount;
MessageBox.Show("Loaded - Waiting. Total K = " + (bytecount/1024).ToString());
long bytecount = System.GC.GetTotalMemory(true);
System.Xml.XmlDocument xmlDoc = new System.Xml.XmlDocument();
xmlDoc.Load("c:\\test.xml");
bytecount = System.GC.GetTotalMemory(true) - bytecount;
MessageBox.Show("Loaded - Waiting. Total K = " + (bytecount/1024).ToString());
Thanks Barry Gervin, http://objectsharp.com/Blogs/barry/archive/2004/02/24/284.aspx
Thank god, Java developers too, doesn't have a simpler option for this and a solution i found thats used in Java world is much like Barry's code.
Not being skeptical here, but we tried using a memory analysis tool (Compuware's DevPartner) and also used the windows perfmon to cross check the value. Oops, none of the value match, no not some minor differences, it differed by a huge numbers. We had to take a expert guess, one which closely matched the memory size calculated from database columns being fetched, no i am not going to disclose which method was close, as i'm myself not sure which one is.
If you can think of something of perfect way to get the memory foot print of a .NET object, pls let me know with your comments here. I appreciate your help.
Labels:
.NET
Saturday, February 19, 2005
.NET app - another running instance check and DTC exception
This error and its fix is weird and i am posting this to a miserable developer, who is still trying to crack this error in this scenario. It was a requirement is to allow only one instance of the batch app to run, hence the following code was copied from internet to check if another instance of application is running, and abort the current instance
Process [] aoRunningInstance = Process.GetProcessesByName(Constant.APPLICATION_NAME);
if (aoRunningInstance.Length > 1)
{
throw new ApplicationException("Another instance of app is running. Aborting current instance.");
}
aoRunningInstance = null;
Everything went fine; it found another instance and aborted, but weirdly in a scenario
//Create a new Transaction
//Open SQL connection inside the Transaction
//Open DB2 connection inside the Transaction
Line where i try to open DB2 connection, an exception is thrown >>>>> [IBM][CLI Driver] CLI0126E Operation invalid at this time. SQLSTATE=HY011
It was found that if we comment out another instance check code, the error is not happening. #@$@#$@!#. Wait, fix to this error is even weirder, we open and close the DB2 connection before this another instance check code and click the error vanishes in thin air.
I found a another way of to check another running instance of the app from Updater Application Block,
private Mutex _appStartMutex;
private readonly Guid _mutexGuid = new Guid( new byte[] { 0x5F, 0x4D, 0x69, 0x63, 0x68, 0x61, 0x65, 0x6C, 0x20, 0x53, 0x74, 0x75, 0x61, 0x72, 0x74, 0x5F });
bool isOwned = false;
_appStartMutex = new Mutex( true, System.Reflection.Assembly.GetExecutingAssembly().FullName + _mutexGuid.ToString(), out isOwned );
if ( !isOwned ){
throw new ApplicationException("Another instance of app is running. Aborting current instance.");
}
This will not alow the application to run even if its run with different executable name or from a different location. But has overhead of Mutex, not sure if this will fix this the above error.
It indeed fixes the above issue and after some thought i think it will be performance effective to have Mutex instead of pulling every process name that is running machine, i always see a 100% spike if i do this using task manager.
Process [] aoRunningInstance = Process.GetProcessesByName(Constant.APPLICATION_NAME);
if (aoRunningInstance.Length > 1)
{
throw new ApplicationException("Another instance of app is running. Aborting current instance.");
}
aoRunningInstance = null;
Everything went fine; it found another instance and aborted, but weirdly in a scenario
//Create a new Transaction
//Open SQL connection inside the Transaction
//Open DB2 connection inside the Transaction
Line where i try to open DB2 connection, an exception is thrown >>>>> [IBM][CLI Driver] CLI0126E Operation invalid at this time. SQLSTATE=HY011
It was found that if we comment out another instance check code, the error is not happening. #@$@#$@!#. Wait, fix to this error is even weirder, we open and close the DB2 connection before this another instance check code and click the error vanishes in thin air.
I found a another way of to check another running instance of the app from Updater Application Block,
private Mutex _appStartMutex;
private readonly Guid _mutexGuid = new Guid( new byte[] { 0x5F, 0x4D, 0x69, 0x63, 0x68, 0x61, 0x65, 0x6C, 0x20, 0x53, 0x74, 0x75, 0x61, 0x72, 0x74, 0x5F });
bool isOwned = false;
_appStartMutex = new Mutex( true, System.Reflection.Assembly.GetExecutingAssembly().FullName + _mutexGuid.ToString(), out isOwned );
if ( !isOwned ){
throw new ApplicationException("Another instance of app is running. Aborting current instance.");
}
This will not alow the application to run even if its run with different executable name or from a different location. But has overhead of Mutex, not sure if this will fix this the above error.
It indeed fixes the above issue and after some thought i think it will be performance effective to have Mutex instead of pulling every process name that is running machine, i always see a 100% spike if i do this using task manager.
Labels:
.NET
Tuesday, February 15, 2005
ASP.NET Datagrid to Excel clipboard copy/paste: an ugly javascript solution
As usual this one is a crazy reqt to provide a feature to copy/paste a fixed size datagrid to/from excel. To me * should understand the architectural difference between a web form and winform There are some inherent features that comes with winform; and one should not expect, all the features to be provided in webform. "He who gives me salt, he shall get the solution", i found excel reads/writes data in clipbooard with tab delimited for columns and new line delimited for rows,
function GetExcelData(){
var content = clipboardData.getData("Text");
if (content!=null) {
var t = content.replace(/\n/g," \n");
t = t.replace(/\t/g," \t");
var myArray = t.split(/\n/);
var y = "<table align='center' border='1'>";
for (var i = 0; i < myArray.length; i++) {
y = y + "<tr>";
var myArray2 = myArray[i].split(/\t/);
for (var j = 0; j < myArray2.length; j++) {
y = y + "<td> " + myArray2[j] + "</td>";
}
y = y + "</tr>";
}
y = y + "</table>";
window.spnMsg.innerHTML = y;
}
else {
window.spnMsg.innerHTML = "No text found in clipboard.";
}
}
function PutExcelData(){ //... build a string in delimited format and put it in clipboard
Proposed solution is to provide a button "Copy", to copy the data from datagrid to clipboard and a "Paste" button to copy the data data from clipboard to datagrid.
Warning: Not sure if it is supported in all IE versions and other GOOD browsers like Firefox.
I found a workaround also, use a textarea form field that holds the text to be copied, select it by form.textarea.select() method and copy it to the clipboard using the execCommand like below, Unfortunately the select() method works with visible form objects only, that can be easily overcomed but putting that control in a div tag and making the div tag invisible.
document.myForm.invisibleTextArea.select();
document.execCommand('Copy');
It struck me after coding the solution, how easy it will be to exploit this and steal a sensitive information from clipboard (i know many copy/paste passwords, credit card nbrs!). I expect IE to atleast prompt user, before allowing this script to access clipboard.
function GetExcelData(){
var content = clipboardData.getData("Text");
if (content!=null) {
var t = content.replace(/\n/g," \n");
t = t.replace(/\t/g," \t");
var myArray = t.split(/\n/);
var y = "<table align='center' border='1'>";
for (var i = 0; i < myArray.length; i++) {
y = y + "<tr>";
var myArray2 = myArray[i].split(/\t/);
for (var j = 0; j < myArray2.length; j++) {
y = y + "<td> " + myArray2[j] + "</td>";
}
y = y + "</tr>";
}
y = y + "</table>";
window.spnMsg.innerHTML = y;
}
else {
window.spnMsg.innerHTML = "No text found in clipboard.";
}
}
function PutExcelData(){ //... build a string in delimited format and put it in clipboard
Proposed solution is to provide a button "Copy", to copy the data from datagrid to clipboard and a "Paste" button to copy the data data from clipboard to datagrid.
Warning: Not sure if it is supported in all IE versions and other GOOD browsers like Firefox.
I found a workaround also, use a textarea form field that holds the text to be copied, select it by form.textarea.select() method and copy it to the clipboard using the execCommand like below, Unfortunately the select() method works with visible form objects only, that can be easily overcomed but putting that control in a div tag and making the div tag invisible.
document.myForm.invisibleTextArea.select();
document.execCommand('Copy');
It struck me after coding the solution, how easy it will be to exploit this and steal a sensitive information from clipboard (i know many copy/paste passwords, credit card nbrs!). I expect IE to atleast prompt user, before allowing this script to access clipboard.
Labels:
ASP.net
Sunday, January 30, 2005
asp.net custom validator for mmddyy date format
This one is a usability reqt, since system is migrated form mainframe, users have long since got used to enter the date in mmddyy format without any slashes; mainframe CICS screen used to shift to next fld as current fld is filled out. And we needed to have that date textbox to accept date in this format and validate the date. {Personally, i would not prefer handling this and needs to be considered as a training reqt}
To minimize the impact to the code, (almost all times, these reqts spring up only in user acceptance stage, where you have not time think a better solution; will most probably patch the code) i added the following java script, which on tab out of text box, put the slash in approp place, but unfortunately the asp.net validator fires before this onblur event and hence fails, so i had to create a custom validator which formats and also validates the date. I am posting that useless date time patch code below,
<asp:TextBox id="TextBoxDate" runat="server" Width="65" MaxLength="8" CssClass="textbox"></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidatorDate" ControlToValidate="TextboxDate" Enabled="false"
Display="Static" ErrorMessage="Date is required and must be in MMDDYY or MM/DD/YY format." Runat="server" />
<asp:CustomValidator id="CustomValidatorDateCheck" runat="server" ErrorMessage="Date or Date format is invalid. Format is MMDDYY or MM/DD/YY." ClientValidationFunction="FormatAndValidateDate" ControlToValidate="TextBoxDate" />
/*
This is having client script for formating and validating date. The following date formats are accepted:
mmddyy, mmddyyyy, mm-dd-yyyy, mm/dd/yyyy, mm.dd.yyyy, mm dd yyyy,
mmm dd yyyy, mmddyyyy, m-d-yyyy, m/d/yyyy, m.d.yyyy,
m d yyyy, mmm d yyyy, m-d-yy, m/d/yy, m.d.yy, m d yy,
mmm d yy (yy is 20yy)
*/
function FormatAndValidateDate(oSource,oArguments) {
var szDate;
var szDateArray;
var szDay;
var szMonth;
var szYear;
var bFound = false;
var aszSeparatorArray = new Array("-"," ","/",".");
var iElementNr;
oArguments.IsValid = false;
if (oArguments.Value.length < 6){
return;
}
szDate = oArguments.Value;
szDate = szDate.replace(/^\s+/,'').replace(/\s+$/,'');
var szDateFormat = new RegExp("^(\\d{1,2})([-./ ]{0,1})(\\d{1,2})\\2((\\d{4})|(\\d{2}))$");
m = szDate.match(szDateFormat);
if (m == null) {
return;
}
for (iElementNr = 0; iElementNr < aszSeparatorArray.length; iElementNr++)
{
if (szDate.indexOf(aszSeparatorArray[iElementNr]) != -1)
{
szDateArray = szDate.split(aszSeparatorArray[iElementNr]);
if (szDateArray.length != 3)
{
return;
}
else
{
szDay = szDateArray[0];
szMonth = szDateArray[1];
szYear = szDateArray[2];
}
bFound = true;
}
}
if (bFound == false)
{
if (szDate.length > 5)
{
szDay = szDate.substr(0, 2);
szMonth = szDate.substr(2, 2);
szYear = szDate.substr(4);
}
}
if(szYear != null)
{
if (szYear.length == 2)
{
szYear = '20' + szYear; //If entered 2 digit yr, consider it as 21st century
}
}
//swap for US date format mm/dd/yy
var szTmp = szDay;
szDay = szMonth;
szMonth = szTmp;
szTmp = "";
if( (szMonth<10) && (szMonth.length == 1))
{
szTmp = "0" + szMonth + "/";
}
else
{
szTmp = szMonth + "/";
}
if( (szDay<10)&& (szDay.length == 1))
{
szTmp += "0" + szDay + "/";
}
else
{
szTmp += szDay + "/";
}
document.getElementById(oSource.controltovalidate).value = szTmp + szYear.substr(2, 2);
szMonth = szMonth - 1; // javascript month range : 0- 11
var tempDate = new Date(szYear,szMonth,szDay);
if ( (typeof(tempDate) == "object") && (getYear(tempDate.getYear()) == szYear) && (szMonth == tempDate.getMonth()) && (szDay == tempDate.getDate()) )
{
oArguments.IsValid = true;
}
}
function getYear(d) {
return (d < 1000) ? d + 1900 : d;
}
To minimize the impact to the code, (almost all times, these reqts spring up only in user acceptance stage, where you have not time think a better solution; will most probably patch the code) i added the following java script, which on tab out of text box, put the slash in approp place, but unfortunately the asp.net validator fires before this onblur event and hence fails, so i had to create a custom validator which formats and also validates the date. I am posting that useless date time patch code below,
<asp:TextBox id="TextBoxDate" runat="server" Width="65" MaxLength="8" CssClass="textbox"></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidatorDate" ControlToValidate="TextboxDate" Enabled="false"
Display="Static" ErrorMessage="Date is required and must be in MMDDYY or MM/DD/YY format." Runat="server" />
<asp:CustomValidator id="CustomValidatorDateCheck" runat="server" ErrorMessage="Date or Date format is invalid. Format is MMDDYY or MM/DD/YY." ClientValidationFunction="FormatAndValidateDate" ControlToValidate="TextBoxDate" />
/*
This is having client script for formating and validating date. The following date formats are accepted:
mmddyy, mmddyyyy, mm-dd-yyyy, mm/dd/yyyy, mm.dd.yyyy, mm dd yyyy,
mmm dd yyyy, mmddyyyy, m-d-yyyy, m/d/yyyy, m.d.yyyy,
m d yyyy, mmm d yyyy, m-d-yy, m/d/yy, m.d.yy, m d yy,
mmm d yy (yy is 20yy)
*/
function FormatAndValidateDate(oSource,oArguments) {
var szDate;
var szDateArray;
var szDay;
var szMonth;
var szYear;
var bFound = false;
var aszSeparatorArray = new Array("-"," ","/",".");
var iElementNr;
oArguments.IsValid = false;
if (oArguments.Value.length < 6){
return;
}
szDate = oArguments.Value;
szDate = szDate.replace(/^\s+/,'').replace(/\s+$/,'');
var szDateFormat = new RegExp("^(\\d{1,2})([-./ ]{0,1})(\\d{1,2})\\2((\\d{4})|(\\d{2}))$");
m = szDate.match(szDateFormat);
if (m == null) {
return;
}
for (iElementNr = 0; iElementNr < aszSeparatorArray.length; iElementNr++)
{
if (szDate.indexOf(aszSeparatorArray[iElementNr]) != -1)
{
szDateArray = szDate.split(aszSeparatorArray[iElementNr]);
if (szDateArray.length != 3)
{
return;
}
else
{
szDay = szDateArray[0];
szMonth = szDateArray[1];
szYear = szDateArray[2];
}
bFound = true;
}
}
if (bFound == false)
{
if (szDate.length > 5)
{
szDay = szDate.substr(0, 2);
szMonth = szDate.substr(2, 2);
szYear = szDate.substr(4);
}
}
if(szYear != null)
{
if (szYear.length == 2)
{
szYear = '20' + szYear; //If entered 2 digit yr, consider it as 21st century
}
}
//swap for US date format mm/dd/yy
var szTmp = szDay;
szDay = szMonth;
szMonth = szTmp;
szTmp = "";
if( (szMonth<10) && (szMonth.length == 1))
{
szTmp = "0" + szMonth + "/";
}
else
{
szTmp = szMonth + "/";
}
if( (szDay<10)&& (szDay.length == 1))
{
szTmp += "0" + szDay + "/";
}
else
{
szTmp += szDay + "/";
}
document.getElementById(oSource.controltovalidate).value = szTmp + szYear.substr(2, 2);
szMonth = szMonth - 1; // javascript month range : 0- 11
var tempDate = new Date(szYear,szMonth,szDay);
if ( (typeof(tempDate) == "object") && (getYear(tempDate.getYear()) == szYear) && (szMonth == tempDate.getMonth()) && (szDay == tempDate.getDate()) )
{
oArguments.IsValid = true;
}
}
function getYear(d) {
return (d < 1000) ? d + 1900 : d;
}
Labels:
ASP.net
Thursday, January 20, 2005
asp.net form submision hijack
I am not sure if anybody in the world is handling this behaviour. To explain the requested behaviour, i am using a simplified scenario, there is a web form which accepts employee number and empolyee name and age. Employee age is validated for range and in code behind employee number is chceked if it's present in database, if not a error message is shown to user using a label control.
In a scenario, user enters a valid age and a employee number which not present in db, so page is processed and label is set with the error message "employee not in db". Now if he enters a valid employee number and invalid age (outside the range) and tabs out, since age range is invalid both client side range validator error and server side error messages are displayed. I was told that user is confused as he knows the employee number is correct but page displays a contradicting message. {my first thoughts is "Oh yeah... so..." } and was asked to remove the message before form is submited.
Initially thought of hijacking the asp.net form submission {for those who like to see how its done, i have included the script } but wrote a client script to clear the label and register using Page.RegisterOnSubmitStatement, since that is fired only when form is submitted, the on-blur of the age control doesn't invoke the script. I didn't had a clue if i can wire client events and when i found the option, i wrote a script to clear the server message.
//Wire the method to events
document.body.attachEvent('onkeydown',ClearServerMessage);
document.body.attachEvent('onmousedown',ClearServerMessage);
// Will hold the Label control client id
var strHTMLElementForServerSideMessage;
function ClearServerMessage(e){
//get the ServerSideMessage HTML element
strHTMLElement = document.getElementById(strHTMLElementForServerSideMessage);
//Clear only when the user does something with validation control elements, such as textbox's,.. if((window.event.srcElement.tagName == "INPUT")
|| (window.event.srcElement.tagName == "SELECT")
|| (window.event.srcElement.tagName == "A") )
{
//Check if not null and element of type SPAN, then clear off message
if( (strHTMLElement != null) && (strHTMLElement.nodeName == 'SPAN') )
{
strHTMLElement.innerHTML = "";
}
//UnWire the method from events, so it won't be fired again
document.body.detachEvent('onkeydown',ClearServerMessage);
document.body.detachEvent('onmousedown',ClearServerMessage);
}
}
//code behind
string szClrScript = "<script language=JavaScript>strHTMLElementForServerSideMessage=\"" + LabelServerMessage.ClientID + "\";</script>";
if(!Page.IsClientScriptBlockRegistered("szClrSCript"))
Page.RegisterClientScriptBlock("szClrScript", szClrScript);
The fun, form submission hijack script,
<script language="javascript">
// save the original function pointer of the .NET __doPostBack function in a global variable netPostBack
var netPostBack = __doPostBack;
// replace __doPostBack with your own function
__doPostBack = EscapeHtml;
function EscapeHtml (eventTarget, eventArgument)
{
// execute your own code before the page is submitted
document.all." + HtmlText.ClientID + ".value = escape(document.all." + HtmlText.ClientID + ".value);
// call base functionality
return netPostBack (eventTarget, eventArgument);
}
</script>
In a scenario, user enters a valid age and a employee number which not present in db, so page is processed and label is set with the error message "employee not in db". Now if he enters a valid employee number and invalid age (outside the range) and tabs out, since age range is invalid both client side range validator error and server side error messages are displayed. I was told that user is confused as he knows the employee number is correct but page displays a contradicting message. {my first thoughts is "Oh yeah... so..." } and was asked to remove the message before form is submited.
Initially thought of hijacking the asp.net form submission {for those who like to see how its done, i have included the script } but wrote a client script to clear the label and register using Page.RegisterOnSubmitStatement, since that is fired only when form is submitted, the on-blur of the age control doesn't invoke the script. I didn't had a clue if i can wire client events and when i found the option, i wrote a script to clear the server message.
//Wire the method to events
document.body.attachEvent('onkeydown',ClearServerMessage);
document.body.attachEvent('onmousedown',ClearServerMessage);
// Will hold the Label control client id
var strHTMLElementForServerSideMessage;
function ClearServerMessage(e){
//get the ServerSideMessage HTML element
strHTMLElement = document.getElementById(strHTMLElementForServerSideMessage);
//Clear only when the user does something with validation control elements, such as textbox's,.. if((window.event.srcElement.tagName == "INPUT")
|| (window.event.srcElement.tagName == "SELECT")
|| (window.event.srcElement.tagName == "A") )
{
//Check if not null and element of type SPAN, then clear off message
if( (strHTMLElement != null) && (strHTMLElement.nodeName == 'SPAN') )
{
strHTMLElement.innerHTML = "";
}
//UnWire the method from events, so it won't be fired again
document.body.detachEvent('onkeydown',ClearServerMessage);
document.body.detachEvent('onmousedown',ClearServerMessage);
}
}
//code behind
string szClrScript = "<script language=JavaScript>strHTMLElementForServerSideMessage=\"" + LabelServerMessage.ClientID + "\";</script>";
if(!Page.IsClientScriptBlockRegistered("szClrSCript"))
Page.RegisterClientScriptBlock("szClrScript", szClrScript);
The fun, form submission hijack script,
<script language="javascript">
// save the original function pointer of the .NET __doPostBack function in a global variable netPostBack
var netPostBack = __doPostBack;
// replace __doPostBack with your own function
__doPostBack = EscapeHtml;
function EscapeHtml (eventTarget, eventArgument)
{
// execute your own code before the page is submitted
document.all." + HtmlText.ClientID + ".value = escape(document.all." + HtmlText.ClientID + ".value);
// call base functionality
return netPostBack (eventTarget, eventArgument);
}
</script>
Labels:
ASP.net
Friday, January 14, 2005
Iniya pongal nal vazthukal!!!
Thanks for all those who keep the divine language from being extinct. Kudos Project Madurai
Thanks for all those who keep the divine language from being extinct. Kudos Project Madurai
Labels:
Scraps
Thursday, January 13, 2005
repeou nisbum
This prank is really intresting, gist here,
"News from Repeou:
The country Repeou threatens Microsoft to pay a fine as much as 10 percent of its global annual sales for monopoly defenses. The software giant is abusing its monopoly power by bundling several applications such as the Calculator and Paint with Windows.
The process against Microsoft was started by the company named Nisbum. Nisbum developed a great calculator but doesn't see a chance to sell this great product to the masses as long as Microsoft bundles the Calculator with Windows.
According to Repeou, Microsoft must offer at least two separate versions of Windows, one version without the Calculator.
Repeou is giving Microsoft a last opportunity to comment before the case is concluded."
After 24 hrs i could succesfully de-scramble the words "repeou nisbum" -> "europe ibm sun", a good prank on the recent ruling against Microsoft by European Union.
"News from Repeou:
The country Repeou threatens Microsoft to pay a fine as much as 10 percent of its global annual sales for monopoly defenses. The software giant is abusing its monopoly power by bundling several applications such as the Calculator and Paint with Windows.
The process against Microsoft was started by the company named Nisbum. Nisbum developed a great calculator but doesn't see a chance to sell this great product to the masses as long as Microsoft bundles the Calculator with Windows.
According to Repeou, Microsoft must offer at least two separate versions of Windows, one version without the Calculator.
Repeou is giving Microsoft a last opportunity to comment before the case is concluded."
After 24 hrs i could succesfully de-scramble the words "repeou nisbum" -> "europe ibm sun", a good prank on the recent ruling against Microsoft by European Union.
Labels:
Scraps
Tuesday, January 11, 2005
MCSD.net...
https://partnering.one.microsoft.com/authenticate/MCPCredentials.aspx
Transcript ID: 690126
Access Code: isasmcsd
70-315 Developing and Implementing Web Applications,
70-316 Developing and Implementing Windows-based Applications,
70-320 Developing XML Web Services and Server Components,
70-300 Analyzing Requirements and Defining .NET Solution Architectures &
70-340 Implementing Security for Applications
After 2 months of preparation and 20+ hrs of travel to/fro Sioux Falls, SD exam center, i am finally certified. Keeping the debate of worthness of the certification apart, the excercise proved to be a good test, to see where i stand in the crowd. With thousands of dumpsters, I am really skeptical of the certificate credits, but at end of the day, knowledge gained is all that matters and i am really satisfied what i gained from this certification excercise.
Labels:
Scraps
Monday, January 03, 2005
OpenXML and index scan issue
Faced a peculiar issue with OpenXML, when joining with a table with an OpenXML data, it seems the index being hit is erratic.
CREATE TABLE OpenXMLTest3
(
Col1 INT NOT NULL primary key,
Col2 CHAR(1) NOT NULL,
Col3 CHAR(10)
)
GO
CREATE INDEX IDX_OpenXMLTest3 ON OpenXMLTest3
( Col2, Col3 ) WITH FILLFACTOR = 90 ON [PRIMARY]
GO
Execution plan for the following code gives a index scan on IDX_OpenXMLTest3, but if we load a lot of data into this table, and get the execution plan, it shows a clustered index scan on primary key index. ???? Yes on the "primary key index" ????
DECLARE @hDoc INT
EXEC sp_xml_preparedocument @hDocOUTPUT, '?'
SELECT * FROM OpenXMLTest3 A,
OPENXML (@hDoc, 'ROOT/OpenXMLTest3',1)
WITH (COL2 CHAR(1), COL3 CHAR(10)) B
WHERE A.COL2 = B.COL2 AND
A.COL3 = B.COL3
When we dump the xml data into a table variable and join with that like one below, it was found to give an index seek on IDX_OpenXMLTest3. That is what we used to fix this isse as the table we are joining is a very big invoice table and OpenXML failed hands down.
DECLARE @Temp table (
Col2 CHAR(1) NOT NULL,
Col3 CHAR(10)
)
SELECT * FROM OpenXMLTest3 A, @Temp B
WHERE A.COL2 = B.COL2 AND
A.COL3 = B.COL3
CREATE TABLE OpenXMLTest3
(
Col1 INT NOT NULL primary key,
Col2 CHAR(1) NOT NULL,
Col3 CHAR(10)
)
GO
CREATE INDEX IDX_OpenXMLTest3 ON OpenXMLTest3
( Col2, Col3 ) WITH FILLFACTOR = 90 ON [PRIMARY]
GO
Execution plan for the following code gives a index scan on IDX_OpenXMLTest3, but if we load a lot of data into this table, and get the execution plan, it shows a clustered index scan on primary key index. ???? Yes on the "primary key index" ????
DECLARE @hDoc INT
EXEC sp_xml_preparedocument @hDocOUTPUT, '?'
SELECT * FROM OpenXMLTest3 A,
OPENXML (@hDoc, 'ROOT/OpenXMLTest3',1)
WITH (COL2 CHAR(1), COL3 CHAR(10)) B
WHERE A.COL2 = B.COL2 AND
A.COL3 = B.COL3
When we dump the xml data into a table variable and join with that like one below, it was found to give an index seek on IDX_OpenXMLTest3. That is what we used to fix this isse as the table we are joining is a very big invoice table and OpenXML failed hands down.
DECLARE @Temp table (
Col2 CHAR(1) NOT NULL,
Col3 CHAR(10)
)
SELECT * FROM OpenXMLTest3 A, @Temp B
WHERE A.COL2 = B.COL2 AND
A.COL3 = B.COL3
Subscribe to:
Posts (Atom)