Our Services
Recent Posts
02/02/2010 |Karl Hering
ASP.NET 2.0 brought a lot to the table with the Membership and Profiles API, and when coupled with some fine techniques provided by jquery some very sleek-looking login functionality can be provided to your users. We just finished a nifty presentation model when working with login functionality for a new non-for-profit site; SpaceForGood.  This article will attempt to highlight the core settings used to put together the Profiles web services with your site, as well as depict an example of the script used to invoke it client-side. First of all I want to bring out that this article is going to assume that you are already familiar with the Profile API of ASP.NET 2.0. You should already know how to make a connection string in your web.config file, and at least a brief understanding of membership, users and the concept of each user having their own profile. Also, you should at least be somewhat familiar with ASP.NET AJAX and how to put the dll's in your bin folder and update your web.config. Even if you're not fully up on these concepts just yet, you can still benefit from seeing how easy it is, and maybe that will inspire you to get started. Exposing Your Profile in the Web.config In order to access the profile service vis-a-vis AJAX or jquery, you will have to enable a few properties in your web.config first: <profile>      <providers>        <clear/>        <add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" connectionStringName="MyConnectionString" applicationName="/" />              </providers>      <properties>        <add name="FirstName" type="System.String"/>        <add name="LastName" type="System.String"/>        <add name="JobTitle" type="System.String"/>        <add name="Email1" type="System.String"/>        <add name="Email2" type="System.String"/>        <add name="Email3" type="System.String"/>        <add name="HomePhone" type="System.String"/>        <add name="WorkPhone" type="System.String"/>        <add name="MobilePhone" type="System.String"/>        <group name="Organization">          <add name="Keys"/>        </group>      </properties>    </profile>     ... <system.web.extensions>    <scripting>      <webServices>        <authenticationService enabled="true" />        <roleService enabled="true"/>        <profileService enabled="true" readAccessProperties="FirstName, LastName, Email1, Email2, Email3"/>              </webServices>    </scripting>  </system.web.extensions> Once you have enabled the service in your web.config file, you can interact with these services using codes somewhere along the lines of... // login function doLogin() {     $("#loginMessage").html("");     var userNameValue = $("#userNameInput").val();     var passwordValue = $("#passwordInput").val();     var rememberMeValue = $("#rememberMeInput").val();     var persistLogin = (rememberMeValue == "persist");     // call the authetication service to authenticate the credentials entered by the user.     Sys.Services.AuthenticationService.login(userNameValue, passwordValue,         persistLogin, null, null, OnLoginCompleted, OnAuthenticationFailed, "User Context"); } // login completed function OnLoginCompleted(validCredentials, userContext, methodName) {     if (validCredentials) {         $("#username").attr("value", "");       // clear login entry         $("#password").attr("value", "");       // clear password entry         LoadRoles();     }     else {         $("#loginMessage").html("Invalid user credentials");     } } // logout completed function OnLogoutCompleted(result) {     $("#username").attr("value", "");   // clear login entry     $("#password").attr("value", "");   // clear password entry     $("#userWelcomeDisplay").html("Hello There!");   // obviously you can do something more elaborate } // authentication failed function OnAuthenticationFailed(error, userContext, methodName) {     alert("Authentication service failed with message: " + error.get_message()); } // loads the profile of the current authenticated user function LoadProfile() {     var loggedIn = Sys.Services.AuthenticationService.get_isLoggedIn();     if (loggedIn) {         Sys.Services.ProfileService.load(null, OnLoadProfileCompleted, OnLoadProfileFailed, "User Context");     }     else {         OnLogoutCompleted(null);     } } // reads the profile information and displays it function OnLoadProfileCompleted(numProperties, userContext, methodName) {     // todo: display some user information } // callback function called if the profile load or save operations failed. function OnLoadProfileFailed(error, userContext, methodName) {     alert("Profile service failed with message: " + error.get_message()); } 
01/11/2010 |Karl Hering
If you are recieving the generic error "Sequence contains no elements." it is because LINQ creates an InvalidOperationException when you are looking for a record that doesn't exist. Your code may look something like... return this.DataContext.MyRecords.Single([expression]);return (from record in DataContext.MyRecords where [someCondition] select record).Single(); In place of of Single, you can alternatively use SingleOrDefault, which will return null if the object doesn't exist. return this.DataContext.MyRecords.SingleOrDefault([expression]);return (from record in DataContext.MyRecords where [someCondition] select record).SingleOrDefault();
12/14/2009 |Karl Hering
I'm continuing my previous post to include a few more tips to help you...mainly concerned with execution performance. I know that with my projects, time is always the issue. What may seem like a small 5-10 min transfer operation becomes large when coupled with 45 other processes that must run in the morning as part of a data warehouse load. With SQL Server 2008, I recently read that SSIS 2008 has further enhanced the internal dataflow pipeline engine to provide even better performance, you might have heard the news that SSIS 2008 has set an ETL World record of uploading 1TB of data in less than half an hour. Pulling High Volumes of Data As part of a recent project, we had to pull data from a source table which had ~ 4 million records to a new target table. Initially when the SSIS package started, everything looked fine, data was being transferred as expected but gradually the performance degraded and the data transfer rate went down dramatically. During analysis we found that the target table had a primary clustered key and two non-clustered keys. Because of the high volume of data inserts into the target table these indexes got fragmented heavily up to 85%-90%. We used the online index rebuilding feature to rebuild/defrag the indexes, but again the fragmentation level was back to 90% after every 15-20 minutes during the load. This whole process of data transfer and parallel online index rebuilds took almost 12-13 hours which was much more than our expected time for data transfer. Then we came with an approach to make the target table a heap by dropping all the indexes on the target table in the beginning, transfer the data to the heap and on data transfer completion, recreate indexes on the target table. With this approach, the whole process (by dropping indexes, transferring data and recreating indexes) took just 3-4 hours which was what we were expecting. Rows Per Batch Settings Rows per batch – The default value for this setting is -1 which specifies all incoming rows will be treated as a single batch. You can change this default behavior and break all incoming rows into multiple batches. The allowed value is only positive integer which specifies the maximum number of rows in a batch. Maximum insert commit size – The default value for this setting is '2147483647' (largest value for 4 byte integer type) which specifies all incoming rows will be committed once on successful completion. You can specify a positive value for this setting to indicate that commit will be done for those number of records. You might be wondering, changing the default value for this setting will put overhead on the dataflow engine to commit several times. Yes that is true, but at the same time it will release the pressure on the transaction log and tempdb to grow tremendously specifically during high volume data transfers. The above two settings are very important to understand to improve the performance of tempdb and the transaction log. For example if you leave 'Max insert commit size' to its default, the transaction log and tempdb will keep on growing during the extraction process and if you are transferring a high volume of data the tempdb will soon run out of memory as a result of this your extraction will fail. So it is recommended to set these values to an optimum value based on your environment. Note: The above recommendations have been done on the basis of experience gained working with DTS and SSIS for the last couple of years. But as noted before there are other factors which impact the performance, one of the them is infrastructure and network. So you should do thorough testing before putting these changes into your production environment. Avoid SELECT * I know this recommendation has been around forever for most DBAs and developers, but in SSIS there is an additional important consideration to avoid using SELECT *. The Data Flow Task (DFT) of SSIS uses a buffer (a chunk of memory) oriented architecture for data transfer and transformation. When data travels from the source to the destination, the data first comes into the buffer, required transformations are done in the buffer itself and then written to the destination. The size of the buffer is dependant on several factors, one of them is the estimated row size. The estimated row size is determined by summing the maximum size of all the columns in the row. So the more columns in a row means less number of rows in a buffer and with more buffer requirements the result is performance degradation. Hence it is recommended to select only those columns which are required at destination. Even if you need all the columns from the source, you should use the column name specifically in the SELECT statement otherwise it takes another round for the source to gather meta-data about the columns when you are using SELECT *. OLEDB Destination Settings There are couple of settings with OLEDB destination which can impact the performance of data transfer. Data Access Mode – This setting provides the 'fast load' option which internally uses a BULK INSERT statement for uploading data into the destination table instead of a simple INSERT statement (for each single row) as in the case for other options. So unless you have a reason for changing it, don't change this default value of fast load. If you select the 'fast load' option, there are also a couple of other settings which you can use as discussed below. Keep Identity – By default this setting is unchecked which means the destination table (if it has an identity column) will create identity values on its own. If you check this setting, the dataflow engine will ensure that the source identity values are preserved and same value is inserted into the destination table. Keep Nulls – Again by default this setting is unchecked which means default value will be inserted (if the default constraint is defined on the target column) during insert into the destination table if NULL value is coming from the source for that particular column. If you check this option then default constraint on the destination table's column will be ignored and preserved NULL of the source column will be inserted into the destination. Table Lock – By default this setting is checked and the recommendation is to let it be checked unless the same table is being used by some other process at same time. It specifies a table lock will be acquired on the destination table instead of acquiring multiple row level locks, which could turn into lock escalation problems. Check Constraints – Again by default this setting is checked and recommendation is to un-check it if you are sure that the incoming data is not going to violate constraints of the destination table. This setting specifies that the dataflow pipeline engine will validate the incoming data against the constraints of target table. If you un-check this option it will improve the performance of the data load.
11/03/2009 |Karl Hering
I've been employing SQL Server Integration Services for some years now and find it to be quite an improvement over its predecessor Data Transformation Services. Apart from being an ETL product, it also provides different built-in tasks to manage a SQL Server instance. SSIS is not an enhancement to DTS but rather a new product which has been written from scratch to provide high performance and parallelism and as a result of this it overcomes several limitations of DTS. Not to mention the fact that versions of each package are easilty stored and maintained using TFS, and so plays well with other Visual Studio design elements by your support team. The best part of SSIS is that it is a component of SQL server.  It comes free with the SQL Server installation and you don't need a separate license for it. Because of this, along with hardcore BI developers, database developers and database administrators are also using  it to transfer and transform data. Here are some tips when employing SSIS that I've come across over the past couple years... Avoid asynchronous transformation wherever possible Before I talk about different kinds of transformations and its impact on performance, let me briefly talk about of how SSIS works internally. The SSIS runtime engine executes the package.  It executes every task other than data flow task in the defined sequence.  Whenever the SSIS runtime engine encounters a data flow task, it hands over the execution of the data flow task to data flow pipeline engine. The data flow pipeline engine breaks the execution of a data flow task into one more execution tree(s) and may execute two or more execution trees in parallel to achieve high performance. Now if you are wondering what an execution tree is, then here is the answer. An execution tree, as name implies, has a similar structure as a tree.  It starts at a source or an asynchronous transformation and ends at destination or first asynchronous transformation in the hierarchy. Each execution tree has a set of allocated buffer and scope of these buffers are associated the execution tree. Also each execution tree is allocated an OS thread (worker-thread) and unlike buffers this thread may be shared by any other execution tree, in other words an OS thread might execute one or more execution trees. In SSIS 2008, the process of breaking data flow task into an execution tree has been enhanced to create an execution path and sub-path so that your package can take advantage of high-end multi-processor systems. Synchronous transformations get a record, process it and pass it to the other transformation or destination in the sequence. The processing of a record is not dependent on the other incoming rows. Because synchronous transformations output the same number of records as the input, it does not require new buffers (processing is the done in the same incoming buffers i.e. in the same allocated memory) to be created and because of this it is normally faster. For example, in the Derived column transformation, it adds a new column in the each incoming row, but it does not add any additional records to the output. Unlike synchronous transformations, the asynchronous transformation might output a different number of records than the input requiring new buffers to be created. Because an output is dependent on one or more records it is called a blocking transformation.  Depending on the types of blocking it can either be partially blocking or a fully blocking transformation.  For example, the Sort Transformation is a fully blocking transformation as it requires all the incoming rows to arrive before processing. As discussed above, the asynchronous transformation requires addition buffers for its output and does not utilize the incoming input buffers.  It also waits for all incoming rows to arrive for processing, that's the reason the asynchronous transformation performs slower and must be avoided wherever possible. For example, instead of using Sort Transformation you can get sorted results from the source itself by using ORDER BY clause. DefaultBufferMaxSize and DefaultBufferMaxRows The number of buffer created is dependent on how many rows fit into a buffer and how many rows fit into a buffer dependent on few other factors. The first consideration is the estimated row size, which is the sum of the maximum sizes of all the columns from the incoming records. The second consideration is the DefaultBufferMaxSize property of the data flow task.  This property specifies the default maximum size of a buffer. The default value is 10 MB and its upper and lower boundaries are constrained by two internal properties of SSIS which are MaxBufferSize (100MB) and MinBufferSize (64 KB). It means the size of a buffer can be as small as 64 KB and as large as 100 MB. The third factor is, DefaultBufferMaxRows which is again a property of data flow task which specifies the default number of rows in a buffer.  Its default value is 10000. Although SSIS does a good job in tuning for these properties in order to create a optimum number of buffers, if the size exceeds the DefaultBufferMaxSize then it reduces the rows in the buffer. For better buffer performance you can do two things.  First you can remove unwanted columns from the source and set data type in each column appropriately, especially if your source is flat file.  This will enable you to accommodate as many rows as possible in the buffer. Second, if your system has sufficient memory available, you can tune these properties to have a small number of large buffers, which could improve performance. Beware if you change the values of these properties to a point where page spooling begins, it adversely impacts performance. BufferTempStoragePath and BLOBTempStoragePath If there is a lack of memory resource i.e. Windows triggers a low memory notification event, memory overflow or memory pressure, the incoming records, except BLOBs, will be spooled to the file system by SSIS. The file system location is set by the BufferTempStoragePath of the data flow task. By default its value is blank, in that case the location will be based on the of value of the TEMP/TMP system variable. Likewise SSIS may choose to write the BLOB data to the file system before sending it to the destination because BLOB data is typically large and cannot be stored in the SSIS buffer. Once again the file system location for the spooling BLOB data is set by the BLOBTempStoragePath property of the data flow task. By default its value is blank.  In that case the location will be the value of the TEMP/TMP system variable. As I said, if you don't specify the values for these properties, the values of TEMP and TMP system variables will be considered as locations for spooling.  What is important is to change the default values of the BufferTempStoragePath/BLOBTempStoragePath properties and specify locations where the user executing the package (if the package is being executed by SQL Server Job, then SQL Server Agent service account) has access to these locations.  Preferably both locations should refer to separate fast drives (with separate spindles) to maximize I/O throughput and improve performance. How DelayValidation property can help you SSIS uses validation to determine if the package could fail at runtime. SSIS uses two types of validation.  First is package validation (early validation) which validates the package and all its components before starting the execution of the package.  Second SSIS uses component validation (late validation), which validates the components of the package once started. Let's consider a scenario where the first component of the package creates an object i.e. a temporary table, which is being referenced by the second component of the package. During package validation, the first component has not yet executed, so no object has been created causing a package validation failure when validating the second component. SSIS will throw a validation exception and will not start the package execution. So how will you get this package running in this common scenario? To help you in this scenario, every component has a DelayValidation (default=FALSE) property.  If you set it to TRUE, early validation will be skipped and the component will be validated only at the component level (late validation) which is during package execution.
05/27/2010 |Daniel Kohler
In the previous post I showed you how to create some Powershell scripts with intention to sync up a master and secondary DNS server, specifically by creating any missing secondary zones. In this post, I'll clean up the functions and create the main script to keep things in sync. For the sake of cleanliness, I decided to split everything up into seperate reusable scripts, I have a feeling I'm going to be reusing parts of these scripts for various different things, so here are the new scripts and contents. ############################################################### # function: zone-exists # parameters: $zoneName - the name of the zone to look for # $server - the FQDN of the server to look # $useruname - user account # $password - password # returns: true/false # Author: Daniel Kohler # blog: http://danielkohler.name # Disclaimer: use at your own risk author is not responsible # for any damage you may cause by using this # script # Copyright(c) 2010 - Icon Technology Solutions, Inc. ############################################################### param([string]$zonename,[string]$server,[parameter(mandatory=$false)]$username,[parameter(mandatory=$false)]$password); $return=$false; if(($username-ne $null)-band($password -ne $null)){ $spwd=ConvertTo-SecureString $password -AsPlainText -Force $credential=New-Object System.Management.Automation.PSCredential $username, $spwd $s=new-pssession -ComputerName $server -Credential $credential enter-pssession -Session $s $c=Get-WMIObject -Class "MicrosoftDNS_Zone" -Namespace "root\MicrosoftDNS" -ComputerName $server | where-object{$_.Name -eq $zonename} $return=$c -ne $null #close session remove-pssession -Session $s #return } else{ $c=Get-WMIObject -Class MicrosoftDNS_Zone -Namespace root\MicrosoftDNS -computername $server | where-object{$_.Name -eq $zonename} $return=$c -ne $null } return $return; ############################################################### # Function: Get-Zones # Purpose: Retrieves the particluar zone by type # specified for a given # server. # Parameters: -server (required) - the FQDN of the DNS # server # -zonetype (required) - the type of zone # (0 -primary, # 1-secondary, etc) # -username (optional) - user account # -password (optional) - password for user # account # # returns: a collection of MicrosoftDNS_Zone records # Author: Daniel Kohler # blog: http://danielkohler.name # Disclaimer: use at your own risk author is not responsible # for any damage you may cause by using this # script # Copyright(c) 2010 - Icon Technology Solutions, Inc. ############################################################### param([string]$server,[int]$zonetype,[parameter(mandatory=$false)]$username=$null,[parameter(mandatory=$false)]$password=$null); $return=$null; if(($username-ne $null)-band($password -ne $null)){ $spwd=ConvertTo-SecureString $password -AsPlainText -Force $credential=New-Object System.Management.Automation.PSCredential $username, $spwd $s=new-pssession -ComputerName $server -Credential $credential enter-pssession -Session $s $Return=Get-WMIObject -Class MicrosoftDNS_Zone -Namespace root\MicrosoftDNS -computername $server | Where-Object{($_.ZoneType -eq $zoneType) -band($_.Name -ne "TrustAnchors")} remove-pssession -Session $s } else{ $return=Get-WMIObject -Class MicrosoftDNS_Zone -Namespace root\MicrosoftDNS -computername $server | Where-Object{($_.ZoneType -eq $zoneType) -band($_.Name -ne "TrustAnchors")} } return $return; ############################################################### # function: new-secondary-zone.ps1 # parameters: $zoneName - user account name # $masterIP - delimited list of master ips # $server - server # $username - user account # $password - user account password # returns: nothing # Author: Daniel Kohler # blog: http://danielkohler.name # Disclaimer: use at your own risk author is not responsible # for any damage you may cause by using this # script # Copyright(c) 2010 - Icon Technology Solutions, Inc. ############################################################### param([string]$zonename,[string]$masterIP,[string]$server,[parameter(mandatory=$false)]$username,[parameter(mandatory=$false)]$password); if(($username-ne $null)-band($password -ne $null)){ $spwd=ConvertTo-SecureString $password -AsPlainText -Force $credential=New-Object System.Management.Automation.PSCredential $username, $spwd $s=new-pssession -ComputerName $server -Credential $credential enter-pssession -Session $s $s=new-pssession -ComputerName $server -Credential $credential enter-pssession -Session $s $type=1; $fileName=$zoneName+".dns"; $adminEmail="hostmaster@" +$zoneName; ([WmiClass]"\\$server\root\MicrosoftDNS:MicrosoftDNS_Zone").CreateZone( ` $zoneName, $type, $false, $filename, ` @($masterIP),$adminEmail) #close session remove-pssession -Session $s } else{ $type=1; $fileName=$zoneName+".dns"; $adminEmail="hostmaster@" +$zoneName; ([WmiClass]"\\$server\root\MicrosoftDNS:MicrosoftDNS_Zone").CreateZone( ` $zoneName, $type, $false, $filename, ` @($masterIP),$adminEmail) } And the final script to sync everything up ######################################################################### # Utility Script: This script will create secondary forward lookup # zones on the server specified when they do not # exist. It uses a primary DNS server to # determine which zones are missing # Author: Daniel Kohler # blog: http://danielkohler.name # Disclaimer: use at your own risk author is not responsible # for any damage you may cause by using this # script # Copyright(c) 2010 - Icon Technology Solutions, Inc. ######################################################################### $userName="someuser@domain.com"; $password="someusers_password"; $primaryDNS="."; $masterIP="10.10.10.10"; [array]$secondaryDNS="ns1.domain.com","ns1.domain.com"; $credential= .\new-credential.ps1 -username $userName -password $password $zones=.\get-zones.ps1 -server $primaryDNS -zoneType 1 foreach($zone in $zones) { foreach($server in $secondaryDNS) { #determine if the zone exists on the remote server $e=.\zone-exists.ps1 -zonename $zone.Name -server $server -username $username -password $password if($e -ne $true) { #we need to create this zone on the secondary server .\new-secondary-zone.ps1 -zonename $zone.Name -masterIP $masterIP -server $server -username $username -password $password } } } All of these scripts can also be found on our forum site, http://forums.iconsolution.net/viewforum.php?f=11
05/24/2010 |Daniel Kohler
This post is going to show you how to create a resuable windows powershell script to monitor a primary DNS server for the creation of new forward lookup zones, if a new zone is detected and it does not exist on the configurable secondary DNS server, it will create a new secondary zone, setup the master server and begin a zone transfer. This script has the following assumptions: The computers must on a domain. Windows Powershell 2.0 installed on all servers. Powershell script execution is enabled (Set-ExecutionPolicy unrestricted) WinRM is configured and enabled on all servers in question. Enabling WinRM on Server 2003 R2 To enable WinRM on server 2003 R2, download and install the windows poershell 2.0.  Once you have it installed run enable-psremoting and accept the prompts. Enabling WinRM on Server 2008 R2 Just open an elevated PowerShell and run enable-psremoting and follow the prompts You could use this function to create a credential for authenticating to remote servers ############################################################### # function: CreateCredential # returns: System.Management.Automation.PSCredential # parameters: $uid - user account name # $pwd - account password # example: CreateCredential "user@123.com" "somepwd" ############################################################### function CreateCredential([string] $uid, [string] $pwd) { $spwd=ConvertTo-SecureString $pwd -AsPlainText -Force return New-Object System.Management.Automation.PSCredential $uid, $spwd } I wrote the following function to test for the existance of a zone a particular server: ############################################################### # function: ZoneExists # parameters: $zoneName - the name of the zone to look for # $server - the FQDN of the server to look # $credential - a credential with rights to the server # example: ZoneExists "123.com" "ns1.123.com" [credential] ############################################################### function ZoneExists([string]$zoneName, [string]$server,[System.Management.Automation.PSCredential]$credential) { $return=0; $s=new-pssession -ComputerName $server -Credential $credential enter-pssession -Session $s $c=Get-WMIObject -Class MicrosoftDNS_Zone -Namespace root\MicrosoftDNS -computername $server | Where-Object{$_.Name -eq $zoneName} $return=$c -ne $null #close session remove-pssession -Session $s #return return $return; } And the final function needed to create the secondary zone on the specific server ############################################################### # function: CreateSecondaryZone # returns: System.Management.Automation.PSCredential # parameters: $zoneName - user account name # $masterIP - account password # $server - server # $credential - credential # example: CreateSecondaryZone "123.com" []"192.168.1.1" "ns2.123.com" [credential] ############################################################### function CreateSecondaryZone($zoneName,$masterIP,$server,$credential) { $return=0; $s=new-pssession -ComputerName $server -Credential $credential enter-pssession -Session $s $type=1; $fileName=$zoneName+".dns"; $adminEmail="hostmaster@" +$zoneName; ([WmiClass]"\\$server\root\MicrosoftDNS:MicrosoftDNS_Zone").CreateZone( ` $zoneName, $type, $false, $filename, ` @($masterIP),$adminEmail) #close session remove-pssession -Session $s #return return $return; } Part 2 brings it all together ---> All the files needed to run this solution can be found at http://forums.iconsolution.net/viewtopic.php?f=11&t=6
05/14/2010 |Daniel Kohler
This short post will demonstrate how to configure multiple sites to use SSL on the same IP using Host Header Bindings. This example is appropriate when you have a wildcard SSL or a unified communications certificate and you want to run multiple websites over port 443.  These commands will need to be run on the web server.  Just open a command prompt and navigate to the folder containing adsutil.vbs (usually c:\inetpub\adminscripts). cscript.exe adsutil.vbs set /w3svc/[site identifier]/SecureBindings ":443:[host header]" Just run this command for each site that needs to run over SSL and you are done.
11/24/2009 |Mike Lee
Normal 0 false false false EN-US X-NONE X-NONE MicrosoftInternetExplorer4 /* Style Definitions */ table.MsoNormalTable {mso-style-name:"Table Normal"; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-priority:99; mso-style-qformat:yes; mso-style-parent:""; mso-padding-alt:0in 5.4pt 0in 5.4pt; mso-para-margin-top:0in; mso-para-margin-right:0in; mso-para-margin-bottom:10.0pt; mso-para-margin-left:0in; line-height:115%; mso-pagination:widow-orphan; font-size:11.0pt; font-family:"Calibri","sans-serif"; mso-ascii-font-family:Calibri; mso-ascii-theme-font:minor-latin; mso-fareast-font-family:"Times New Roman"; mso-fareast-theme-font:minor-fareast; mso-hansi-font-family:Calibri; mso-hansi-theme-font:minor-latin; mso-bidi-font-family:"Times New Roman"; mso-bidi-theme-font:minor-bidi;} As developers we often find ourselves torn between two different but similar technologies for a variety of reasons.  I always find myself leaning toward the Microsoft end of this spectrum whenever in doubt.  One notable exception to this “rule” of mine is something I am sure any developer is fairly familiar with, jQuery.  Javascript is unavoidable for web developers, but dealing with the document object model implemented by different browsers can be a truly frustrating task…  and then one day, in walks jQuery and provides us with a level of DOM abstraction that alleviates this giant pain in the neck. Although not exactly recent news ( http://weblogs.asp.net/scottgu/archive/2008/09/28/jquery-and-microsoft.aspx http://blog.jquery.com/2008/09/28/jquery-microsoft-nokia/ ), the fact that Microsoft now officially supports jQuery is something sure to put a smile on most of our faces.  With another official tool available I find myself yet again wondering if I should abandon one technology over the other.  Should I use jQuery for my AJAX needs, or should I use Microsoft AJAX?  Fortunately, or unfortunately depending on your viewpoint, I have to admit the answer seems to be “It depends.”     There are pros and cons to each, but from my perspective a developer (given the choice) should use whatever technology is easiest for them and fits into the projects needs.  That said, the following is an example of retrieving/sending data asynchronously using each technology.  Which you decide to use is entirely up to you. [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] [ScriptService] public class WebServiceExample : System.Web.Services.WebService {     public WebServiceExample () {            }     [WebMethod]     public string GetPeople()     {         List<Person> obj = new List<Person>();         obj.Add(new Person("John", "Doe", 18));         obj.Add(new Person("Jane", "Doe", 20));         obj.Add(new Person("Jimmy", "John", 30));         return JSONHelper.Serialize<List<Person>>(obj);           }     [WebMethod]     public string UpdatePeople(List<Person> people)     {         //Do something with each person here.                return string.Empty;     } } public class JSONHelper {     public static string Serialize<T>(T obj)     {         System.Runtime.Serialization.Json.DataContractJsonSerializer serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(obj.GetType());         MemoryStream ms = new MemoryStream();         serializer.WriteObject(ms, obj);         string retVal = Encoding.Default.GetString(ms.ToArray());         return retVal;     }     public static T Deserialize<T>(string json)     {         T obj = Activator.CreateInstance<T>();         MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(json));         System.Runtime.Serialization.Json.DataContractJsonSerializer serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(obj.GetType());         obj = (T)serializer.ReadObject(ms);         ms.Close();         return obj;     } } [DataContract] public class Person {     [DataMember]     public string FirstName { get; set; }     [DataMember]     public string LastName { get; set; }     [DataMember]     public int Age { get; set; }     public Person()     {     }     public Person(string firstName, string lastName, int age)     {         FirstName = firstName;         LastName = lastName;         Age = age;     } }   In the three classes above:  WebServiceExample contains two WebMethods GetPeople - returns a JSON string consisting of three "People" UpdatePeople - Accepts a generic list of "people".  (Doesn't actually update anything in our example)  JSONHelper contains some helper methods for serializing and deserializing to and from JSON.   Person - Just a simple class holding information about a person.   Ok, so let's assume the task is to retrieve a list of people, modify some information about those people, and send the data back to be updated.  Note for both methods I am going to use a common snippet of code to help me parse JSON results.  I do this not only for native JSON support (if the browser supports it), but also to deal with data.d headaches.   You can read more about this here:  http://encosia.com/2009/07/07/improving-jquery-json-performance-and-security/ function dataFilter(data) {     var msg;     if (typeof (JSON) !== 'undefined' && typeof (JSON.parse) === 'function')         msg = JSON.parse(data);     else         msg = eval('(' + data + ')');     if (msg.hasOwnProperty('d'))         return msg.d;     else         return msg; }       Microsoft AJAX   Add a scriptmanager to your page that has a serviceReference pointing to the appropriate web service.   <asp:ScriptManager ID="_scriptManager" runat="server">       <Services>         <asp:ServiceReference              Path="WebServiceExample.asmx" />       </Services> </asp:ScriptManager>     Make the appropriate call using the proxy generated for you by the script manager.  Note that you don't need to worry about serializing/deserializing your collection of people.     WebServiceExample.GetPeople( function OnGetPeopleSucceeded(result) {     var people = dataFilter(result);     for (var i = 0; i < people.length; i++) {     people[i].FirstName = "Johnny";     }     WebServiceExample.UpdatePeople(people,     function OnUpdatePeopleSucceeded(result) {         alert('updated');     }     ); } );               jQuery AJAX  NOTE:  With jQuery you must manually convert to and from JSON.   I elected to use the Jquery JSON plugin for this task ( http://code.google.com/p/jquery-json/ )  Add your script references :) <script type="text/javascript" src="jquery-1.3.2.js"></script> <script type="text/javascript" src="jquery.json-2.2.min.js"></script>   Make the appropriate call with the proper WebService url/method and any parameters you need.               $.ajax({                 type: "POST",                 url: "WebServiceExample.asmx/GetPeople",                 data: "{}",                 contentType: "application/json; charset=utf-8",                 dataType: "json",                 dataFilter: function(data) {                     return dataFilter(data);                 },                 success: function(msg) {                     for (var i = 0; i < msg.length; i++) {                         msg[i].FirstName = "Johnny";                     }                     var people = $.toJSON({ "people": msg });                     $.ajax({                         type: "POST",                         url: "WebServiceExample.asmx/UpdatePeople",                         data: people,                         contentType: "application/json; charset=utf-8",                         dataType: "json",                         success: function(msg) {                             alert('updated');                         }                     });                 }             });        
11/06/2009 |Mike Lee
Although I used the following method to install jQuery as a Sharepoint Farm Feature, you can obviously use this same technique for anything you want available as a SharePoint-wide feature.  I've found JQuery to be an incredible tool so I think it's more than worthy of being the main example here.  :) Step 1. Dowload the latest jQuery script and place it in C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\TEMPLATE\LAYOUTS\js Step 2. Create a Control Template for jquery in C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\TEMPLATE\CONTROLTEMPLATES  (Just a user control that has nothing but a script include pointing to the respective javascript file from step 1.) JqueryControl.ascx <%@ Control ClassName="jQueryControl" %><script type="text/javascript" src="/_layouts/js/jquery-1.3.2.min.js"></script> Step 3.  Create a Feature Template describing JqueryControl in C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\TEMPLATE\FEATURES\  (Each template being a directory with an appropriate feature.xml and <featureName>.xml…  This just points to the control template from step 2.) Please note:  When I was doing this the first time I happened to be installing both Jquery and JqueryUI as features.  In a classic forehead slap moment I completely overlooked the Id attribute of the Feature node in the feature.xml file and had duplicated the GUID in the second feature.  Needless to say, you cannot install two different features using the same Feature Id.  Avoid the forehead slap effect and generate a new GUID here:  http://msdn.microsoft.com/en-us/library/ms241442%28VS.80%29.aspx  feature.xml <?xml version="1.0" encoding="utf-8" ?><Feature Id="62D5F317-A793-4328-A250-50CBE1F5B70E"  Title="jQueryControl"  Scope="Farm"  Description="jQuery Control"  Version="1.0.0.0"  xmlns="http://schemas.microsoft.com/sharepoint/" >  <ElementManifests>      <ElementManifest Location="jQueryControl.xml" />  </ElementManifests></Feature>JqueryControl.xml <?xml version="1.0" encoding="utf-8" ?><Elements xmlns="http://schemas.microsoft.com/sharepoint/" >    <Control Id="jQueryMinifiedControl"          ControlSrc="~/_ControlTemplates/jQueryMinifiedControl.ascx"          Sequence="100" >      </Control></Elements> Step 4.  Run the following on your SharePoint server:    stsadm –o installfeature -filename JQuery\feature.xml Step 5.  Verify that the feature is enabled in:  Central Administration -> Operations -> Manage Farm Features Step 6.  Add the following DelegateControl in any page you wish to use JQuery (or in your masterpage) <SharePoint:DelegateControl ControlId="jQueryMinifiedControl" RunAt="server" /> Enjoy!
10/03/2009 |Mike Lee
 I seem to be fascinated lately with the idea of having rounded DIVs that also have transparent backgrounds.  I think it's a very cool visual effect but has always seemed problematic when attempting to make this work in different types of browsers.  The good news is that the method implemented here works for IE6, IE7, IE8, Firefox 2, Firefox 3, Safari, and Chrome.  The opaque backgrounds will work in Opera, but it would take a bit of tweaking to get the corners working.   As you probably already know (and I found out) Internet Explorer is rather troublesome (or non existent) with implementing CSS 3 features like rounded corners.  Also, even though you can create opaque DIVs in Internet Explorer, the built in approach of setting a Opacity value effects any nested children.  This is bad because it actually makes text appear opaque which is a real pain in the butt to read.  The solution to this (that seemed to work best with a variety of browsers) was to use an Opaque PNG image as a DIV backgroundimage.  Of course this removes the ability to dyamically change   Include the following: <script language="javascript" src="./scripts/jquery-1.3.2.min.js" type="text/javascript"></script> <script language="javascript" src="./scripts/browserdetect_lite.js" type="text/javascript"></script> <script language="javascript" src="./scripts/DD_roundies_0.0.2a-min.js" type="text/javascript"></script>     The following will run when the DOM is loaded:                 <script language="javascript" type="text/javascript">      $(document).ready(function() {          $('.opaque').css('background-image','url(./Images/back.png)');          DD_roundies.addRule('.rounded', '8px', !browser.isIE);      }); </script> I could have created a class in my CSS file to handle the opaque background image, but in learning a bit about jquery I felt compelled to show how a css element can be applied on the fly with very little code.  An important note here is that IE6 (and I think IE7) will NOT natively use a PNG as a background image properly.  This is solved in this case because of a fix implemented by DD_Roundies.  (Two birds with one stone!  Yipee)   DD_Roundies will add rounded corners to elements in one of two ways (three if you count IE8).  If the browser is CSS 3 compliant (or mostly compliant) it will use the appropriate border-radius property.  Because Internet Explorer does not support this is will use VML to draw the corners.    MyStyles.css (optional of course)  .box {       padding:20px;       border: 1px #767878 solid; }   Add the following class attributes anywhere you want this effect: <div id="myMaindDiv" class="rounded opaque box">     ... content here ... </div>       http://www.dillerdesign.com/experiment/DD_roundies/ http://jquery.com/

