Sunday, March 30, 2008

Programming Webservices using WSDL (Without WebReference)

WSDL stands for Web Service Description Language, a standard by which a web service can tell clients what messages it accepts and which results it will return. WSDL contains every details regarding using web service
  1. Method and Properties provided by web service
  2. URLs from which those method can be accessed.
  3. Data Types used.
  4. Communication Protocol used.
This post will help you to program with WSDL without using webservice reference. In brief following are the steps you need to take.

Create the proxy class using the tool WSDL.exe* (this can be accessed using Visual Studio.NET command prompt).

Following is the syntax of the wsdl.exe command you can use to generate the proxy class.
wsdl.exe  <options><url><url>...


for e.g: wsdl myservice.wsdl -language:cs

Based on the schema of myservice.wsdl this Utility will generate the proxy class myservice.cs in c# in the current directory. You can use lots of other options also, you can find the options by using the command wsdl /? in command prompt.

If you want, you can also generate the VB class file by using the command wsdl myservice.wsdl -language:vb

You can create a project or use the existing project now and add the class in your project, thats it :) now you are ready to create the instance of the class, call methods, etc.

I hope this is helpful, if you need more detail please leave a comment, I will try to answer.

Also if you are very new to webservice you can browse this site,
I found this very helpful for beginners : All About Web Service in .Net

And some of the good sites which can give you more indepth knowledge.

Creating and Consuming .NET Web Services in Five Easy Steps

Creating a .NET Web Service - By Chris Peiris

Programming .NET Web Services -O'Reilly

*WSDL.exe is the utility to generate code for xml web service clients and xml webservices using ASP.NET from WSDL contract files, XSD schemas and .discomap discovery documents. This tool can be used in conjunction with disco.exe.

Saturday, March 15, 2008

Multidimensional arrays in Javascript

Javascript has no inbuilt support for multidimensional arrays, however the language is flexible enough that you can emulate this behaviour easily by populating your arrays with separate arrays, creating a multi-level structure.

You can create an array in Javascript simply by doing any of the following:

var array1 = new Array(5);

var array2 = [1,2,3,4,5];

var array3 = new Array();

var array4 = [];





If you know the size of your array in advance, but not the contents, the first form is better since it allocates the right amount of memory, but doesn't fill it. If you need to populate the array from the beginning, you can just specify the contents when you declare it. The second array has the same contents as if we wrote:

var array2 = new Array(5);

array2[0] = 1; //remember that arrays count from zero

array2[1] = 2;

array2[2] = 3;

array2[3] = 4;

array2[4] = 5;





Lastly, if you want to identify a variable as an array, but don't know how big it is, you can use either of the last two forms.


Retrieving elements from an array has the same syntax as entering them. In the following code, we display two alerts, once before and once after we change the array -- we should see the number 5, followed by the number 10:


var array = [5];

alert(array[0]);

array[0] = 10;

alert(array[0]);

That's more or less all you need to know about single dimensional arrays. When you need extra dimensions, things get slightly more complicated.


Multidimensional Arrays


If you've got a two dimensional array, for example you need to keep track of the contents of a table, then what you really want to do is index them like array[2,3]. There's no support for arrays of this kind, but we can take advantage of the fact that arrays can contain any value -- including other arrays -- to fake it.


In the following example we create a 3x3 array:

var array = new Array(3);

for (var i = 0; i < 3; i++) {

array[i] = [' ', ' ', ' '];

}

array[0][2] = 'x';

array[1][1] = 'x';

array[2][0] = 'x';
We set three cells to be equal to "x", meaning that our array now contains:



You can create arrays of any depth by adding more array references for each successive dimension you need. For example, to modify the above example to create a 3x3x3 cube, we'd simply write:

var array = new Array(3);

for (var i = 0; i < 3; i++) {

array[i] = new Array(3);

for (var j = 0; j < 3; j++) {

array[i][j] = [' ', ' ', ' '];

}

}

