Friday, June 20, 2008

How to have a HTML FORM as part of EMail?

Today I came across a very interesting scenario wherein we have to send a survey form as a part of email. I mean email itself shall contain the complete HTML (including form tag) where in user is going to provide the information and submit the same.

The sample HTML survey form in email shall look like



Ideally we can send an email to user and include just the URL of the survey page instead of the complete HTML as a part of the mail itself. But in many cases such as surveys, feedbacks the willingness of clicking on URL and opening it in browser and then submitting the same is less.

Whereas if we provide the same HTML Form as a part of email itself then the probability of filling and submitting these kinds of surveys/ feedbacks is more.

Generally whenever I wanted to send any formatted HTML in mail I used to design with my favorite designer/editor and then browse the HTML in any browser and then copy from browser and paste in the new mail window of outlook.

This time also I did the same and see what; my usual method is failed when I pasted the formatted HTML from browser to outlook. Surprisingly outlook removed only the FROM tag from my all HTML content. And hence the user will not able to submit the survey to any website.

This time it replace FROM tag as just simple text as below


I tried all possible things but no luck. Then I thought if somehow I put this FORM tag as part of mail body then it might work. So started generating the complete mail programmatically including FORM tag and send it to the user, and there we are, we got the solution. Now user can fill and submit the form from email itself.

Here I did very simple string formation using C#

And then finally set this as mail body and send the mail.


But before using this solution I want to highlight few things

  • It’s not good idea to have forms as part the mail itself, but if situation demands here is the solution.

  • If you want to do any script validation (JavaScript), then by default in outlook it’s disabled as a result none of the JavaScript will be fired.

  • I tried submitting from Outlook 2007 it didn't work, probably there might be some security constraint.

  • If the generated mail is forwarded then the recipient of the mail cannot submit the form as outlook would remove the FORM tag.

Hope this information helps you.In case if you find any information here is wrong please feel free to write to me Bharat.Mane@gmail.com

Thank You

Bharat Mane

Monday, May 19, 2008

MS SQL Server 2005 - Linked Servers One Has to Know

A linked server is a fantastic feature provided by Microsoft with Microsoft SQL Server to talk to a remote Microsoft SQL Server. This can be set up using the SQL Enterprise Manager interface or by using the sp_addlinkedserver stored procedure.
You can find the detailed information at
http://msdn2.microsoft.com/en-us/library/ms188279.aspx
http://msdn2.microsoft.com/en-us/library/ms188477.aspx

Now let’s talk about the some of the things that I learned about Linked Servers;
In one of my projects we have many interrelated application running on MS SQL 2005 server. And for various reasons these servers share lot of information among themselves by using [Database Name].[Schema Name].[Object Name]. These application are running fine for last couple of years but since the load contributed by these various application is increasing day-by-day, so we decided to have one more MS SQL Sever and move few databases from present one to new one. But there were hundreds of stored procedures, triggers, views, and function using the database objects as [Database Name].[Schema Name].[Object Name]. So, for us it was a big challenge to separate them without disturbing their coupling.

This is where we thought using linked servers and wherever we are using [Database Name].[Schema Name].[Object Name] we decided to use [Server Name].[Database Name].[Schema Name].[Object Name]

But hang on techies, though it looks simple and straight forward which actually it is, there is a hidden cost which you have to pay if your application is falling in one of the following scenarios
  • Using remote server objects in transaction,
  • Using remote views which reference multiple tables
  • Using remote server objects in cursors
  • Using Identity output variables which references remote server objects ,
  • And last but not the least if you miss MSDTC settings;

Thanks to Microsoft support techies and Google who gave me whole lot of information on handling these issues.
Before you get into debugging any issues, use this DTSPING utility to check whether your both the DB servers are communicating properly.
http://blogs.msdn.com/florinlazar/archive/2005/09/16/469064.aspx

Then probably have a look at this article on How to troubleshoot error 7391 that occurs when you use a linked server in SQL Server
http://support.microsoft.com/kb/306212

Then if you face any errors listed below, I have few pointer to MS KB.

  • Server: Msg 7391, Level 16, State 1, Line 1The operation could not be performed because OLE DB provider "%ls" for linked server "%ls" was unable to begin a distributed transaction.
  • Distributed transaction aborted by MSDTC.
Resolution
http://support.microsoft.com/kb/306212

  • Server: Msg 8180, Level 16, State 1, Line 2 Statement(s) could not be prepared.