This Terms and Conditions ("Agreement") is an agreement between Icon Tecnology Solutions, Inc. ("Icon") and the party ("Customer", "Client", "Member", "you". "your"), and applies to all services ("Services") ordered by Customer from Icon. BY COMPLETING THE SIGNUP PROCESS, YOU AGREE TO BE BOUND BY THE TERMS OF THIS AGREEMENT AND ALL TERMS AND CONDITIONS INCORPORATED BY REFERENCE. YOUR CONTINUED USE OF THE SERVICES CONSTITUTES ACCEPTANCE OF THIS AGREEMENT. Icon reserves the right to terminate this Agreement for any reason or no reason. Icon reserves the right to refuse service to anyone.

Service Usage Policy

Under this Agreement, Customer shall comply with Icon's then current Service Usage Policy, located on our website at http://www.iconsolution.net/managed/policies/usage.aspx.

Member Content

Member Content will include content uploaded to, submitted to, stored on or disseminated by Customer via the Services. Member Content also includes content of users of Customer's website and materials and content provided by third parties. Customer shall be solely responsible for the development, operation, and maintenance of Member Content.

Corrective Action

Icon may take corrective action with or without notice, including removal of all or a portion of the Member Content, disconnection or discontinuance of any and all Services, or termination of this Agreement in the event of notice of possible violation by Customer of this Agreement, violation of our Service Usage Policy, non-payment, or chargebacks. Customer agrees that Icon shall have no liability to Member due to any Corrective Action that Icon may take. Customer also agrees that Icon will not provide any refunds of any fees paid by Member prior to Corrective Action. In the event of Corrective Action against Spamming Activities and Internet Abuse, Icon will charge the customer a $500.00 clean up fee.