Multidimensional arrays are useful tools in circumstances where you have to populate the entire space with information. If your data is more sparse -- meaning most of the cells are empty -- then you're better off using associative arrays (hashes or dictionaries in other languages).

Wednesday, March 12, 2008

Migrating ASP.NET Site from IIS 6.0 to IIS 7.0

1. Remove the built-in Membership, Role and Profile providers

If you are configuring your own Membership, Role or Profile providers with your own database connection string, make sure you remove the built-in ones or you may get an exception about not being able to connect to "LocalSqlServer". Which is the connection string used in machine.config for the stock providers. This did not happen under IIS6. So it turns out the bolded lines become very important under IIS7.

<membership defaultProvider="MembershipSqlProvider"...>
<providers>
<remove name="AspNetSqlMembershipProvider"/>
<add name="MembershipSqlProvider"
:
connectionStringName="MyDatabaseConnection"/>
</providers>
</membership>

<roleManager defaultProvider="RoleManagerSqlProvider"...>
<providers>
<remove name="AspNetSqlRoleProvider"/>
<add name="RoleManagerSqlProvider"
:
connectionStringName="MyDatabaseConnection"/>
</providers>
</roleManager>

<profile defaultProvider="SqlProfileProvider">
<providers>
<remove name="AspNetSqlProfileProvider"/>
<add name="SqlProfileProvider"
:
connectionStringName="MyDatabaseConnection"/>
</providers>
</profile>

2. Move your Modules and Handlers to the <system.webServer> section

This one took me a while to figure out, but it shouldn't have. I had a custom module that was redirecting to secure pages when necessary, and it was not firing under IIS7. So I instrumented it up with log statements, and still nothing. A quick search turned up Rick Strahl's post on this.

<configuration>

<system.web>
<httpModules>
MODULES DON'T GO HERE ANYMORE
</httpModules>
<httpHandlers>
HANDLERS DON'T GO HERE ANYMORE
</httpHandlers>
</system.web>

<system.webServer>
<modules>
FOR IIS7, MODULES GO HERE NOW
</modules>
<handlers>
FOR IIS7 HANDLERS GO HERE NOW
</handlers>
</system.webServer>

<configuration>

Monday, March 10, 2008

CSS Expression Optimization

 

CSS Expressions

CSS expressions were introduced in Internet Explorer 5.0 and it allows you to to assign a JavaScript expression to a CSS property. For example, this allows you to set the position of an element according to the browser size.

#myDiv {
   position:   absolute;
   width:      100px;
   height:     100px;
   left:       expression(document.body.offsetWidth  - 110 + "px");
   top:        expression(document.body.offsetHeight - 110 + "px");
   background: red;
}

Not the best way to achieve this but it is easy enough to understand.

Dynamic Expressions

Not only does CSS expressions allow you to calculate the CSS value inside the style declarations, it also recalculates the expression so that property value is always correct. This means that the expression needs to be recalculated every time the document.body.offsetWidth is changed. If this was the case dynamic expressions would actually be a lot more useful. This isn't the case and recalculations of the expressions happens every time a JS execution thread is finished. This means that if you move your mouse and have a listener to onmousemove all the dynamic expressions are recalculated. This does not require you to be a genious to figure out that this can bring the simplest web application to a crawl.

Take a look at the following CSS block:

#myDiv {
   border:  10px solid Red;
   width:   expression(ieBox ? "100px" : "80px");
}

Asuming ieBox is a constant flag which is true when IE is in quirks mode, the expression will at all times result in "80px" (or "100px"). Even though the expression is constant it will be recalculated a lot of times. The question is how to remove these extra calculations for constant expressions.

Constant Expressions

The thing to do is to go through all the style sheet declarations and replace the constant expressions with a constant value. In the previous example, assuming we are using IE6 in standard mode, we want:

#myDiv {
   border:  10px solid Red;
   width:   80px;
}

