Tuesday, September 23, 2008

DYNAMIC IFRAME HEIGHT

Following code sample is taken from dynmaicdrive.com to get rid of IFRAME scrollbars. It will also adjust the Frame height automatically

/***********************************************
* IFrame SSI script II- © Dynamic Drive DHTML code library (http://www.dynamicdrive.com)
* Visit DynamicDrive.com for hundreds of original DHTML scripts
* This notice must stay intact for legal use
***********************************************/

//Input the IDs of the IFRAMES you wish to dynamically resize to match its content height:
//Separate each ID with a comma. Examples: ["myframe1", "myframe2"] or ["myframe"] or [] for none:
var iframeids=["IFReports"]

//Should script hide iframe from browsers that don't support this script (non IE5+/NS6+ browsers. Recommended):
var iframehide="yes"

var getFFVersion=navigator.userAgent.substring(navigator.userAgent.indexOf("Firefox")).split("/")[1]
var FFextraHeight=parseFloat(getFFVersion)>=0.1? 16 : 0 //extra height in px to add to iframe in FireFox 1.0+ browsers

function resizeCaller() {
var dyniframe=new Array()
for (i=0; i
if (document.getElementById)
resizeIframe(iframeids[i])
//reveal iframe for lower end browsers? (see var above):
if ((document.all || document.getElementById) && iframehide=="no"){
var tempobj=document.all? document.all[iframeids[i]] : document.getElementById(iframeids[i])
tempobj.style.display="block"
}
}
}

function resizeIframe(frameid){
var currentfr=document.getElementById(frameid)
if (currentfr && !window.opera){
currentfr.style.display="block"
if (currentfr.contentDocument && currentfr.contentDocument.body.offsetHeight) //ns6 syntax
currentfr.height = currentfr.contentDocument.body.offsetHeight+FFextraHeight;
else if (currentfr.Document && currentfr.Document.body.scrollHeight) //ie5+ syntax
currentfr.height = currentfr.Document.body.scrollHeight;
if (currentfr.addEventListener)
currentfr.addEventListener("load", readjustIframe, false)
else if (currentfr.attachEvent){
currentfr.detachEvent("onload", readjustIframe) // Bug fix line
currentfr.attachEvent("onload", readjustIframe)
}
}
}

function readjustIframe(loadevt) {
var crossevt=(window.event)? event : loadevt
var iframeroot=(crossevt.currentTarget)? crossevt.currentTarget : crossevt.srcElement
if (iframeroot)
resizeIframe(iframeroot.id);
}

function loadintoIframe(iframeid, url){
if (document.getElementById)
document.getElementById(iframeid).src=url
}

if (window.addEventListener)
window.addEventListener("load", resizeCaller, false)
else if (window.attachEvent)
window.attachEvent("onload", resizeCaller)
else
window.onload=resizeCaller

ReportViewer Height + Scrollbars

If the output is mushed height-wise, add this to the ReportServices.css file which can be located under ReportManager/styles:

/* Fix report IFRAME height for Firefox */
.DocMapAndReportFrame
{
min-height: 860px;

}

------------------------------------------------------------------------------------------------

Following code uses javascript to get rid of multiple scrollbars in VS2005 reportviewer control

window.onload=function RemoveScrollbars()

{

document.getElementById("<%=ReportViewer1.ClientID %>").lastChild.firstChild.style.overflow = "visible";

}

<rsweb:ReportViewer

ID="ReportViewer1"

runat="server"

ProcessingMode="Remote"

AsyncRendering="false"

SizeToReportContent="true" />




Wednesday, September 3, 2008

Journey From NDoc To SandCastle

NDoc was Source Forge tool for generating MSDN style documentation based on XML comments in your .NET 1.0 or 1.1 code. Now with the evolution of 2.0 XML Comments with "///" no revised NDoc version is available till date.

Microsoft has stepped in an provided SandCastle, which allows you to generate documentation and help files based on your .NET 2.0 code. It is still in CTP, but has the following features:

“Sandcastle produces accurate, MSDN style, comprehensive documentation by reflecting over the source assemblies and optionally integrating XML Documentation Comments. Sandcastle has the following key features:

  • Works with or without authored comments
  • Supports Generics and .NET Framework 2.0
  • Sandcastle has 2 main components (MrefBuilder and Build Assembler)
  • MrefBuilder generates reflection xml file for Build Assembler
  • Build Assembler includes syntax generation, transformation..etc
  • Sandcastle is used internally to build .Net Framework documentation“

You can download SandCastle here

Following resources can provide you additional information about Sandcastle:


Creating a Chm build using Sandcastle

Here are the steps to create a Chm build using Sandcastle. Please see the atatchment for the steps in text format.

Prerequisites:

1. .Net Framework 2.0

2. For Chm generation download HTML Help Workshop - http://msdn.microsoft.com/library/default.asp?url=/library/en-us/htmlhelp/html/hwMicrosoftHTMLHelpDownloads.asp

