JQuery to get file from a webservice

Note: I have moved to blog at my own domain, so kindly visit this post over there for recent updates or comments. http://www.imranbalouch.com/blog/index.php/2011/07/jquery-to-get-file-from-a-webservice/

Recently we were working on a project, which was ASP.NET 3.0 based and used jquery to get and set data. Our design was to have Presentation layer at separate place and business layer at separate place, so we introduced webservices in it.

We had a use case in which user has to download file, either PDF or ZIP file. In traditional server side code we use to put the byte array of file in Response and user get a download option but in jquery we got stuck as byte array wasn’t getting handled by jquery.

The soultion that we implemented was that we created a server side static method with return type string in our ASP.NET and marked it as a WebMethod.

[WebMethod]
public static string DownloadFile(Int64[] requestId)

if input parameter array has one value, system returns PDF otherwise ZIP file.
Our server side gets data from the web service and writes the file in a folder and return the file virtual path like http://localhost/myapp/tempfolder/myfile.zip to the calling jquery method.

jquery method than uses that url by calling window.open method and user gets that file downloaded.

I feel like that its not a better way of doing it but still don’t have any other.
I will be glad to have a better suggestion from anyone.

All is Well!

Lets Play JavaScript, trips and tricks

Note: I have moved to blog at my own domain, so kindly visit this post over there for recent updates or comments. http://www.imranbalouch.com/blog/index.php/2011/03/lets-play-javascript-trips-and-tricks/

I am writing this blog for different tips and tricks for javascript on demand of a friend of mine who is new to this world, it might contain normal and newbies methods and might have complex scripts. I will be updating it on regular basis.

String Manupulation

To remove/replace some character(s) from string use String.replace() method:

<script type="text/javascript">
        var str1 = "imran balouch";
        str1 = str1.replace("imran","");
        alert (str1);
</script>
Don't forget to assign back the results or replace method to variable.

To get a substring from a string you can use either substring method or slice method.

var str = "Imran Balouch!";
var newStr = str.substring(0, str.length-1);
alert(newStr);
// alert Imran Balouch

The slice() method takes at least one integer argument, which determines after which character the substring will be extracted.

var str = new String("Imran Balouch!");
alert( str.slice(6) );
the alert will show Balouch!

If you pass negative integer to slice method,slice() will cycle backwards (from end to start) through the string until it has iterated through as many characters as the absolute value of the integer passed.

var str = new String("Imran Balouch!");
alert( str.slice(-8) );
the alert will show Balouch!

The second argument optionally accepted by the slice() method is also an integer, and determines the length of the substring returned.

var str = new String("Imran Balouch!");
alert( str.slice(6,7) );
the alert will show Balouch

Other useful methods can be:

Length is a read-only property of JavaScript strings: your scripts can retrieve a string's length (the number of characters it contains), but cannot set it to a new length value.The length property contains and returns a positive integer, or zero in the case of an empty string.
 var str = new String("Imran Balouch!");
alert( str.length.toString() );
alert will show 14.
The charAt() method, a string method that allows you to determine which character is at a given position in a string.
var str = new String("Imran Balouch!");
alert(str.charAt(str.length-1) );
the alert will show !
alert will show 14.

Javascript and C#

If you have created a javascript method and want to call from server side than following can be helpful for you:

<script type="text/javascript">
function callMeFromServer()
{
    alert("Imran Balouch!");
}
</script>