Resolution
Many places we use cursors and in sometimes in the cursors we use linked server objects/remote objects in those cases you might get this kind of error.
To resolve this you may follow the methods specified by Microsoft. Or even you can use while loop instead of cursor (Please note that it may not remove your problem in all cases)
http://support.microsoft.com/kb/826860

  • Msg 1206, Level 18, State 167, Line 3 The Microsoft Distributed Transaction Coordinator (MS DTC) has cancelled the distributed transaction.

You use the SQL Native Client OLE DB provider (SQLNCLI) in SQL Server 2005 to create a linked server. You create a distributed transaction. The distributed transaction contains a query that uses the linked server to retrieve data from a table. When you commit the distributed transaction, you may receive the following error message
The Microsoft Distributed Transaction Coordinator (MS DTC) has cancelled the distributed transaction.
Sometimes
Distributed transaction completed. Either enlist this session in a new transaction or the NULL transaction.

Resolution
http://support.microsoft.com/kb/937517

  • Server: Msg 16955, Level 16, State 2, Line 0Could not create an acceptable cursor.
  • Server: Msg 16945, Level 16, State 1, Procedure sp_cursoropen, Line 57The cursor was not declared.

Resolution
http://support.microsoft.com/kb/302477

  • You have two instances of Microsoft SQL Server 2005 that are named Instance1 and Instance2.
  • In Instance1, you have a table that has the following characteristics:
    § The table has a column of the VARCHAR data type.
    § The table has no clustered index.
    § The column of the VARCHAR data type is not indexed.
    § The table has many rows. For example, the table has 100,000 or more rows.
  • In Instance2, you perform the following operations:
    § You create a linked server to Instance1.
    § You run an UPDATE statement against the linked server to update the column of the VARCHAR data type in the table in Instance1.
    In this scenario, the update operation may be performed on incorrect rows

Resolution
http://support.microsoft.com/?id=951185

  • In your application if you create a linked server that is linked to the local server itself. This configuration is also known as a loopback linked server. Then, you create a stored procedure that contains a statement that resembles the following statement:
    o INSERT EXEC .
    You will receive an error message as
    Msg 3910, Level 16, State 2, Line 1 Transaction context in use by another session.

Resolution
http://support.microsoft.com/?id=947486

  • In Microsoft SQL Server 2005, you run a transaction from a remote server by using a linked server. The transaction contains a DML statement that is followed by a data definition language (DDL) statement. For example, the transaction contains an INSERT statement that is followed by a DROP TABLE statement. In this scenario, you receive the following error message when you run the transaction:
    Server: Msg 3970, Level 16, State 2, Line 1 This operation conflicts with another pending operation on this transaction. The operation failed.

Resolution
http://support.microsoft.com/kb/949687

  • In some scenarios the errors disappeared by enabling network Distributed Transaction Coordinator access
    This article describes the procedure that you follow to enable network Distributed Transaction Coordinator (DTC) access in Microsoft Windows Server 2003.
    http://support.microsoft.com/kb/817064

Apart from all the above here are few more related articles.

Hope this information helps you.
In case if you find any information here is wrong please feel free to write to me Bharat.Mane@gmail.com
Thank You
Bharat Mane

Thursday, May 1, 2008

ASP.NET Using MaxLength, One has to know.

One of the basic validations that we do in our day-to-day programming is checking the length of the data. In web application, in ASP.NET we have a textbox control and there is a property called MaxLength. The maxLength property sets or returns the maximum number of characters in a text field. Say for example if we have set the value for the maxlength is 20 and user is trying to enter data which is more than 20 characters then it will not allow to do the same, it works well even if user paste a text which is more than 20 characters.
There is one scenario where it fails, actually I shall not say it fails rather it is not meant for such scenario. The scenario is when we set maxlength to 20 as shown below


And in code behind if we set text property of textbox programmatically as shown belowIn this case the resulting screen would be
This means, in this case it does not restrict maximum number of characters to 20, the reason is, if you see the source of the page (the rendered HTML)
Here the MaxLength property of asp.net control gets converted to maxlength property of HTML and this is meant for client validation and not for server validation. And we are trying to set the value at the server side, which leads to a wrong validation.
Here one has to be aware of this while using MaxLength property.