Policy Amendments and Modifications

Icon may amend or modify this Agreement or the Service Usage Policy at any time in its sole discretion. Customer shall be bound by any such modification. Icon may, but is under no obligation to, provide notice of any modification of this Agreement or the Service Usage Policy. Any modification is effective upon posting on Icon's website. If you continue to use the Services following effectiveness of the modification, your continued use will mean that you have accepted that modification.

Service Modifications

Icon reserves the right to amend its service offerings and add, delete, suspend, or modify the Services at any time, and to determine whether and when any such changes apply to both existing and future customers.

Term and Termination

Services will commence on the Effective Date indicated in the account activation order form ("Order Form") and continue for the duration of the term set forth in the Order Form ("Initial Term"). The Initial Term does not include any promotional periods that the Customer may qualify for at the time of the order. Thereafter, the Agreement will automatically renew for successive terms of equal length as the Initial Term or the most current term selected by Customer and indicated in their control panel ("Renewal Term"), unless the Agreement is terminated by either party. Either party may terminate this Agreement immediately upon the occurrence of any one or more of the following events: (i) the other party fails to pay when due any amounts required to be paid under this Agreement; (ii) the other party breaches any material term or provision of this Agreement and/or the Service Usage Policy; (iii) the other party becomes insolvent, makes an assignment for the benefit of its creditors, institutes or becomes subject to any proceeding under any bankruptcy or similar laws for the relief of debtors, or seeks the appointment of, or becomes subject to the appoint of, any trustee or receiver for all or any portion of such party's assets. Icon may terminate this Agreement, (i) if the Services are prohibited by applicable law, (ii) if the Services become impractical or unfeasible for any technical, legal, or regulatory reason, (iii) as part of Corrective Action, (iv) for any reason or no reason. If Icon terminates this Agreement or Customer cancels this Agreement prior to the end of the contract term and after the initial 30 days of service of Initial Term (during which the 30 Day Money Back Guarantee offer is active), Icon will not refund to Customer any Service Fees paid in advance of termination. Customer agrees that they are obligated to pay all Service Fees and charges accrued prior to the effective termination date.