now is your server side code (following is C# code), you can get this method called by:
ScriptManager.RegisterStartupScript(this.Page, this.Page.GetType(), "Testing", "callMeFromServer();", true);
ScriptManager class is present under System.Web.UI

If you are in need of building a javascript array from server side, following can be helpful for you, again its C# code:

System.Random random = new System.Random();
System.Text.StringBuilder clientArray = new System.Text.StringBuilder(String.Empty);
clientArray.Append(" var myArray= new Array(3);");
clientArray.Append("myArray[0]=Imran;");
clientArray.Append("myArray[1]=Balouch;");
clientArray.Append("myArray[2]=!;");
ScriptManager.RegisterStartupScript(this, typeof(String), "BuildMyArray" + random.Next(), clientArray.ToString(), true);

Above code will create a javascript array named myArray and you can access it from client side as:

<script type="text/javascript">
function useMyArray()
{
    if(myArray!=null)
    {
         alert(myArray[0]);
         alert(myArray[1]);
     }
     else
          alert("Array is null, some problem occured.");
}
</script&gt

All for now,I will be editing this post off and on.
All is Well!!

Postback behavior of dropdown in firefox

Note: I have moved to blog at my own domain, so kindly visit this post over there for recent updates or comments. http://www.imranbalouch.com/blog/index.php/2011/03/postback-behavior-of-dropdown-in-firefox/

I am not sure that either it is behavior of firefox or not but that was a strange thing that happened to me during a development.

I have a web application in ASP.NET and C#. On a page I have a drop down list, which works fine in IE. However in firefox if I click on the dropdown, it get expanded, now if i type some charcter, relevant value get selected, now if i click out side the dropdown anywhere on my page, dropdown collpased, new value is shown as selected but no post back occurs even auto post back is set to true.

I even put a client side function to call on change of value, but that also didn’t get called.

I feel like that it is behavior of firefox, caz it appears that firefox postbacks data after dropdown looses focus. on 1st click the focus is at the dropdown and on 2nd click dropdown looses focus. But the wiered thing is that in dropdown new value is being displayed to the user.

But on the other hand if we see it is a nice behavior of firefox, caz on dropdown list if autopoastback is set to true than in IE, if u move focus to dropdown and type A, first value starting with A is selected and page is post backed where as firefox waits for lossing focus so that if selected value is not your desired one than u can reach desired value and avoid extra post backs.

A way out that I found to avoid it in case of mouse usage is to capture the onclick event of dropdown in javascript and hold a value that the dropdown is opened now and capture onclick event of page and see if previous click was on dropdown and new click is not on dropdown than using dopostback, make a post back for the dropdown. I know currently its a wiered solution but right now i figured out only this way to handle it.

All is Well…

Infragistics Ultrawebgrid igtbl_updateAddNewBox(this.Id) throws javascript exception

Note: I have moved to blog at my own domain, so kindly visit this post over there for recent updates or comments. http://www.imranbalouch.com/blog/index.php/2011/02/infragistics-ultrawebgrid-igtbl_updateaddnewboxthis-id-throws-javascript-exception/

While working with Infragistics, ultra webgrid, you might have come across javascript exception, “Object expected” at method igtbl_updateAddNewBox(this.Id).

One basic reason to this exception is that AllowAddNewDefault property of DisplayLayout of Grid is not set to yes, set it to yes and you will get rid of this exception.

But I came across this one in another scenario, and wasted a good amount of time on it. I had 2 aspx pages having master page and update panel. Both pages have ultra web grids in update panel, older page was working fine but the new one was showing strange behavior. After page loaded for first time if i click any cell of grid for editing, it throw the javascript exception but if some postback occurred than it worked fine.

I took grid from older page but no hope, after 6-7 hours it hit my mind that there was a basic difference between both pages, older page was sending synchronous calls to our middle layer web service where as new page (problem child) was sending asynchronous calls to the web service, I removed the asynchronous calls to synchronous ones and removed Async=”true” from the Page directive and here we go, it was working fine.

I am not sure what was the in depth reason behind it but it worked for me, and posting it here, if anyone falls in same trouble. Also I was adding a new row in grid via javascript and was throwing same error on addrow function, which also vanished after it.

All is Well!

CSharp Calling Different Web Services

Note: I have moved to blog at my own domain, so kindly visit this post over there for recent updates or comments. http://www.imranbalouch.com/blog/index.php/2010/05/csharp-calling-different-web-services/

If you are developing an application that has to call different webservices and at run time the application get to know that which method of which web service it has to call than you can use the following code:

using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Security.Permissions;
using System.Web.Services.Description;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
namespace CallbackWindowsService
{
public class DynamicWebService
{
[SecurityPermissionAttribute(SecurityAction.Demand, Unrestricted = true)]
internal static ReturnedObject CallWebService(string webServiceAsmxUrl, string userName, string password, string serviceName, string methodName, object[] args)
//internal static object CallWebService(string webServiceAsmxUrl, string serviceName, string methodName, object[] args)
{
System.Net.WebClient client = new System.Net.WebClient();
ReturnedObject retObj = new ReturnedObject();
try
{
if (userName.Length > 0)
{
client.Credentials = new NetworkCredential(userName, password);
}
System.IO.Stream stream = null;
// Connect To the web service
try
{
stream = client.OpenRead(webServiceAsmxUrl + “?wsdl”);
}
catch (Exception ex)
{
//”Unable to connect to the remote server”
retObj.ServiceIssues = Convert.ToInt64(ServiceIssues.ServiceNotAvailable);
retObj.ErrorMessage = ex.Message;
retObj.ReturnObject = null;
return retObj;
}
// Now read the WSDL file describing a service.
ServiceDescription description = ServiceDescription.Read(stream);
///// LOAD THE DOM /////////
// Initialize a service description importer.
ServiceDescriptionImporter importer = new ServiceDescriptionImporter();
importer.ProtocolName = “Soap12”; // Use SOAP 1.2.
//importer.ProtocolName = “default”;
importer.AddServiceDescription(description, null, null);
// Generate a proxy client.
importer.Style = ServiceDescriptionImportStyle.Client;
// Generate properties to represent primitive values.
importer.CodeGenerationOptions = System.Xml.Serialization.CodeGenerationOptions.GenerateProperties;
// Initialize a Code-DOM tree into which we will import the service.
CodeNamespace nmspace = new CodeNamespace();
CodeCompileUnit unit1 = new CodeCompileUnit();
unit1.Namespaces.Add(nmspace);
// Import the service into the Code-DOM tree. This creates proxy code that uses the service.
ServiceDescriptionImportWarnings warning = importer.Import(nmspace, unit1);
if (warning == 0) // If zero then we are good to go
{
// Generate the proxy code
CodeDomProvider provider1 = CodeDomProvider.CreateProvider(“CSharp”);
// Compile the assembly proxy with the appropriate references
string[] assemblyReferences = new string[5] { “System.dll”, “System.Web.Services.dll”, “System.Web.dll”, “System.Xml.dll”, “System.Data.dll” };
CompilerParameters parms = new CompilerParameters(assemblyReferences);
CompilerResults results = provider1.CompileAssemblyFromDom(parms, unit1);
// Check For Errors
if (results.Errors.Count > 0)
{
String errMessage = String.Empty;
foreach (CompilerError oops in results.Errors)
{
errMessage += oops.ErrorText + “…”;
}
retObj.ServiceIssues = Convert.ToInt64(ServiceIssues.AssemblyCompilingError);
retObj.ErrorMessage = errMessage;
retObj.ReturnObject = null;
return retObj;
}
// Finally, Invoke the web service method
object wsvcClass = results.CompiledAssembly.CreateInstance(serviceName);
MethodInfo mi = wsvcClass.GetType().GetMethod(methodName);
object obj = mi.Invoke(wsvcClass, args);
retObj.ReturnObject = obj;
retObj.ServiceIssues = Convert.ToInt64(ServiceIssues.ProcessedSuccessfully);
}
else
{
retObj.ServiceIssues = Convert.ToInt64(ServiceIssues.NullObject);
retObj.ErrorMessage = “Response Object cannot be created.”;
retObj.ReturnObject = null;
}
return retObj;
}
else
{
retObj.ServiceIssues = Convert.ToInt64(ServiceIssues.ServiceImportWarning);
String errormsg = String.Empty;
switch (warning)
{
case ServiceDescriptionImportWarnings.NoCodeGenerated:
errormsg = “Service Warning: No Code Generated”;
break;
case ServiceDescriptionImportWarnings.NoMethodsGenerated:
errormsg = “Service Warning: No Methods Generated”;
break;
case ServiceDescriptionImportWarnings.RequiredExtensionsIgnored:
errormsg = “Service Warning: Required Extensions Ignored.”;
break;
case ServiceDescriptionImportWarnings.WsiConformance:
errormsg = “Service Warning: Service does not conform to the WS-I Basic Profile.”;
break;
default:
errormsg = “Service Warning: Unknown warning occured with code, ” + warning.ToString() + “.”;
break;
}
retObj.ErrorMessage = errormsg;
retObj.ReturnObject = null;
return retObj;
}
}
catch (Exception ex)
{
retObj.ServiceIssues = Convert.ToInt64(ServiceIssues.UnknownException);
retObj.ErrorMessage = ex.Message;
retObj.ReturnObject = null;
return retObj;
}
}
public DynamicWebService()
{
ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(SSLResult);
}
public Boolean SSLResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
return true;
}
}
public class ReturnedObject
{
public ReturnedObject()
{
}
public object ReturnObject
{
get;
set;
}
public Int64 ServiceIssues
{
get;
set;
}
public String ErrorMessage
{
get;
set;
}
}
public enum ServiceIssues
{
ServiceNotAvailable = 1,
ProcessedSuccessfully = 2,
ClientReturnedNULLObject = 3,
ServiceImportWarning = 4,
AssemblyCompilingError = 5,
UnknownException = 6,
NullObject = 7
}
}