So, how do we find out if an expression is constant. The easiest way is to mark the expression so that it can be easily found. The solution we are going to use is to enclose the expression in a function that we know the name of and is equal to the identity function.

function constExpression(x) {
   return x;
}

And then in the CSS block we use:

#myDiv {
   border:  10px solid Red;
   width:   expression(constExpression(ieBox ? "100px" : "80px"));
}

Usage

The first thing you need to do is to include the cssexpr.js file. This should be done before any usage of constExpression.

<script type="text/javascript" src="cssexpr.js"></script>

After this you can use constExpression in any style block or any file included using a link element or using the @import directive in a these. Notice that style attributes are not checked due to performance reasons.

Implementation

The idea here is to go through all style sheets and then go through all rules and finally go through all the cssText. To do this we first go through the document.styleSheets collection.

function simplifyCSSExpression() {
   try {
      var ss,sl, rs, rl;
      ss = document.styleSheets;
      sl = ss.length

      for (var i = 0; i < sl; i++) {
         simplifyCSSBlock(ss[i]);
      }
   }
   catch (exc) {
      alert("Got an error while processing css. The page " +
            "should still work but might be a bit slower");
      throw exc;
   }
}

In the style sheet we go thorugh the imports collection and then the rules collection. We also check that the cssText contains "expression(constExpression(" so that we do not process the style sheet in vain.

function simplifyCSSBlock(ss) {
   var rs, rl;

   // Go through imports
   for (var i = 0; i < ss.imports.length; i++)
      simplifyCSSBlock(ss.imports[i]);

   // if no constExpression we don't have to continue
   if (ss.cssText.indexOf("expression(constExpression(") == -1)
      return;

   rs = ss.rules;
   rl = rs.length;
   for (var j = 0; j < rl; j++)
      simplifyCSSRule(rs[j]);
}

Now we go through the cssText of each rule and update the text, using a function named simplifyCSSRuleHelper, until the text does not change any more.

function simplifyCSSRule(r) {
   var str = r.style.cssText;
   var str2 = str;
   var lastStr;

   // update string until the updates does not change the string
   do {
      lastStr = str2;
      str2 = simplifyCSSRuleHelper(lastStr);
   } while (str2 != lastStr)

   if (str2 != str)
      r.style.cssText = str2;
}

The helper function just finds the first expression and evaluates that and replaces the expression with the value.

function simplifyCSSRuleHelper(str) {
   var i, i2;
   i = str.indexOf("expression(constExpression(");
   if (i == -1) return str;
   i2 = str.indexOf("))", i);
   var hd = str.substring(0, i);
   var tl = str.substring(i2 + 2);
   var exp = str.substring(i + 27, i2);
   var val = eval(exp)
   return hd + val + tl;
}

Finally we need to call the function simplifyCSSExpression and this is done once the page is loaded.

if (/msie/i.test(navigator.userAgent) && window.attachEvent != null) {
   window.attachEvent("onload", function () {
      simplifyCSSExpression();
   });
}
 

Download

Author: Erik Arvidsson

Thursday, March 6, 2008

Crystal Report 8.5 and SubReports (Reimport problems)

If you have a linked sub report in Main Crystal Report, every time you open the main report, it re imports the sub report if it founds the sub report in the same location. This is despite the fact that Re-import Subreports when Opening Reports check box is unchecked.

This seems to me a bug. Similar bug in Crystal 10 has been reported on businessobject support web site.

Clearing the 'Re-import Subreport on Open' check box does not work (c2017466)

This creates a annoying behavior, as Crystal report will remove the links between main report and sub report. Only workaround I have found is to rename the sub reports or move them to other folders, once they are imported in main report. If Crystal Report does not find the sub report in the original location, it does not re import the sub report.