Fraud Prevention

Icon may randomly select customers and require them to provide additional billing information, verify billing information, and/or fill out and fax Credit Card authorization forms to authenticate orders as part of Icon's fraud prevention program. Customers are required to comply with all fraud prevention program requests. Any unfulfilled requests may result in account suspension and/or account cancellation.

New Domain Name Registration

Under this Agreement, Customer has the option, through the Order Form or as part of an addon service activation or domain switch, to request Icon to register a new domain name on behalf of the Customer. Customer understands and acknowledges that Icon is not a Domain Registrar and that Icon will register new domain names through a Domain Registrar partner selected by Icon. Customer understands that the domain registration process requires Icon to pass Customer Information to the Domain Registrar partner and such information may become public information. Icon will not be responsible if a domain name is not available for any reason. Icon will not be responsible for any infringement of any thrid party rights caused by its domain registration on behalf of Customer. For such new domain name registration, Customer shall comply with the then current Domain Name Terms and Conditions posted at http://www.iconsolution.net/managed/policies/domain.aspx. Customer understands that Domain Name Registration fees are non-refundable. Customer understands that Icon will register the domain and lock the domain to protect customer against fraudulent domain transfer requests. This policy is in effect to protect the customer due to ICANN's relaxing of domain registrar transfer requirements, and not to deter customers from managing their domain.