If the webservice you are calling is accepting some object as input parameter you will get an exception that YourObjectType can not be converted to YourObjectType’.

To resolve this issue, replace the following line:

object obj = mi.Invoke(wsvcClass, args);

with

ParameterInfo[] pm = mi.GetParameters();
object ob;
object[] y = new object[1];
YourObjectType objResponse = null;
if (args.Length > 0)
{
objResponse = (YourObjectType)args[0];
}
if (objResponse != null)
{
foreach (ParameterInfo paraminfo in pm)
{
ob = results.CompiledAssembly.CreateInstance(paraminfo.ParameterType.Name);
//Some Junk Logic to get the set the values to the properties of the custom Object
foreach (PropertyInfo propera in ob.GetType().GetProperties())
{
if (propera.Name == “Property1″)
{
propera.SetValue(ob, objResponse.Property1, null);
}
else if (propera.Name == ” Property2″)
{
propera.SetValue(ob, objResponse.Property2, null);
}
}
y[0] = ob;
}
}
object obj = mi.Invoke(wsvcClass, y);

In this above code you will be getting parameters of method and loop on them, create object of the type which WebService is expecting, assign values to the object and call Invoke method.

Happy Development

=================================================================================
Updated On: 20th July 2011
An Update in this context, recently i came across a web service that was written in php and was using Soap as protocol, so the above code was generating NoCodeGeneratedWarning, so i gave it a quick fix.
Before line
if (warning == 0) // If zero then we are good to go
I placed this line of code,
if (warning == ServiceDescriptionImportWarnings.NoCodeGenerated)
{
importer.ProtocolName = “Soap”;
warning = importer.Import(nmspace, unit1);
}
It was the quickest fix i can do for it, however we can put this protocol name in database for each service and assign it accordingly.
Cheers
===============================================================================

