Ran Wahle's blog

Bi-directional Dictionary implementation

Bi-directional Dictionary implementation

There were several times, during my short development career, that I’ve
used Dictionary<TKey, TValue>. It may not be on most cases, but I’m sure
in many of them, I needed to find a dictionary item by it’s value whereas
the dictionary’s values were unique as well as it’s keys.

This led me to the motivation of developing a dictionary that will support
bi-directional access.

 

What were the requirements?

1. Access dictionary[value] will return it’s key the same way dictionary[key]
    return it’s value.

2. Performance will be effected only by a constant (O(1) to get and set dictionary item
    the same as in regular Dictionary<TKey, TValue>)

3. The bidirectional dictionary will implement all interfaces that Dictionary<TKey, TValue>
    does.

 

Implementation:

The requirements listed above have led me to use Dictionary<TKey, TValue> qualities by
using an internal two dictionaries. One will act as Dictionary<TKey, TValue> and the other
will be the other way around (Dictionary<TValue, TKey>). 
I’ve set two indexers (one for each direction). The add / remove methods calls their
corresponding methods on their internal dictionaries.

When trying to add the same value twice (with different keys) an exception is thrown.

Limitations:

When using the bi-directional dictionary with key and value having the same type, there
is an ambiguity when calling dictionary[key] and dictionary[value]. 
I’ve had two choices – Change the whole interface of the opposite direction access and
having all “by value” access be explicit, or removing the support for same type. On that
case, I’ve preferred keeping the same interface for by-key and by-value access and
therefore removed support for the same type.

 

My implementation can be downloaded here (don’t forget to change the extension to .cs)

Another implementation that does support same type dictionary I’ve found on a
StackOverflow forum thread  here .

 

 

This class can run on Framework 2.0 and above

kick it on DotNetKicks.com
Code snippet for control wrapping properties

Code snippet for control wrapping properties

Hello everyone.