Domain Name Transfers For Existing Domain Names

Under this Agreement, Customer has the option, through the Order Form or as part of an addon service activation or domain switch, to request Icon to provision a hosting account or setup an addon service with an existing Domain Name. Customer represents and warrants to Icon that they have the authority to manage said existing domain name. Customer understands that Icon will provide necessary information, including Icon DNS Server information, to the Customer to facilitate the domain name transfer process. However, the domain name transfer process is the sole responsibility of the Customer. Customer understands that such domain names are registered with or through third parties and the Customer must contact these third parties or use their web interfaces in order to transfer the domain name. Customer further understands that DNS updates are not instant and can take a few days for the new DNS information to propagate through the internet. The Customer is solely responsible for managing said exiting domain name, including making annual domain registration fee payments with the Domain Registrar or other domain name management company.

Domain Name Renewal For Domain Names Registered By Icon

In the interest of avoiding service interruption, Customer agrees that Icon will automatically renew such domain name annually and charge the Customer the annual domain name registration fee as posted in the then current Icon fee schedule, unless the Agreement is terminated by the Customer prior to the annual domain name renewal date. In the case when the account is terminated by Icon for non-payment, if the former Customer desires to continue domain ownership, then the former Customer is responsible to pay Icon for the domain registration fee as posted in the then current Icon fee schedule and a processing service charge. For this case, Icon requires a faxed completed authorization form and full payment to release the domain name. In the case of termination of this Agreement or termination of the auto-renewal service requested by the Customer, Icon's domain name management services will also terminate and the management of the domain name, including domain name renewals and transfers, is the sole responsibility of the Customer. In this case, the customer agrees that they are solely responsible for transferring their domain to another domain registrar of their choice. If the Agreement is terminated within 30 days prior to the domain expiration date, and Customer wishes to continue their domain ownership after termination of this Agreement, the Customer agrees to pay Icon the annual domain name registration fee as posted in the then current Icon fee schedule for an additional 1 year of domain ownership. Icon's domain name management services will also terminate and the management of the domain name, including future domain name renewals and transfers, is the sole responsibility of the Customer. Customer waives any claims it may have against Icon for, and hereby releases Icon of and from, any loss, damage, liability or expense arising out of, or relating to, the registration and renewal of such domain name in any online or offline network directories, membership lists or registration lists, or the release of the the domain name from such directories or lists following the termination of Services for any reason.