SQL CLR UDF returning result set

Note: I have moved to blog at my own domain, so kindly visit this post over there for recent updates or comments. http://www.imranbalouch.com/blog/index.php/2010/05/sql-clr-udf-returning-result-set/

SQL CLR Integration is a very nice feature provided by Microsoft especially if you need to do some complex calculations or deal with objects.

Today we will be creating a User Defined Function,UDF, using CLR, which will return a result set/table and hence will be a Table Value Function, TVF.

Our UDF will be accepting a query parameter, which will hit database and get some XML values and later on deserialize them and return the values in table.

First of all in VS create a SQL Project and add a User Defined Function in it.

public partial class UserDefinedFunctions
{
[Microsoft.SqlServer.Server.SqlFunction(DataAccess = DataAccessKind.Read,
FillRowMethodName = “getDeserializedData_Fill”,
// define columns returned
TableDefinition = “ResquestId bigint, RequestDetailId bigint, Name nvarchar(50), Address nvarchar(50 “
)]
public static IEnumerable getDeserializedData(String sqlQuery)
{
ArrayList resultCollection = new ArrayList();
if (sqlQuery == null || sqlQuery == “”)
{
sqlQuery = “SELECT TOP (10) R.REQUESTID AS REQUESTID, R.REQUESTTYPEID_FK AS REQUESTTYPEID, REQUESTDETAILID, RD.XMLPACKET FROM REQUESTS1 R WITH (NOLOCK)JOIN REQUESTDETAILS1 RD WITH (NOLOCK) ON RD.REQUESTID_FK = R.REQUESTID WHERE RD.REQUESTSTATUSIDINTERNAL_FK = 1”;
}
using (SqlConnection conection = new SqlConnection(“context connection = true;”))
using (SqlCommand command = new SqlCommand(sqlQuery, conection))
{
conection.Open();
SqlDataReader dReader = command.ExecuteReader();
if (dReader != null && dReader.HasRows)
{
DataTable dTable = new DataTable();
dTable.Load(dReader);
foreach(DataRow dRow in dTable.Rows)
{
resultCollection.Add(GetGenericClass(dRow));
}
}
}
return resultCollection;
}

In above code we created a UDF with DataAccessKind.Read to tell that our function will be accessing data only to read it, Fill row method tells the name of method which will be populating the rows of our table and Table Definition tells that which columns will be present in the returning table.

getDeserializedData is our main function that will accept a String type parameter named query, they query which will get data from database. Any UDF that is a TVF must have return type as IEnumerable. Laterally we opened a connection and fetched data from database, and pass one by one row to our GetGenericClass method which return an object of our generic class which we than add in to an ArrayLIst. Our GenricClass is as

using System;
using System.Collections.Generic;
using System.Text;
namespace CLRSQLInregration
{
[Serializable]
public class GenericClass
{
public Int64 ResquestId
{
get;
set;
}
public Int64 RequestDetailId
{
get;
set;
}
public String Name
{
get;
set;
}
public String Address
{
get;
set;
}
}
}

Another Class that we will use is CustomerClass like:

using System;
using System.Collections.Generic;
using System.Text;
namespace CLRSQLInregration
{
[Serializable]
public class CustomerClass
{
public String Name
{
get;
set;
}
public String Address
{
get;
set;
}
}
}

We have marked the class as Serializable, so that we can serialize and deserialize the objects of this class.

Our GetGenericClass method is like:

public static GenericClass GetGenericClass(DataRow dRow)
{
GenericClass objGeneric = new GenericClass();
objGeneric.ResquestId = Convert.ToInt64(dRow[“REQUESTID”]);
objGeneric.RequestDetailId = Convert.ToInt64(dRow[“REQUESTDETAILID”]);
InternalResponse objResponse = null;
if (dRow[“XMLPACKET “] != DBNull.Value)
objResponse = (CustomerClass)Serializer.DeSerializeObject(Convert.ToString(dRow[“XMLPACKET “]), typeof(CustomerClass));
if (objResponse != null)
{
objGeneric.Name = objResponse.Name;
objGeneric.Address = objResponse.Address;
}
}

This method simply deserializes the XML Packet in the row and take values from the object and assign values to our GenericClass object.

Our datafill method is be like:

public static void getDeserializedData_Fill(object obj, out Int64 ResquestId, out Int64 RequestDetailId, out String Name, out String Address)
{
GenericClass objResponse = (GenericClass)obj;
if (objResponse != null)
{
ResquestId = objResponse.ResquestId;
RequestDetailId = objResponse.RequestDetailId;
Name = objResponse.Name;
Address = objResponse.Address;
}
}

This fill method will execute when return resultCollection; code of getDeserializedData method is called.

After all this u need to deploy the CLR assembly and call the UDF and here you go.

Whenever Serialization is involved in CLR, we need to create a Serializer class for our project as well, which can be created by using sgen.exe file of VS or in project properties, go to build events and in post build event command line specify the following line:

“D:Program FilesMicrosoft Visual Studio 8SDKv2.0Binsgen.exe” /force “$(TargetPath)”

It will create the serializer class for your project which you have to add in your CLR assemblies of SQL.

Creating Report Template in Visual Studio

Note: I have moved to blog at my own domain, so kindly visit this post over there for recent updates or comments. http://www.imranbalouch.com/blog/index.php/2010/04/creating-report-template-in-visual-studio/

We have been doing report development using SQL Server 2008 Reporting Services and all of reports normally followed a standard pattern, so I thought to design a report template so that we can have all standards while developing a new report. Following are the steps that I found from net for it:

  • Add a new report to your project
  • Using the report designer place any objects (text boxes, tables, lines, etc) on the report that you want as a template.
  • Give the report a name (anything that you can remember in the future, for instance if you want landscape reports and you create a landscape template you should then call the report LandscapeTemplate.rdl)
  • Save this .rdl file to: C:Program FilesMicrosoft Visual Studio 9.0Common7IDEPrivateAssembliesProjectItemsReportProject

The next time you add a report item you will notice this item in the Templates section.

For older version of SSRS use the Microsoft Visual Studio 8 directory:C:Program FilesMicrosoft Visual Studio 8Common7IDEPrivateAssembliesProjectItemsReportProject

And here you go, ALL IZ WELL… (Y)