I faced this issue when I changed the database driver of subreport and deployed in QA environment, still all my main report was referring to same old database driver for my subreport, after lots of investigation I discovered that I will have to reimport the subreport into all these 25 reports and redeploy all the report all over again, this is very painful and time consuming. If any body encounter similar problem and has better solution then please do let me know by posting in comments section.

Wednesday, March 5, 2008

Difference between NVARCHAR and VARCHAR in SQL Server

The broad range of data types in SQL Server can sometimes throw people through a loop, especially when the data types seem to be highly interchangeable. Two in particular that constantly spark questions are VARCHAR and NVARCHAR: what's the difference between the two, and how important is the difference?

VARCHAR is an abbreviation for variable-length character string. It's a string of text characters that can be as large as the page size for the database table holding the column in question. The size for a table page is 8,196 bytes, and no one row in a table can be more than 8,060 characters. This in turn limits the maximum size of a VARCHAR to 8,000 bytes.

The "N" in NVARCHAR means uNicode. Essentially, NVARCHAR is nothing more than a VARCHAR that supports two-byte characters. The most common use for this sort of thing is to store character data that is a mixture of English and non-English symbols — in my case, English and Japanese.

The key difference between the two data types is how they're stored. VARCHAR is stored as regular 8-bit data. But NVARCHAR strings are stored in the database as UTF-16 — 16 bits or two bytes per character, all the time — and converted to whatever codepage is being used by the database connection on output (typically UTF-8). That said, NVARCHAR strings have the same length restrictions as their VARCHAR cousins — 8,000 bytes. However, since NVARCHARs use two bytes for each character, that means a given NVARCHAR can only hold 4,000 characters (not bytes) maximum. So, the amount of storage needed for NVARCHAR entities is going to be twice whatever you'd allocate for a plain old VARCHAR.

Because of this, some people may not want to use NVARCHAR universally, and may want to fall back on VARCHAR — which takes up less space per row — whenever possible.

Here's an example of how to mix and match the use of the two types. Let's say we have a community website where people log in with a username, but can also set a public "friendly" name to be more easily identified by other users. The login name can be a VARCHAR, which means it must be 8-bit ASCII (and it can be constrained further to conventional alphanumerics with a little more work, typically on the front end). The friendly name can be an NVARCHAR to allow Unicode entities. This way you're allowing support for Unicode, but only in the place where it matters most — both for the users, and where the extra storage space is going to be put to the best possible use.

VARCHAR and NVARCHAR in SQL Server 2005

One fairly major change to both VARCHAR and NVARCHAR in SQL Server 2005 is the creation of the VARCHAR(MAX) and NVARCHAR(MAX) data types. If you create a VARCHAR(MAX) column, it can hold up to 2^31 bytes of data, or 2,147,483,648 characters; NVARCHAR(MAX) can hold 2^30 bytes, or 1,073,741,823 characters.

These new data types are essentially replacements for the Large Object or LOB data types such as TEXT and NTEXT, which have a lot of restrictions. They can't be passed as variables in a stored procedure, for instance. The (MAX) types don't have those restrictions; they just work like very large string types. Consequently, if you're in the process of re-engineering an existing data design for SQL Server 2005, it might make sense to migrate some (although not all!) TEXT / NTEXT fields to VARCHAR(MAX) / NVARCHAR(MAX) types when appropriate.

The big difference between VARCHAR and NVARCHAR is a matter of need. If you need Unicode support for a given data type, either now or soon enough, go with NVARCHAR. If you're sticking with 8-bit data for design or storage reasons, go with VARCHAR. Note that you can always migrate from VARCHAR to NVARCHAR at the cost of some room -- but you can't go the other way 'round. Also, because NVARCHAR involves fetching that much more data, it may prove to be slower depending on how many table pages must be retrieved for any given operation.

Tuesday, March 4, 2008

SQL SERVER - Import CSV File Into SQL Server Using Bulk Insert - Load Comma Delimited File Into SQL Server