Fees, Taxes, and Payment

Services are provided on a pre-pay basis. Customer will pay to Icon the Service Fees in accordance with Icon's fee schedule as posted on the DiscountASP.NET website. All fees are fully earned when due and non-refundable when paid, unless within the first 30 days of Service (in which case, Icon's 30 day money back guarantee offer will be active). Service Fees for renewal periods after the Initial Term shall be due immediately upon the first day of renewal period. Customer agrees that Icon will charge Service Fees to the credit card supplied by Customer. All payments shall be made in US Currency. If any credit card is declined for any reason, Icon will charge the Customer an additional $1.00 service charge every time the card is declined. In the case of a chargeback, Icon will immediately suspend the site until the matter is resolved and Icon will bill Customer $50.00 per credit card chargeback received. If any invoice is not paid when due, Icon will impose an interest at the rate of one and one half percent (1.5%) per month or the maximum rate permitted by applicable law, whichever is less. If payment is not made ten (10) calendar days after payment is due, Icon will charge Customer a late fee of $15. In the event that any amount due Icon is not paid after twenty (20) calendar days after payment is due, Icon may immediately terminate this Agreement, or withhold or suspend Services, in its sole discretion. The Service Fees do not include any applicable sales, use, revenue, excise or other taxes imposed by any taxing authority with respect to the Services or any software provided hereunder. If applicable, all taxes will be paid by the Customer. Icon may, with 15 days notice to Customer, amend the Service Fee schedule.