many of us,  I’m sure, needed to wrap inner controls of a user\custom control 
with public properties. That’s in order to have their control encapsulated,
and to add some code flexibility (If the control is changing, all I need to do is
change the code of my property and the rest remains intact.

Therefore I’ve made a code snippet for myself that allow me to write these kind
of properties easily, and figured why not let everyone use it.

I hope you’ll find it useful.

 

<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets  xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
    <CodeSnippet Format="1.0.0">
        <Header>
            <Title>Control Property</Title>
            <Shortcut>propctrl</Shortcut>
            <Description>Code snippet for property with get and set accessors 
      that wraps an inner control</Description>
            <Author>Ran Wahle</Author>
            <SnippetTypes>
                <SnippetType>Expansion</SnippetType>
            </SnippetTypes>
        </Header>
        <Snippet>
            <Declarations>
                <Literal>
                    <ID>type</ID>
                    <ToolTip>Property type</ToolTip>
                    <Default>string</Default>
                </Literal>
                <Literal>
                    <ID>name</ID>
                    <Default>PropName</Default>
          <ToolTip>Property name</ToolTip>
                </Literal>
        <Literal>
          <ID>controlName</ID>
          <Default>ctrlName</Default>
          <ToolTip>Control Name</ToolTip>
        </Literal>
        <Literal>
          <ID>controlInnerProperty</ID>
          <Default>Text</Default>
          <ToolTip>Control Inner property</ToolTip>
        </Literal>
            </Declarations>
            <Code Language="csharp">
        <![CDATA[
        /// <summary>
        /// Put summary for $name$
        /// </summary>
        public $type$ $name$
        {
            get
            {
                return $controlName$.$controlInnerProperty$;
            }
            set
            {
                $controlName$.$controlInnerProperty$ = value;
            }
        }
]]>
            </Code>
        </Snippet>
    </CodeSnippet>
</CodeSnippets>
kick it on DotNetKicks.com
Posted: Dec 29 2009, 03:46 PM by Ran Wahle | with 1 comment(s) |
תגים:, ,
Session manager

This post comes as an extension to a post by Shlomo Goldberg (in Hebrew) that talks
about how to work with session variable in a safer way than plain strings.

Shlomo Goldberg has suggested that instead of strings we should work with enum entries.
This way is more efficient for developers who can simply find all the uses of a certain  session
variable and can find all reference to it.

As you can see from the code attached to that post, it uses indexer with SessionParam
enum using a private method called RetrieveFromSession, which calls it’s overloading
method that accepts the good old string parameter (using the enum.ToString method).

This one, of course holds some performance penalty because it’s use of the ToString method
call for enum. Here’s another approach:

As an extension for this suggestion one might suggest the use of properties that envelopes
the session variable within.

All properties are in a singleton class (The same as in the class suggested by Shlomo Goldberg)

A property of such can look like that:

   1:    public UserInfo DelegatingUser
   2:          {
   3:              get
   4:              {
   5:                  return Session != null ? (UserInfo)Session[DELEGATING_USER] : null;
   6:              }
   7:              set
   8:              {
   9:                  if (Session != null)
  10:                  {
  11:                      Session[DELEGATING_USER] = value;
  12:                  }
  13:              }
  14:          }
 Where Session is also a property envelopes HttpContext.Current.Session 
and the DELEGATING_USER is a string constant

 

What do we gain from it?

1. Type safety. Use of this kind of properties will prevent override one type of an object by
   another without the compiler  will notify.

2. We don’t have to use the enum.ToString anymore and therefore gain our performance
    back almost fully.

3. We can add logic to the properties.

There are two (or more) downsides however:

1. This class may be coupled to the project’s data model, you cannot simply put it on another
    project because it won’t compile.

2. You cannot add session variables through this class form another files. Adding new session
    variables requires adding new properties to the class.

 

You can download the class in here. (Note – it won’t compile because it is coupled to
my project’s data model)

kick it on DotNetKicks.com
Posted: Dec 20 2009, 09:51 PM by Ran Wahle | with 1 comment(s) |
תגים:, ,
Accessibility: Using WAVE extension for Firefox

Accessibility: Using WAVE extension for Firefox

 WAVE toolbar for Firefox

Two issues I came across regarding developing web apps that supports accessibility
are knowing the guidelines along with lack of tools that can check the actual
page generated by our application and provide as with meaningful information
on how to fix accessibility errors.

Visual Studio validation disabilities

Visual studio has, since it’s 2005 version, a tool for accessibility check on web pages.
however, it cannot discover errors caused by HTML generated in our code behind,
in our or 3rd party’s custom controls and of course not on elements generated in
JavaScript using DOM manipulations or any other technique on client side.

Accessibility toolbars

There is a variety of accessibility toolbars for Internet Explorer, Firefox, Opera and more.
These toolbars are great tools and include features like stripping page from it’s
CSS / pictures / JavaScript  (viewing in text-only mode) , sending the page to be
validated on various web accessibility and W3C compliance validators and so on.  

WAVE toolbar for Firefox

WAVE toolbar for Firefox contains all those features and one, very significant, more.
In the following screenshot you can see the “Error, Features and alert” . Here, by pressing
a button, you can see all accessibility faults on your page:

 WAVE Error features and alert screenshot

As you can see in the on the picture above, there are little icons added near some elements.
The red ones are for errors, the yellow for alerts and the green ones are displaying the
accessibility features on the page.

Going with your mouse over each icon tells us what the error / alert / feature is about as
a tooltip.

What does it give us?

1. The “Errors, Features and Alerts” button does it’s validation on the client side.
    Meaning that it is good  for offline pages, pages on enterprise’s intra-net and
    sites requires log-in.

2. Even if you are not familiar with the accessibility guidelines you can easily learn
    what your mistakes  are by simply press the “Icon key” button. The explanations
    and recommendations on that  page are simple.

 

Summary

Accessibility is something to keep in mind when designing our web application’s UI.
Visual Studio’s accessibility checks is not profound enough because it’s limitations
in discovering issues caused by our code-behind or ours / third party’s custom controls.
WAVE accessibility toolbar may come in handy with it’s “Error / Features and Alerts”
feature that helps us find our accessibility issues easily. It check’s our page with it’s
final output (including elements created on client side) and does it locally. It also
contains the same features as other toolbars such as disabling CSS / scripts 
and sending the page’s URL for validating in various validating sites.

You may download latest version here (open the downloaded file with Firefox)


kick it on DotNetKicks.com
Accessibility presentation at SRL

Accessibility presentation at SRL

 On Tuesday, January 6th, I held a presentation on the monthly SRL .Net developer
 meeting. The theam was accessibility which is n area I've become aware about
just recently.

We've heard a site in screen reader, talked about accessibility in general,  what
is it good for? for whom? What are the main things to take not account while
building an  accessible application or making old one accessible, and presented
some testing tools at the end.

 

 You can download my presentation (PDF format) from here

kick it on DotNetKicks.com
How to divide page into user controls as quietly as possible?

Post by my friend and colleague Gil Fink, has reveled one of the difficulties of our project.
A legacy system, poorly designed and implemented and our need of rewriting some of
it's code in order to make it easier for us to extent it with more features as demanded
by our users.

Another aspect of our legacy system was pages with lots of controls, almost each and every
one of them has server-side event (click, textChanged, selectedIndexChanded, etc.) while
best practice is to divide the page into units of User Controls while the page acts as a router
between them and between them and the business layer.

 

So, How can we change the existing situation to be closer to the desired one?
Here we have a long and risky process, I'll try and  give it's details:

 

"Before you begin" stage

1. Make the time to work on it. It is long process and you can fall into many
   holes along the way. If you have the time to work on it continuously it's you
   can proceed, if  not - ask for the time. If it is very much needed, you'll be given
   the time to do so.

"Begin" stage

2. Cut all markup belongs to the user control which you need to divide into a new
    User control. Do not transfer any code-behind at this stage! Put the new
   User control inside the page where the transferred markup used to be.

Compilation Errors correction stages

3. look at all compilation errors. Courtesy of VS2008 SP 1 you'll see it all without
    compiling, given that your changed page is open. The compilation errors  will
    mostly be the absence of the controls transferred to the new user control.
    For each control being transferred, make a property represents it's data . By all
   means, do not expose any inner control as public property
. Here you can also
   change the data type (which is string most of the time, to the type needed ,
   and put all parsing code inside the property).
   After doing so, whenever the page's code behind takes data you can replace
   the controls by the user control's data properties you've created.
   Note - this should be done with caution because data type changing are risky
  

4. There are still compilation errors, these errors refers to the control's state, style
   etc. Here you have no choice but to move this code to the user control.
   Make small methods in the user control, corresponding to the methods on
   the page's code behind, transfer the lines referring to the internal controls
   and call these methods from the original methods.
   For example : if you have a method call SetUIState containing lines referring
   to the inner control,make a public or an internal method inside the user
   control, call it SetUIState, transfer the relevant lines into it and call it
   from the original method.

Runtime exceptions correcting stages

5. By now, all compilation errors should be corrected, however our control
    won't work mainly because it doesn't contains the event handlers to
    handle it's inner controls evens. Therefore we do the following:
    For each event of the inner control we make public event of the user
    control, a protected event handler that will only invoke the event
    recently created.

6. On the page's markup we should add all events created on step 5 and
    for each event we associate  the event handler to the old event handler was
    for the inner control while being on the page. That's how we won't
    change server side behavior of our page.

Client code handling

7. Now, that all runtime exceptions should be behind us, it's time to
   handle client errors that might occur. Client errors may occur if there
   is JavaScript code referring to the control's ID hard coded, and where
   there is client scripting referring to the internal controls with server
   code islands, which will cause runtime errors.
   Here you have to do the following:
   A. Take all client code referring to the internal controls to the
        user control's markup.
   B. Whenever there is reference to the internal control ID's in client
        script, you should change it to <%=YourInternalControl.ClientID %>
        That's because whenever a control is put inside composite control
        (or user control for that meter) it changes it's ClientID.

 

Summery: This was a long post mainly because the process is long. The goal
is to gain more encapsulation and code clarity for our system without changing
it's functionality. However, this is just the first step. You soon will see
that you have a little bit clearer code and but this is only the first step
of a long journey of making it better.

kick it on DotNetKicks.com
Posted: Dec 20 2008, 10:04 PM by Ran Wahle | with 3 comment(s) |
תגים:,
Behind The Scene - Control ID's in ASP.Net

Behind The Scene - Control ID's in ASP.Net

We all familiar with the terms of ID, ClientID and UniqueID which are
properties of Control class. In this post I'll dive into the way the last two
read-only properties values are being set and when.

The difference between ClientID and UniqueID

Let's go to the basic HTML form. The form's inputs (I.E text-boxes,
Checkboxes, DropdownLists, RadioButtons) has two basic HTML attributes
called id and name (in small letters which is the standard for HTML attribute) .

The "id" attribute is used by client scripting code to access the element (hopefully
you're using document.getElementById or $get and not accessing it like an inner
property of the form or document.all which are not standard).
The "name" attribute is used as a key in the data being sent to the server when submitting
the form.

On simple form you see that both attributes are the same. However when using a master page,
Field inside User control / CompositeControl / other controls implementing INamingContainer
you see the character of "_" inside the ID attribute and the "$" inside the name attribute.

Note: On ASP.Net 1.1 or sites migrated from it,  you may see the ":" seperator on the "name"
attribute instead of the "$" sign. You can set the option of the legacy rendering by changing
the  XhtmlConformanceMode on your web.config file.

The HTML attribute of ID corresponds to the server property of ClientID while the Name HTML
attribute corresponds to the UniqueID . One common mistake I've seen is developers confusing
between the two. Internet Explorer will forgive you for binding the UniqueID to client code,
however browser of another kind will issue a script error because it won't find the HTML element.

 

How both properties are set

Both properties have get accessor only. First, let's have a look of Control.UniqueID  property:
(with courtesy of RedGate Reflector)

public virtual string UniqueID
{
get
{
if (this._cachedUniqueID == null)
{
Control namingContainer = this.NamingContainer;
if (namingContainer == null)
{
return this._id;
}
if (this._id == null)
{
this.GenerateAutomaticID();
}
if (this.Page == namingContainer)
{
this._cachedUniqueID = this._id;
}
else
{
string uniqueIDPrefix = namingContainer.GetUniqueIDPrefix();
if (uniqueIDPrefix.Length == 0)
{
return this._id;
}
this._cachedUniqueID = uniqueIDPrefix + this._id;
}
}
return this._cachedUniqueID;
}
}

As you can see, it uses _cachedUniqueId for caching (it also clears when the ID is changing).
However, the main logic of the accessor is assemble the UniqueID with the string returns
from namingContainer.GetUniqueIDPrefix(). This method is recursive while each NamingContainer
calls it's own NamingContainer (The first control that implements INamingContainer contains
this control, not necessarily it's parent) and assemble the UniqueID
of <Container>$<Container>$<Container>$<Container>$...$<ID>.

The CientID is simpler. It simply replaces the seperators. Let's have a look at the code:

public virtual string ClientID
{
get
{
this.EnsureID();
string uniqueID = this.UniqueID;
if ((uniqueID != null) && (uniqueID.IndexOf(this.IdSeparator) >= 0))
{
return uniqueID.Replace(this.IdSeparator, '_');
}
return uniqueID;
}
}
 

In conclusion:

1. UniqueID is the property corresponds to the input's name on client side.
   In order to get it's value from the Request object wee need to call
   Request[<control>.UniqueID]

2. ClientID corresponds to the input "id" on client side. we need it to bind
   to the client code when accessing the HTML element rendered from the
   control on the client side.

3. UniqueID is assembled from the control's naming container ID prefix
    and the control ID. It is also  cached. Therefore it is recommended not
    to change the control's ID more than once.

4. The UniqueID won't necessarily contain the parent of the control.
    If you have a custom control consists of some controls it is better to
    use CompositeControl or any other control implements  INamingContainer
   
than using WebControl or other.

5. After doing so, no need to change the ID property to more than an identifier
    to the control itself.   Placing an ID of "<parentid>_<controlId>" will cause the
    parent id to be chained twice.

kick it on DotNetKicks.com
Posted: Nov 27 2008, 01:57 AM by Ran Wahle | with 1 comment(s) |
תגים:,
AJAX and Dates

AJAX and Dates

Clock While AJAX in general, and Data-Services in particular
becomes more and more in use, you may encounter a
problem of sending / receiving dates when you don't
usually share the same Time Zone settings.

 

Dates between services

When sending dates over soap the date is serialized
with the date and it's time zone
(The GMT +/- # part which comes straight after
the date itself).

When consuming a service through .Net application you won't notice
any difference, That's mainly because it  is being translated to your local time.
What's happens "behind the scene" is that the universal time is being sent
with the "Kind" property of "Utc", then it is being translated to your local time
according to your machine's time zone settings.

And what about your browser?

That's not exactly the situation when the service consumer is your browser.
On some browsers, when receiving dates through JSON, the date sometimes
keep it's original settings of date + time zone. displaying the hour with
date.format("HH:mm") can cause the hour not to be displayed according
to your time zone. I've encountered browsers of the same kind and version
that treat dates differently on different computers so you really cannot determine
what each browser will do.

How to determine what is the client treatments for dates?


Using the getTimezoneOffset() method of JavaScript date object
can be helpful, you can determine the client's time zone by using it
for a date created on client side, you can compare it with the server's
time zone in many ways : Sending the time-zone offset to the server
and compare the server's time zone there, You can send the time zone offset
along with the date from the server to the client and make your comparison
there. It is all depend on where the date object is in, posted date or response.

Just remember - the getTimezoneOffset returned in minutes and with the opposite
sign (meaning - date with Jerusalem standard time will return the result of -120).

What do you want to do with the date?

After you have this information you have to decide what you want to do with
it. If you want to display your dates according to your time zone,  determine what
your browser is doing by comparing the getTimezoneOffset() with the actual time zone
on the server. Then, you might want to set you date according to your policy by using
the setMinutes method .When deciding, you might take into account that on the client
side what you most of the time is displaying, and if you didn't use AJAX you would probably
display the dates according to the server's time zone.

 

Some Code examples in JavaScript

In here - the server sends the time zone offset inside the response (TimeZoneOffsetInMinutes):

var tzGap = resopnse.Date.getTimezoneOffset() * (-1) - response.TimeZoneOffsetInMinutes;

 if (tzGap != 0)
{

        //Change the date to the server's time zone
        response.Date.setMinutes(response.Date.getMinutes() - tzGap);

}

Note: What I did was actually changing the date, I cannot change the date's time zone offset
in JavaScript so the date in here is different from the date on the server.
Anyway - you have to omit time zone effect when sending the date to the server.

 

Summary:

Dealing with dates with web services was always tricky because of different time-zone settings.
It became evenmore tricky when the client is our browser (on AJAX) and we have to use some
good-old JavaScript tricks to overcome this issue. When sending dates from your client,
it's back to .Net code again and the date being sent is of "Utc" kind
(meaning that you can extract the client's time zone easily).
You can read about it in my "AJAX and DST difference" post.

kick it on DotNetKicks.com
New hours reporting system @ SRL

 

SRL, the company I work for, for the past two years, is saying goodbye to it's old hours reporting system.
Made By SRL The old system, which was developed long before I've started working there
and served SRL employees ever since, will continue serve SRL payroll staff
(untill  we move all management interfaces to the new system)but all other workers
are going to use the new one.
Usually this news it's not very exciting, not enough to write about, however
in this case, I was the one who developed it.

 

It has all started on my first week on the job. No Internet access at work
(It's alright I have one now) and non-windows OS at home has prevented
me from filling my hours report on this system which supports IE only.
A simple mail to my manager asking her to make a few adjustments in the system's
JavaScript to make it cross browser, has led me to complete replacement of the
hours reporting interface.


It took a great deal of studying new stuff for me, along with investigating the old system's
database and code. A great help in interface design and graphics from
my College Irena Chernov and receiving recommendations and remarks
from an endless list of colleges whom I've
recruited to the pilot team.

The development involved Lot's of AJAX, no Update panel, meaning that
the UI changes was almost solely on client side (Table created  on JavaScript after data
received from an AJAX enabled web service ), and a DAL adjusted to work with
the existing system's DB schema.

This has allowed as to have both old and new systems working
side by side so our payroll stuff can still work with their management
screens (that wasn't rewritten for the new system), along with employees
ability to enjoy a faster, cross browser and with some new features (Jewish
holidays built in the hours reporting table).

Needless to say that there were some problems along the way. Working
directly with clients outside our office raised DST setting difference
problem. The time needed to work on the system couldn't be on
working hours (because I work at a customer's site) which caused
the development process take much longer than expected, however
working on the new system was fun even so.


This is the opportunity to thank SRL staff for their trust,
Although the market is full with these kind of products and although these
kind of systems are considered  critical I was allowed to build one for SRL.
I want to thank all people who helped me along the way and to those who'll
suffer some bugs (hope not many and no critical ones).

And now for the next project...

Using Firebug extension

Before Visual Studio 2008 there wasn't many decent client debugging tools.
One of the tools that were already (and for free) was the Firebug extension Firefox
for Firefox.

Firebug provides, among it's many features an in-browser script debugger
which consists some basic debugging features such as break points, step 
into functions, watches of local and global variables, automatic variables
and so on...

 

Script debuggingFirebug

Like in VS-2008, you can actually debug your client scripts. the main difference is
that you can stay on the browser and not even have to open Visual Studio for
that meter. All you have to do is go to the script tab, click on the script
resource being debug (third tab on the top).
and reveal the list of scripts. Clicking the selected row will reveal the client
script produced there.
image

There clicking on a row will create a breakpoint, from there on - you can go with
the usual F10, F11 and F5 buttons we al familiar with...

image

Error counter

Moreover, one of it's best debugging features, provided also out of the  Firefox
Error-Consoleimage is the client error list.  It displays an error counter and provide
links to the relevant line by clicking on the specific error. 

 

 



Scripts error console

Script source

Net transport

Like Fiddler tool, Firebug provides also a list of all page related requests with the raw data being
sent and received from the server. The difference between these two tools is that
Firebug provides only page-related requests, meaning that the list is being cleared on
every page replacement.
Viewing net transport 

You can press the expand button (from this tab and from the console tab)and see headers, parameters or post data, and response:

Viewing net transport from console tab
Note: In order to see that response you'll have to press a button, that's because firebug didn't
want the performance penalty of processing each response on the browser and on firebug.

Client script profiling                                  

One of it's latest services is the script profiler, all you have to do is click "Profile" at the top and
click it once more to stop profiling. When you've first clicked, a console record is created and when
you've second clicked, the record is expanded to provide a profile report as seen in the picture below.
 

Firebug Profiler


however, this tool is not perfect

JavaScript is many time a headache, using firebug won't  solve it, at least not completely
. Moreover, sometimes it will add it some headache of it's own. For example -
if you're using multiple tabs you will see sometime scripts from another tab.
Although a major performance improvement regarding performance, firebug is still a
debugging tool and therefore it slows your page loading process.

It's user interface is much less convenient that Visual Studio, for example the collapsible list
of the script resources to debug. It's DOM inspector and CSS editor are far less effective than
other tools available and so on...

 

In conclusion

Need a tool for script debugging, especially  if your targeted audience has multiple browsers
and you need your client script to be the closest you can to the standards? you may use
Firebug.
Need to review a web application client performances, need to track down errors easily -
Firebug may be your answer.
However, if you've developed an IE only application , Firebug may not worth the overhead
of making it standard.

On the other hand, it will suit you best if you're developing a web application that should
support almost all browsers (where it's better to develop for Firefox and test on other
browsers). It's is best for AJAX developers because of it's joined abilities of monitoring
your XHR transport and debug your script.

kick it on DotNetKicks.com
Get Rid of COM+ Application after Migrating to Framework 2.0

Get Rid of COM+ Application after Migrating to Framework 2.0

Scenario: Let's say that you went to work on an already-in-production system
which started on the old ages on Framework 1.1 (or lower). Back then,
transaction management could only be via COM+ application.

Beside it's advantage (back then...) in transaction management using COM Plus
is a burden for developers and has performance penalty because of inter process
communication between the main process and the DLLHost.exe that runs
the COM Plus.
Moreover, this architecture suffers from maintenance difficulties because you
have to keep at least two .config files, maybe share Dll files, and many other
error possibilities.

Therefore, altohugh COM+ has alot more to offer than only transaction management
(and because we have used nothing but transaction management)  after migrating our
system to .Net Framework 2.0 we've decided to use the  TransactionScope of
System.Transaction rather than the ContextUtil of System.EnterpriseServices and let
our COM+ application go 

The Process:

The code, before the process should look this way:

Class decleration:

[Transaction(TransactionOption.Required)]

    public class YourClass : ServicedComponent

 

Your methods may look like this:

public void UpdateSomething()

        {

            try

            {

                //Your code here

                ContextUtil.SetComplete();

            }

            catch(Exception ex)

            {

                ContextUtil.SetAbort();

            }

        }

Or, with an AutoComplete attribute, like that:

       [AutoComplete]

        public void UpdateSomething()

        {

                //Your code here

        }

1. Loose the reference to System.EnterpriseServices (unless you need it
    not only for transaction management)
    If you do need this reference besides transaction management matters,
    you may temporarily loose it  and correct only the transaction-related
    compilation errors to come.
   

2. Add reference to System.Transactions

3. Loose the ServicedComponent inheritances  and Transaction
    attribute for your class.

4. On every method, Insert the using (TransactionScope ts = new TransactionScope(TransactionScopeOption.Required))
    block  to cover all transaction activities area.

    After doing so, your method should be looking like that:

    public void UpdateSomething()

        {

            try

            {

                using (TransactionScope ts = new TransactionScope(TransactionScopeOption.Required))

                {

                    //Your code here

                    ts.Complete();

                }

            }

            catch(Exception ex)

            {

                //Do something with the exception

            }

        }

5. If your transaction managing methods uses ContextUtil.SetComplete() /
    ContextUtil.SetAbort() methods you might  replace the ContextUtil.SetComplete()
    call  by ts.Complete() call and erase the ContextUtil.SetAbort() call.
   If your method is decorated by an AutoComplete attribute you might
   place the ts.Complete call at the end of  your TransactionScope block.

6. After your transaction managing assembly is compiled, all calling assemblies
    project probably have compilation error,  that is because  your classes
    won't implement IDisposable (implemented by ServicedComponent) anymore,
    and  therefore you  cannot use them in a using(...) block.
    Here you have two options:
      A. Implement IDisposable   yourself.
      B. Remove the using(...) block and call them regularly.
   Because from now on, these classes will be used on the same process,
   you don't have to use the using(...) block and therefore I'd recommend
   removing the using(...) block and call them regularly.


This process might take long but it can be done in steps. You can remove
the System.EnterpriseServices reference deal with several classes,
add it back on, deal with calling assemblies compilation errors and so on...

Summary:

If you've used COM+ for transaction management solly Loosing the dependency
on COM+ application is worthwhile, although it is a long process and must be
done with extreme caution. The transaction managing assembly  is most of
the times the business layer assembly and needless to say how harmful reckless
changes can be there.
However, If there is one thing my colleges thank me for, loosing the COM+
application it is.

kick it on DotNetKicks.com

Sending complex typed data from web service to SilverLight client - Part III

Sending complex typed data from web service to SilverLight client - Part III

On my previous post I discussed the JavaScript mediator part, 
Here I'll sum this part which is Serialize the object for the SilverLight
component and operate method inside it to bind the data.
Step 5 - Serialize the data for the SilverLight component
And here is the code converting the objects 
function onGettingAllEmployeesSuccess(result)
{
var slEmployees = new Array(result.length);
for (var index = 0; index <result.length; index++)
{
var newEmployee =
{
"FirstName" : result[index].FirstName,
"LastName" : result[index].LastName,
"EmployeeNumber" : result[index].EmployeeNumber
};
slEmployees[index] = newEmployee;
}
//Serialize the employees
var slSerEmployees = Object.toJSON(slEmployees);
//Bind the data on the silverlight component
$get("Xaml1").Content.silverlightManagedCode.BindListBox(slSerEmployees);
}
The method Object.toJSON is taken from the file Prototype.js written by 
Sam Stephenson and distributed freely on http://www.prototypejs.org/
And Finally - Let's insert our SilverlLight control into our test page:
...
<asp:Silverlight ID="Xaml1" runat="server"
Source="~/ClientBin/<YourSilverLightProjectName>.xap"
Version="2.0" Width="100%" Height="100%" />
...
Summary: In order to have complex typed data sent from 
your server to your Cleint's SilverLight control via JavaScript you
need to do the following:
1. On your SilverLight project code - write a class with data corresponds 
to the data you get from your server.
2. Write JavasCript mediator between your page and your SilverLight control
3. Operate method from your page on your SilverLight control to bind
the serialized data received.
I've attached the SilverLight project's code so you can get started 
with your server & mediator easily.
 
AJAX WEB Methods and Daylight Saving Settings

AJAX WEB Methods and Daylight Saving Settings

As most of you know, although our computer displayed time moves forward
by an hour on DST period, It's time isn't changing actually, it just moves to
it's neighboring time zone.

This is in order not to change the computer UTC so different DST setting on different
countries won't  cause actual time difference between computers.

However, many system administrators doesn't know how to configure correctly
the time zone shift and instead they simply setting the clock forward / backwards by
one hour.

 

In an hours reporting system which I've developed I came across a side effect of the
phenomenon mentioned above. When reporting a working day hour one of my colleague
has discovered that his report was "shifted" one hour sooner. The cause of it was
combination of wrong DST settings on the customer's site  along with right settings on
our company's site.

 

Well, In order to solve this problem we cannot change the customer's settings (It's a bank,
they cannot change something so fundamental so rapidly...) and we also can't (and won't)
change our company's settings to the wrong ones, what we can do is sending the client's
current date as a parameter so we can "fix" the dates being sent back to it, if needed.

What we basically need to do is send is the current date from our client.

For that meter we will simply call the new Date() function in our client side.

The server, from it's side, will receive it as a UTC date (you can check it by  reading it's Kind
property on the server side or simply by checking the date itself while your client and server
are on the same computer.

Now, all you have to do is compare the date received with the server's UTC date and
correct the dates being sent back to the client if needed..


 var hoursToAdd = clientDate.Subtract(DateTime.Now.ToUniversalTime()).Hours;
.
.
.
//Correct the hour "Gap"
MoveHour(result, hoursToAdd);


The MoveHour method implementation simply "shift" all the dates sending
back to the client
by the "gap" needed. I did not post the implementation
because it differs from one structure to another and it is very simple.
I know I could use the TimeSpan object
itself (without it Hours property)
to correct the gap but this was an example for work around the DST
miss-configuration and I used the Hour property to make it clearer.

Note: This solution contains security risk. If you sent sensitive
data and you relay on time stamp, you
cannot use this solution.
Moreover, if you're using your web service with another system
(not a browser to service like in AJAX) and you're
implementing WS security this solution is not enough.

To sum up: This solution can go where you have no other choice.
We use it simply because we cannot force large organizations to correctly
configure their DST settings. The date being sent from the client is the
client's machine current UTC time and therefore it is easy to compare
with the server's current UTC time. The rest is too easy to write about...

kick it on DotNetKicks.com 

Sending complex typed data from web service to SilverLight client - Part II

Sending complex typed data from web service to SilverLight client - Part II

On my previous post I've explained the first steps of creating the service and methods on the server side, and the client
corresponding objects in the Silverlight project. Here I'll go further on the JavaScript mediator side.

After making the Web method for getting the employee, we have to call it from out JavaScript mediator,  convert the objects received from the server to the SilverLight corresponding ones, and serialize the objects for our SilverLight component.

Step 3 - Create the JavaScript mediator:

Here is the code for the service call (very simple one but nevertheless...)

function loadEmployees()
{
    Billing.GetAllEmployees(onGettingAllEmployeesSuccess, onError);   
}

Step 4 - Write the Databind Method on the SilverLight control code

In order to operate methods of your Silverlight control from 
JavaScript code, you have to decorate your control class with
ScriptableType attribute and your methodswhich you want to access
with ScriptableMember attribute
 [ScriptableType]
    public partial class Page
    {
.
.
.

//Method to access from JavaScript
 [ScriptableMember]
        public void BindListBox(string employeesString)
        {
            MemoryStream memStr = null;
           
            try
            {
               //Deserialize the data received from the JavaScript mediator
                var jSer = new DataContractJsonSerializer(typeof(Employee[]));
                memStr = new MemoryStream(Encoding.Unicode.GetBytes(employeesString));
                var employees = jSer.ReadObject(memStr) as Employee[];
                
               //Bind the deserialized object with a control (Listbox in that case) 
                Employee.ItemsSource = employees;
               
                Employee.Width = GetMaxWidth();
            }
            catch (Exception ex)
            {
               //This is for debuging, you can operate JavaScript methods of the page
              // as an HtmlPage public methods
                var message = ex.Message;
                HtmlPage.Window.Alert(message);
            }
            finally
            {
               //Close the memory stream to release resources
                if (memStr != null)
                {
                    memStr.Close();
                }
            }
        }
}
On my next and last post I'll go into the JavaScrip mediator
and sum everything up.
Sending complex typed data from web service to SilverLight client - Part I

Sending complex typed data from web service to SilverLight client - Part I

In this post I'll explain in how to send complex typed data between web service and SilverLight  client
code. In order to avoid security issues I'll use JavaScript as mediator between my server code and SilverLight
code.

 

First - Let's have a look at a solution contains web server side code with all layers (Presentation that will host
silverlight  control , BL, DAL, Structures)
and another SilverLight project

Solution screenshot

Now, leaving out all server-side lower layers and focusing on presentation layer
and SilverLight code, let's have a look at what we'll demonstrate:

1. Getting complex typed data from the server via JavaScript .
2. Sending some of the data to SilverLight control
3. Presenting data on Silverlight control (A simple ListBox for that matter).

Step 1 - Create a server web method to provide as with the data we need:

[WebMethod(EnableSession = true)]   
 public List<Employee> GetAllEmployees()    
{        
        var result = new List<Employee>();       
        //Adding some employees to the collection       
        result.Add(new Employee()
       {EmployeeNumber = 1,   FirstName = "Ran", LastName = "Wahle"});        
        result.Add(new Employee()    
       {EmployeeNumber = 2,  FirstName = "Anonymous", LastName = "Employee"        });                                           result.Add(new Employee() 
        {EmployeeNumber = 3 , FirstName = "Known", LastName = "Employee"});               
                
         return result;   
 } 



 

Step 2 - Create object similar to the one in the server site.
At this stage the word "Why" might come to mind followed by a question mark...
The reason for that is simple - we cannot make reference from SilverLight project to
a regular .Net one because SilverLight runs on compact framework and therefore can have referenced to SilverLight projects only.

However, You might of course use the service referenced object if you   connect to a service, here we don't do it to avoid security failures may caused by connection service
directly from the Silverlight object.

public class Employee
{
    public string FirstName { get; set; }
public string LastName { get; set; }
public string FullName
{
get
{
return string.Format("{0} {1}", FirstName, LastName);
}
}
public int EmployeeNumber { get; set; }
}

On the second part I'll explain how to serialize the objects through JSON.

kick it on DotNetKicks.com

Technorati Tags: ,
More Posts Next page »