Another interesting fact about the MaxLength property is, it does not work when you set TextMode="MultiLine"
Say for example we have scenario as shown below
Now if you see source of this page it will be as show below
As we know when we set TextMode="MultiLine", it gets rendered as textarea and surprisingly there is no equivalent attribute/property available for textaera for MaxLength
So in case of TextMode="MultiLine" or when we use HTML textarea we do not have any property which will restrict maxlength. In this case we can write our own javascript function which will check the length on every key press in the textarea. There are many sample available on internet for this.
Few of them are at
http://www.dynamicdrive.com/dynamicindex16/limitinput.htm
http://www.quirksmode.org/dom/maxlength.html

Hope this information helps you.
In case if you find any information here is wrong please feel free to write to me Bharat.Mane@gmail.com
Thank You
Bharat Mane

Wednesday, April 9, 2008

Integrate Microsoft Office Communicator with your Application

While I was using our team room sites which are hosted on share point, I was interested in knowing “How a website shows the status of user which is there in Microsoft Office Communicator?” and my search started to integrate Microsoft Office Communicator with my web application.
So here we have Microsoft Office Communicator installed on user’s machine

Luckily I came to know about NameCtrl Control
A NameCtrl control is an ActiveX control that allows a Web page to display presence information for people, and it allows the user to take various actions with respect to those people through an on-object user interface (UI) in Windows SharePoint Services.
For more details please check out msdn
http://msdn2.microsoft.com/en-us/library/ms455335.aspx
And with small code I could able to come up a HTML page as below,
The code is very simple and easy to use,


HTML Format should be as below
<span>
DISPLAYNAME
<img border='0' height='12' width='12' src='imnunk.GIF' onload="javascript:SPEEDIMNRC('SIPADDRESS')" id='UNIQUE - ID'>
</span>
EXAMPLE:
<span>
Bharat Mane
<img border='0' height='12' width='12' src='imnunk.GIF' onload="javascript:SPEEDIMNRC('bharat.mane@domainname.com')"id='imn7'>
</span>
<span>
Bharat Mane
<img border='0' height='12' width='12' src='imnunk.GIF' onload="javascript:SPEEDIMNRC('E198456@domainname.com')" id='imn7'>
</span>

Note:
Most of the times one's email Id is their SIP Id. But as stated in the above example it might be different also. Good approach would be store and retrieve it from your own database

In the code above there is only one JavaScript function which is new other than basic HTML. This function is responsible to use the ActiveX Name.NameCtrl.1. The complete source code for this function is available in CommunicatorPresence.js.
The complete source code is available at CommunicatorPresence.zip .

In case if you find any information here is wrong please feel free to write to me Bharat.Mane@gmail.com

Thank You
Bharat Mane


Wednesday, March 12, 2008

MS SQL Determining Table sizes (in KB)

Today when I was looking at my database file size and to my surprise I saw the size of database was more than 10 Gigabytes. Then I was keen in knowing tables, which are contributing to this much big size. And Saravana, my colleague gave a fantastic script to find out space used by each table. I thought let’s share it with everybody. Thanks to Microsoft who gave a built in stored procedure sp_spaceused.
With the help of this stored procedure one can easily find out the space with one line code
exec sp_spaceused <Table Name >
sample output

name rows reserved data index_size unused 17991232 12636448 KB 11051664 KB 1583816 KB 968 KB
But I just wanted to find out tables, which are contributing more. Here is that handy script for any DBA

DECLARE
@DBTABLES
AS TABLE
(
SNO INT IDENTITY(1,1),
TABLENAME
VARCHAR(256)
)
INSERT INTO @DBTABLES
SELECT
table_schema + '.' + table_name
FROM
information_schema.TABLES
WHERE
table_type = 'BASE TABLE'
DECLARE
@DBTABLESINFO
AS TABLE
(
SNO INT IDENTITY(1,1),
TABLENAME VARCHAr(256),
ROWS char(11),
reserved varchar(18),
data varchar(18),
index_size varchar(18),
unused varchar(18)
)

DECLARE
@COUNT
INT ,
@CURRENT INT, @TABLENAME VARCHAR(256)
SELECT @COUNT = COUNT(*) FROM @DBTABLES
SET @CURRENT = 1
WHILE (@COUNT >= @CURRENT)
BEGIN
SELECT @TABLENAME =
TABLENAME FROM @DBTABLES WHERE SNO =
@CURRENT
INSERT INTO
@DBTABLESINFO