Special Signup Promotions

Icon may from time to time, at its sole discretion, offer special limited time promotions for new account signups. Customer acknowledges that these promotions are a one time special and does not recur for subsequent renewals. Customer also acknowledges that any currently running promotions are not retroactive and do not apply to accounts that have been signed up previously at a time when the current promotion was not offered.

Special Offers Through Promotion Code

Icon may from time to time, at its sole discretion, offer special limited time offers for new account signups using a Promotion Code. These special offers are only available to new signups, if the Promotion Code is used during the initial online signup process and only during the time period when the Promotion Code is valid. Customer acknowledges that any promotions offered via Promotion Codes are not retroactive and do not apply to accounts that have been signed up previously at a time when the Promotion Code was not valid.

30 Day Money Back Guarantee

If Customer terminates this Agreement within 30 calendar days of Effective Date of the Order's Initial Term, they will receive a full refund of the monthly Service Fees. Setup Fees, New Domain Name Registration Fees, and bandwidth addon fees are not refundable. This Money Back Guarantee does not apply to the Renewal Term.

Additional Fees

Icon will charge a minimum of $15 for any technical work that requires system administrator time including but not limited to switching of primary hosted domain names, CSR regeneration (e.g., for trial SSL certificates), digital certificate installations, and file restoration from backups. Icon will charge a minimum of $15 processing/service fee for any services that require staff time including but not limited to services on the behalf of non-customers and domain name services for expired domain renewals.

Account Reactivation

There is a $30 charge to reactivate accounts that have been suspended or terminated. Icon in its sole discretion can decide to reactivate or not to reactivate a particular account.

Hardware and Software

Customers are responsible for and must provide all phones, phone and Internet connectivity services, computers, software, hardware, and other services necessary to access Icon servers and Services. Icon makes no representations, warranties, or assurances that customer's equipment will be compatible with Icon Services.

CPU Usage

Customer agrees that they will not use excessive amounts of CPU processing on any of Icon's servers. Any violation of this policy may result in corrective action by Icon, which may be taken in Icon's sole discretion with or without notice.

Bandwidth and Disk Space Usage

Customer agrees that they shall not exceed the allotted limits for monthly bandwidth and disk space as set forth during the Order or subsequent addon purchase of additional server resources. Icon monitors Customer server resource usage and has the right to take Corrective Action, if the Customer's server resource usage exceeds the agreed upon limits or adversely affects other customers. If Icon must take Corrective Action, Customer shall not be entitled to refunds of any paid Service Fees.

Customer Representations and Warranties

Customer represents and warrants to Icon that during the Term that Customer owns, is a valid licensee, or has the right to use the Member Content, including all text, graphics, and code, and the use, reproduction, distribution and transmission of the Member Content and any information and materials contained therein does not, and will not, (i) infringe any copyright, trademark, or any other proprietary right of a third party, (ii) violate any criminal laws and will only be used for lawful purposes, (iii) constitute false advertising, unfair competition, defamation, an invasion of privacy, violate a right of publicity or violate any other law or regulation, or (iv) contain and will at all times remain free of computer viruses, worms, trojan horses, and other malicious code.

Ecommerce Activities

If Customer is engaged in Ecommerce Activity, they are solely responsible for (i) the accuracy and appropriateness of the Member Content, (ii) ensuring that Member Content does not infringe or violate upon the rights of any third party or individual, (iii) ensuring that the Member Content, products and services are not illegal, (iv) accepting, processing, and fulfilling customer orders, (v) handling customer inquiries or complaints, (vi) payment of any and all taxes associated with its online store, and (vii) the security and privacy of any customer information that Customer may receive as a result of Ecommerce Activity.

Government Regulations

Customer may not export, re-export, transfer or make available, whether directly or indirectly, any regulated items or information to anyone outside the United States in connection with this Agreement without first complying with all export control laws and regulations which may be imposed by the United States government and any country or organization of nations within whose jurisdiction Customer operates or does business.

License to Icon

Customer grants Icon the royalty-free, non-exclusive, worldwide right and license to reproduce, copy, use and distribute Member Content and to make archival or backup copies of the Member Content solely to provide and operate the Services. Icon acknowledges that they are not acquiring any right, title or interest in or to the Member Content, all of which shall remain solely with the Customer.

Icon Intellectual Property

Icon grants to Customer a non-exclusive, non-transferable, royalty-free license, exercisable solely during the term of this Agreement, to use applicable Icon Technology solely for the purpose of accessing and using the Services. Customer may not use the Icon Technology for any purpose other than accessing and using the Services. Except for the rights expressly granted herein, this Agreement does not transfer from Icon to Customer any Icon Technology, and all rights, titles and interests in and to the Icon Technology shall remain solely with Icon. Customer shall not, directly or indirectly, reverse engineer, decompile, disassemble, or otherwise attempt to derive source code or other trade secrets from any of the Icon Technology. Icon's trademarks, tradenames, service marks, logos, other names and marks, and related product and service names, design marks and slogans are the sole and exclusive property of Icon. Customer may not use any of the foregoing in any advertising, publicity or in any other commercial manner without the prior written consent of Icon. Icon will maintain and control ownership of all Internet protocol numbers and addresses that may be assigned by Icon to Customer. Icon may, in its sole discretion, change or remove any and all such Internet Protocol numbers and addresses. Any feedback, data, answers, questions, comments, suggestions, idea or the like which Customer sends to Icon relating to the Services will be treated as being non-confidential and non-proprietary. Icon may use, disclose or publish any ideas, concepts, know-how or techniques contained in such information for any purpose whatsoever.

Disclaimer of Warranty

Customer agrees to use all Services and any information obtained through or from Icon, at Customer's own risk. Customer acknowledges and agrees that Icon exercises no control over, and accepts no responsibility for, the content of the information passing through Icon's host computers, network, or the Internet. THE SERVICES ARE PROVIDED ON AN "AS IS, AS AVAILABLE" BASIS. NONE OF Icon, ITS PARENT, SUBSIDIARY OR AFFILIATED CORPORATIONS, OR ANY OF THEIR RESPECTIVE EMPLOYEES, OFFICERS, DIRECTORS, SHAREHOLDERS, AFFILIATES, AGENTS, SUPPLIERS, THIRD-PARTY INFORMATION PROVIDERS, LICENSORS OR THE LIKE ("Icon PERSON") MAKE ANY WARRANTIES OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, FOR THE SERVICES OR ANY EQUIPMENT Icon PROVIDES. NO Icon PERSON MAKES ANY WARRANTIES THAT THE SERVICES WILL NOT BE INTERRUPTED OR ERROR FREE; NOR DO THEY MAKE ANY WARRANTIES AS TO THE RESULTS THAT MAY BE OBTAINED FROM THE USE OF THE SERVICES OR AS TO THE ACCURACY, RELIABILITY OR CONTENT OF ANY INFORMATION, SERVICES OR MERCHANDISE CONTAINED IN OR PROVIDED THROUGH THE SERVICES. Icon IS NOT LIABLE, AND EXPRESSLY DISCLAIMS ANY LIABILITY, FOR THE CONTENT OF ANY DATA TRANSFERRED EITHER TO OR FROM CUSTOMER OR STORED BY CUSTOMER OR ANY OF CUSTOMER'S USERS VIA THE SERVICES PROVIDED BY Icon. NO ADVICE OR WRITTEN INFORMATION GIVEN BY ANY Icon PERSON, WILL CREATE A WARRANTY; NOR MAY YOU RELY ON ANY SUCH INFORMATION OR ADVICE. The terms of this section shall survive any termination of this Agreement.