This is very common request recently - How to import CSV file into SQL Server? How to load CSV file into SQL Server Database Table? How to load comma delimited file into SQL Server? Let us see the solution in quick steps.

CSV stands for Comma Separated Values, sometimes also called Comma Delimited Values.

Create TestTable

USE TestData GO CREATE TABLE CSVTest (ID INT, FirstName VARCHAR(40), LastName VARCHAR(40), BirthDate SMALLDATETIME) GO

Create CSV file in drive C: with name csvtest.txt with following content. The location of the file is C:csvtest.txt

1,James,Smith,19750101 2,Meggie,Smith,19790122 3,Robert,Smith,20071101 4,Alex,Smith,20040202

Now run following script to load all the data from CSV to database table. If there is any error in any row it will be not inserted but other rows will be inserted.

BULK INSERT CSVTest FROM 'c:csvtest.txt' WITH ( FIELDTERMINATOR = ',', ROWTERMINATOR = 'n' ) GO

Check the content of the table.

SELECT * FROM CSVTest GO

Drop the table to clean up database.

DROP TABLE CSVTest GO

Reference : Pinal Dave (http://www.SQLAuthority.com)

SQL Query Analyzer Keyboard Shortcuts

This table displays the keyboard shortcuts available in SQL Query Analyzer.

Activity Shortcut
Bookmarks: Clear all bookmarks. CTRL-SHIFT-F2
Bookmarks: Insert or remove a bookmark (toggle). CTRL+F2
Bookmarks: Move to next bookmark. F2
Bookmarks: Move to previous bookmark. SHIFT+F2
Cancel a query. ALT+BREAK
Connections: Connect. CTRL+O
Connections: Disconnect. CTRL+F4
Connections: Disconnect and close child window. CTRL+F4
Database object information. ALT+F1
Editing: Clear the active Editor pane. CTRL+SHIFT+DEL
Editing: Comment out code. CTRL+SHIFT+C
Editing: Copy. You can also use CTRL+INSERT. CTRL+C
Editing: Cut. You can also use SHIFT+DEL. CTRL+X
Editing: Decrease indent. SHIFT+TAB
Editing: Delete through the end of a line in the Editor pane. CTRL+DEL
Editing: Find. CTRL+F
Editing: Go to a line number. CTRL+G
Editing: Increase indent. TAB
Editing: Make selection lowercase. CTRL+SHIFT+L
Editing: Make selection uppercase. CTRL+SHIFT+U
Editing: Paste. You can also use SHIFT+INSERT. CTRL+V
Editing: Remove comments. CTRL+SHIFT+R
Editing: Repeat last search or find next. F3
Editing: Replace. CTRL+H
Editing: Select all. CTRL+A
Editing: Undo. CTRL+Z
Execute a query. You can also use CTRL+E (for backward compatibility). F5
Help for SQL Query Analyzer. F1
Help for the selected Transact-SQL statement. SHIFT+F1
Navigation: Switch between query and result panes. F6
Navigation: Switch panes. Shift+F6
Navigation: Window Selector. CTRL+W
New Query window. CTRL+N
Object Browser (show/hide). F8
Object Search. F4
Parse the query and check syntax. CTRL+F5
Print. CTRL+P
Results: Display results in grid format. CTRL+D
Results: Display results in text format. CTRL+T
Results: Move the splitter. CTRL+B
Results: Save results to file. CTRL+SHIFT+F
Results: Show Results pane (toggle). CTRL+R
Save. CTRL+S
Templates: Insert a template. CTRL+SHIFT+INSERT
Templates: Replace template parameters. CTRL+SHIFT+M
Tuning: Display estimated execution plan. CTRL+L
Tuning: Display execution plan (toggle ON/OFF). CTRL+K
Tuning: Index Tuning Wizard. CTRL+I
Tuning: Show client statistics CTRL+SHIFT+S
Tuning: Show server trace. CTRL+SHIFT+T
Use database. CTRL+U

Source MSDN