How do Reference Build From /// Comments using Sandcastle V2.0:

Sandcastle can read authored triple-slash comments embedded in source files.

  1. Sandcastle by default is installed at c:\Program files\Sandcastle. Open a command prompt and type the following:

cd \Program Files\Sandcastle\Examples\Sandcastle

In this directory, you will find only a single C# file called test.cs under Examples\sandcastle directory.

  1. Begin by compiling the C# file and extracting the /// comments.

csc /t:library /doc:comments.xml test.cs

  1. This creates not only test.dll, but also comments.xml file that contains the extracted /// comments

  1. Next, run MRefBuilder:

MRefBuilder test.dll /out:reflection.org

  1. Transform the output

For building using VS2005 transforms please use the following:

XslTransform /xsl:"..\..\ProductionTransforms\ApplyVSDocModel.xsl" reflection.org /xsl:"..\..\ProductionTransforms\AddFriendlyFilenames.xsl" /out:reflection.xml

For building using prototype transforms please use the following:

XslTransform /xsl:..\..\ProductionTransforms\ApplyPrototypeDocModel.xsl reflection.org /xsl:..\..\ProductionTransforms\AddGuidFilenames.xsl /out:reflection.xml

  1. Generate a topic manifest

XslTransform /xsl:..\..\ProductionTransforms\ReflectionToManifest.xsl reflection.xml /out:manifest.xml

  1. Create an output directory structure

For building using VS2005 transforms please use the following:

call ..\..\Presentation\vs2005\copyOutput.bat

For building using prototype transforms please use the following:

call ..\..\Presentation\Prototype\copyOutput.bat

  1. Run BuildAssembler using the sandcastle component stack (Note: We are providing VS 2005 transforms under Presentation/VS2005 folder and the transforms shipped with the previous versions under Presentation/Prototype folder. For building VS2005 format please use sandcastle.config file from C:\Program Files\Sandcastle\Presentation\vs2005\Configuration folder as it uses shared content from C:\Program Files\Sandcastle\Presentation\vs2005\Content and transforms from C:\Program Files\Sandcastle\Presentation\vs2005\Transforms)

BuildAssembler /config:sandcastle.config manifest.xml

to generate topic files in HTM.

  1. Generate HTML help project

XslTransform /xsl:..\..\ProductionTransforms\ReflectionToChmProject.xsl reflection.xml /out:Output\test.hhp

  1. Generate intermediate table of contents

For building using VS2005 transforms please use the following:

XslTransform /xsl:..\..\ProductionTransforms\createvstoc.xsl reflection.xml /out:toc.xml
For building using prototype transforms please use the following:
XslTransform /xsl:..\..\ProductionTransforms\createPrototypetoc.xsl reflection.xml /out:toc.xml

  1. Generate HTML help project information

XslTransform /xsl:..\..\ProductionTransforms\TocToChmContents.xsl toc.xml /out:Output\test.hhc

XslTransform /xsl:..\..\ProductionTransforms\ReflectionToChmIndex.xsl reflection.xml /out:Output\test.hhk

  1. Run hhc (HTML Help 1.x Compiler) to generate Chm, hhc compiles the Sandcastle target files into a CHM file.

hhc output\test.hhp

Tuesday, August 12, 2008

Securing Web Services With Username and Password

keithelder's Blog.......

The article is short and doesn't give any examples of one of the methods I use a lot. I thought I would elaborate on one of the topics it touches on which is securing a web service with a Username and a Password. While there are other ways to secure web services I find this particular method works really well when dealing with internal systems that may not speak .Net. It is also simple to implement on both sides. These systems could be in Java, PHP or even 4GL. If you are a .Net developer and want to secure a web service with a username, password, or even other information, here is what you need to get going.

1. Create an object that extends SoapHeader


The first thing you need to do is create an object that extends the built-in SoapHeader object. The object can be simple or complex. Add the tokens you want to authenticate against. Here is a sample:

1 ///

2 /// Extends from SoapHeader and provides a username / password

3 /// for web methods that need authentication.

4 ///

5 public class ServiceAuthHeader : SoapHeader

6 {

7 public string Username;

8 public string Password;

9 }

2. Add a property to your service class that uses the class above


Once you've created your base soap header class, add it as a property to your service class.

// SoapHeader for authentication

public ServiceAuthHeader CustomSoapHeader;

3. Attribute the method you want to secure


Add the SoapHeader attribute to each or certain methods you wish to secure pass in the name of the property that is defined as the SoapHeader object in step 2.

1 [WebMethod]

2 [SoapHeader("CustomSoapHeader")]

3 public int AddTwoNumbers(int x, int y)

4 {

5

6 return x + y;

7 }

4. Create a method to process your SoapHeader for authentication