Indemnification

Customer agrees to indemnify, defend and hold harmless Icon and its parent, subsidiary and affiliated companies, and each of their respective officers, directors, employees, shareholders and agents ("Indemnified Parties") from and against any and all claims, damages, losses, liabilities, suits, actions, demands, proceedings, and expenses (including attorney fees) threatened, asserted, or filed by a third party against any of the Indemnified Parties arising out of or relating to (i) Customer's use of the Services, (ii) any violation by Customer of the Service Usage Policy, (iii) any breach of any representation, warranty, or covenant of Customer contained in this Agreement, or (iv) any acts or omissions of Customer. The terms of this section shall survive any termination of this Agreement.

Limitation of Liability

Customer agrees that no Icon Person, under any circumstances, shall be held responsible or liable for situations where the Services are accessed by third parties through illegal or illicit means, including situations where such data is accessed through the exploitation of security gaps, weaknesses or flaws (whether known or unknown to Icon at the time) which may exist in the Services or Icon's equipment used to provide the Services. Under no circumstances, including negligence, shall any Icon Person be liable for any indirect, incidental, special, consequential or punitive damages, or loss of profits, revenue, data or use by Customer, any of its users, or any other third party, whether in an action in contract or tort or strict liability or other legal theory, even if Icon has been advised of the possibility of such damages. No Icon Person shall be liable to Customer, any of its users, or any other third party, for any loss or damages that result or are alleged to have resulted from the use of or inability to use the Services, or that results from mistakes, omissions, interruptions, deletion of files, loss of data, errors, viruses, defects, delays in operations, or transmission or any failure of performance, whether or not limited to acts of God, communications failure, theft, destruction or unauthorized access to Icon's records, programs, equipment, or services. IN NO EVENT WILL Icon'S LIABILITY IN CONNECTION WITH THE SERVICES, ANY SOFTWARE PROVIDED HEREUNDER OR ANY ORDER, WHETHER CAUSED BY FAILURE TO DELIVER, NON-PERFORMANCE, DEFECTS, BREACH OF WARRANTY OR OTHERWISE, EXCEED THE AGGREGATE ACTUAL SERVICE FEES PAID TO Icon BY CUSTOMER DURING THE 12 MONTH PERIOD IMMEDIATELY PRECEDING THE EVENT GIVING RISE TO SUCH LIABILITY. Icon CANNOT GUARANTEE CONTINUOUS SERVICE, SERVICE AT ANY PARTICULAR TIME, INTEGRITY OF DATA, INFORMATION OR CONTENT STORED OR TRANSMITTED VIA THE INTERNET. Icon WILL NOT BE LIABLE FOR ANY UNAUTHORIZED ACCESS TO, OR ANY CORRUPTION, ERASURE, THEFT, DESTRUCTION, ALTERATION OR INADVERTENT DISCLOSURE OF, DATA, INFORMATION OR CONTENT TRANSMITTED, RECEIVED OR STORED ON ITS SYSTEM. Customer understands, acknowledges and agrees that if Icon takes any corrective action under this Agreement because of an action of Customer or its website users, Customer agrees that Icon shall have no liability to Customer due to such corrective action by Icon. The terms of this section shall survive any termination of this Agreement.

Force Majeure

Neither party is liable for any default or delay in the performance of any of its obligations under this Agreement (other than failure to make payments when due) if such default or delay is caused, directly or indirectly, by forces beyond such party's reasonable control, including, without limitation, fire, flood, acts of God, labor disputes, accidents, acts of war or terrorism, acts of government or other legal order, interruptions of transportation or communications, supply shortages or the failure of any third party to perform any commitment relative to the production or delivery of any equipment or material required for such party to perform its obligations hereunder.

Governing Law, Jurisdiction, and Arbitration

This Agreement shall be governed in all respects by Ohio law without regard to the conflict of law provisions thereof. Both parties submit to personal jurisdiction in Ohio. Any controversy or claim arising out of, relating to or in connection with this Agreement, or the breach thereof, shall be subject to arbitration administered by the American Arbitration Association ("AAA") in accordance with its then existing Commercial Arbitration Rules ("AAA Rules") and judgment upon the award rendered by the arbitrator may be entered in any court having jurisdiction thereof. The place of arbitration shall be Cleveland, Ohio, or any other place selected by mutual agreement of the parties. An award rendered in connection with an arbitration pursuant to this Section shall be final and binding upon the parties and the parties agree and consent that the arbitral award shall be conclusive proof of the validity of the determinations of the arbitrations set forth in the award, and any judgment upon such an award may be entered and enforced in any court of competent jurisdiction. The parties agree that the award of the arbitral tribunal will be the sole and exclusive remedy between them regarding any and all claims and counterclaims between them with respect to the subject matter of the arbitrated dispute. The parties hereby waive all in personam jurisdictional defenses in connection with any arbitration hereunder or the enforcement of an order or award rendered pursuant thereto. In any legal action, the prevailing party will be entitled to recover all legal expenses incurred in connection with the action, including but not limited to its costs and reasonable attorney's fees. The terms of this section shall survive any termination of this Agreement.

Independent Contractor

Icon and Customer are independent contractors and nothing contained in the Agreement places Icon and Customer in the relationship of principal and agent, partner or joint venturers. Neither party has, expressly or by implication, or may represent itself as having, any authority to make contracts or enter into any agreements in the name of the other party.

Assignment and Successors

Customer may not assign or transfer this Agreement, or any of its rights or obligations hereunder, without the prior written consent of Icon. Any attempted assignment in violation of the foregoing provision shall be null and void and of no force or effect whatsoever. Icon may assign its rights and obligations under this Agreement, and may engage subcontractors or agents in performing its duties and exercising its rights hereunder, without the consent of Customer. This Agreement shall be binding upon and shall inure to the benefit of the parties hereto and their respective successors and permitted assigns.

Entire Agreement and Severability

This Agreement represents the entire agreement between the parties, and supercedes all previous agreements. All rights and restrictions contained in the Agreement may be exercised and shall be applicable and binding only to the extent that they do not violate any applicable laws and are intended to be limited to the extent necessary so that they will not render this Agreement illegal, invalid or unenforceable. If any provision or portion of any provision of this Agreement shall be held to be illegal, invalid or unenforceable by a court of competent jurisdiction, it is the intention of the parties that the remaining provisions or portions thereof shall constitute their agreement with respect to the subject matter hereof, and all such remaining provisions or portions thereof shall remain in full force and effect. Customer hereby represents that they are either, an individual entering this Agreement for their personal use and is of legal age to execute this Agreement, or a corporation, limited partnership or other legal entity, validly existing under the laws of the state of its organization and the person acting on behalf of Customer is authorized to execute this Agreement on behalf of Customer.