EXEC sp_spaceused @TABLENAME
SET @CURRENT =
@CURRENT + 1
END

SELECT
TABLENAME,
ROWS,
DATA,
convert(bigint, left(DATA,len(data)-3) )
FROM
@DBTABLESINFO

ORDER BY 4 DESC

Hope this will help.
Regards
Bharat Mane

Saturday, November 24, 2007

File Upload in ASP.NET 2.0

Where I migrated to ASP.NET 2.0 there was a whole new world waiting for me, lots of new features, new control and many more... In all that there was one more and nice feature is "FileUpload" which made life of programmer more easy.

This control is not similar as that of ASP.NET 1.x, here you had to take a few extra steps to make use of it such as
  1. In Classic ASP or ASP.NET 1.x we have to add enctype="multipart/form-data" in form tag.
  2. In classic many programmers use to write their own components to read the stream and save the data as file(s) or they use to use third party controls.

While using this one has to know few key things about the control to get best out of it.

  1. The default value for the maxRequestLength parameter in the section of the Machine.config (C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\CONFIG) file is 4096 (4 megabytes). As a result, files that are larger than this value are not uploaded by default. We can overwite this by required value in the web.config. This will change the value to (8 megabytes)
  2. The value given the executionTimeout attribute is the number of seconds the upload is allowed to occur before being shut down by ASP.NET.
  3. During the upload process, ASP.NET 1.x loads the whole file in memory before the user can save the file to the disk. Therefore, the process may recycle because of the memoryLimit attribute of the processModel tag in the Machine.config file. The memoryLimit attribute specifies the percentage of physical memory that the ASP.NET worker process can exhaust before the process is automatically recycled. Recycling prevents memory leaks from causing ASP.NET to crash or to stop responding. But in ASP.NET 2.0 there is a new attribute "requestLengthDiskThreshold" in the httpRunTime element in the web.config that specifies a disk buffer. Changing this to 8192 and you are done.
  4. Make sure that ASP.NET account is enabled to write to the folder you want, simply open up Microsoft Windows Explorer and navigate to the folder to which you want to add this permission. Right-click on the folder and then select Properties. In the Properties dialog box, click on the Security tab and make sure the ASP.NET Machine Account is included in the list and has the proper permissions to write to disk.

Important Note:
This attribute is available in 2.0 and above,
The RequestLengthDiskThreshold property specifies the input-stream buffering threshold limit in number of bytes. Its value should not exceed the MaxRequestLength property value. After a request entity exceeds this threshold, it is buffered transparently onto disk.
With this, fileupload has improved a lot because the requestLengthDiskThreshold value sets the amount of the request that is cached in memory, and data beyond this value is temporarily written to disk. For more info on this please visit
http://msdn2.microsoft.com/en-us/library/h2e8928c.aspx

Here is one more nice feature (progress bar) added to it
http://www.brettle.com/neatupload

Have a look at the important node in web.config for the FileUpload control
http://msdn2.microsoft.com/en-us/library/e1f13641.aspx

For More details
http://msdn2.microsoft.com/en-us/library/aa479405.aspx
http://aspnetresources.com/articles/discuss/dark_side_of_file_uploads.aspx


In case if you any information here is wrong please feel free to write to me Bharat.Mane@gmail.com

Thank You
Bharat Mane

Friday, October 26, 2007

SQL Server 2005 sp_helptext change.

In the earlier version of MS SQL Server (Before SQL Server 2005) , the data in the system tables was visible to any user. But always it is good to have some other tools to view meta data.
We were using sps such as to view the meta data/definition/script of the objects.
  • sp_help
  • sp_helptext

But in SQL Server 2005 this will not work to any user unless it is explicitly specified. Here you will receive an error

Msg 15009, Level 16, State 1, Procedure sp_helptext, Line 54

If you want it to work like legacy, and does not want to restrict metadata visibility, a new SQL Server 2005 permission can be used. The permission, VIEW DEFINITION, allows a user or role to see the definition of an object or all objects within a particular scope. The below mentioned sql statement can be used to do the same

  • GRANT VIEW ANY DEFINITION TO [user]

But be careful while giving these kind of access to any users. Unless it is required do not GRANT such privileges

For more details please visit
http://www.microsoft.com/technet/technetmag/issues/2006/01/ProtectMetaData/

Bharat Mane