The last big step is to create a static method that will take in your custom soap header class and process it for validation. The first thing we want to do is make sure that some type of credentials were passed in the SoapHeader and that the properties we are looking for are not null. Finally we want to validate each property contains the information we are looking for. This could be read from the web.config file, database, or other places.

1 public class ServiceAuthHeaderValidation

2 {

3 ///

4 /// Validates the credentials of the soap header.

5 ///

6 ///

7 public static bool Validate(ServiceAuthHeader soapHeader)

8 {

9 if (soapHeader == null)

10 {

11 throw new NullReferenceException("No soap header was specified.");

12 }

13 if (soapHeader.Username == null)

14 {

15 throw new NullReferenceException("Username was not supplied for authentication in SoapHeader.");

16 }

17 if (soapHeader.Password == null)

18 {

19 throw new NullReferenceException("Password was not supplied for authentication in SoapHeader.");

20 }

21

22 if (soapHeader.Username != "myusername" || soapHeader.Password != "mypassword")

23 {

24 throw new Exception("Please pass the proper username and password for this service.");

25 }

26 return true;

27 }

28 }

5. Add validation to service method

1 [WebMethod]

2 [SoapHeader("CustomSoapHeader")]

3 public int AddTwoNumbers(int x, int y)

4 {

5 // Test to see if the proper credentials were passed in.

6 ServiceAuthHeaderValidation.Validate(CustomSoapHeader);

7

8 // If we get this far the user has been validated.

9 return x + y;

10 }

That's it. You now have all the pieces of the puzzle to process a request and validate the credentials of the calling client via a username and or password. If we launch the solution we will see that our XML for our service has been updated and now contains an XML Node called ServiceAuthHeader which contains two sub nodes: username, password.

Passing SoapHeader Credentials To Your Service

Now that we have our service secured, we need to now call the service and pass the credentials expected from a client. Based on the example above, once you add a web reference to the service and instantiate the service in code, the thing you want to look for is a new property of your service proxy called ServiceAuthHeader. This is converted into a property called ServiceAuthHeaderValue. This property needs to be an instantiation of the ServiceAuthHeader class where you set the username and password properties. Here is an example of a console application calling our service and passing the required information to authenticate.

1 using System;

2 using System.Collections.Generic;

3 using System.Text;

4

5 namespace ConsoleApplication1

6 {

7 class Program

8 {

9 static void Main(string[] args)

10 {

11 localhost.Service service = new ConsoleApplication1.localhost.Service();

12 localhost.ServiceAuthHeader header = new ConsoleApplication1.localhost.ServiceAuthHeader();

13 header.Username = "myusername";

14 header.Password = "mypassword";

15 service.ServiceAuthHeaderValue = header;

16 int x = service.AddTwoNumbers(1, 1);

17 Console.WriteLine(x);

18 Console.ReadLine();

19 }

20 }

21 }

The return result will be 2 of course and from the client side it is rather trivial to pass the credentials as you see. That's it. Happy authenticating!

[Related Link]
To take authenticating one step further with a custom SoapExtension read this follow up article.
http://keithelder.net/blog/archive/2007/01/09/Take-Securing-Web-Services-With-Username-and-Password-One-Step.aspx

Error 8152: "String or binary data would be truncated"

Following could be the possible reasons:

This error usually comes because of incorrect length of table fields.

1. check if there are triggers on the table, if so, you should check out the code of those as well.
2. Check field length of your table and any foreign key tables if exist

Sunday, August 10, 2008

Merging New Rows to an Existing DataSet

We can merge new records to an existing fillled dataset. Following is the example code:

//Existing Dataset
DataSet ds = code to fill dataset;

DataTable dt = reports.Tables[0];
foreach (DataRow dr in dt.Rows)
{
DataRow newRow = ds.Tables[0].NewRow();
newRow["name"] = dr["DisplayName"];
newRow["path"] = dr["ID"];
newRow["rolename"] = dr["Roles"];
newRow["username"] = HttpContext.Current.User.Identity.Name.ToString();


//Appending newly generated row to existing table in the dataset
ds.Tables[0].Rows.Add(newRow);
}

Thursday, August 7, 2008

C# Dynamic object instantiation and Method Calls

Following is the code to load any assembly and reading its classes to make dynamic instances out of them. You can further call the dynamic methods as well.


//Loading an assembly
Assembly objAssembly = Assembly.LoadFrom(Server.MapPath(@"bin\test.dll"));


//Getting list of all types in a the assembly
Type[] type = objAssembly.GetTypes();

// You can also define a typename if that is already known
//Type t = objAssembly.GetType("testnamespace.testclass");

//********************************************************

//Making Instance of object by passing a particular type
object newInstance = Activator.CreateInstance(type[0]);

//Calling the method of the newly created instance by using type name
string str = (string)type[0].GetMethod("testmethod").Invoke(newInstance, null);


Your test.dll will look something like this.....

namespace testnamespace
{
public class testclass
{
public static string testmethod()
{
return "hello";
}
}
}