Publishing workflow as an ASP.NET Web Service.


 

The workflows developed using windows workflow foundation can be published as a web service. To publish a workflow as a web service, we are provided with two activities. WebServiceInput and WebServiceOutput activity.

 

To create a workflow to be published as a web service do the following

 

Create a new Empty Workflow Project.

 

Add a new interface class to the project which would be used by our WebServiceInput activity.

 

Suppose this is our interface class.

 

interface IAddInterface

                {

        int AddNumber(int firstNumber, int secondNumber);

                }

 

Now right click on the project and add a new Sequential Workflow.

 

Now drag and drop three activities. First WebServiceInput, Code and WebServiceOutput.

 

For webServiceInputActivity1 specify following properties.

 

InterfaceType –IAddInterface.

MethodName AddNumber

 

As soon as method is added we’ll see two new properties added over there one for each parameter specified in the interface method.

i.e. firstNumber and secondNumber.

 

Create two variables to bind with them and one more variable to hold the result.

 

  public int intFirstNumber;

  public int intSecondNumber;

  public int total;

 

 

Specify intFirstNumber, intSecondNumber for firstNumber and secondNumber property of webServiceInputActivity1.

 

Finally set IsActivating as true;

 

 

Now right click code activity and select generate handlers to create a handler method and specify the following code for it

 

private void codeActivity1_ExecuteCode(object sender, EventArgs e)

        {

            total = intFirstNumber + intSecondNumber;

        }

 

Now select webServiceOutputActivity1 and set its properties as following

 

InputActivityName = webServiceInputActivity1

 

ReturnValue = Activity=AddWebServiceWorkflow, Path=total (i.e. to total variable)

 

That’s it now we want to publish it as workflow.

 

For this right click the project and Select Publish as a web servcie option.

 

 

This would create a new webservice which would be named as worklflowProjectName.worfklowMethodName_WebService.asmx.

 

Now we could use it just like any other web service created using ASP.NET.

 

WebServiceInputActivity recieves input from the client using the webservice. It can be  associated with single web service method defined inside the interface. The WebServiceInputActivity can be followed by the set of activities which could be built in or custom activity. If the response has to sent back to the calling client than we need to make use of WebServiceOutputActivity.

Understanding and Using AJAX


Suppose this is our simple ASP.NET page i.e. MyPage.aspx which would be called using AJAX

Code for MyPage.aspx.cs

protected void Page_Load(object sender, EventArgs e)

{

// no data is passed

if (Request.QueryString[“myGetData”] == null)

{

Response.Write(“Hello World”);

}

// if GET method is used to call this page

else if (Request.QueryString[“myGetData”] != null)

{

Response.Write(“Hello “ + Request.QueryString[“name”].ToString());

}

// if POST method is used to call this page

else if (Request.Form[“myPostData”] != null)

{

Response.Write(“My Post Data is “ + Request.Form[“myPostData”].ToString());

}

}

Delete everything from MyPage.aspx page just keep the page directive otherwise html tags would also be sent as a part of response.

<%@ Page Language=”C#” AutoEventWireup=”true” CodeFile=”Mypage.aspx.cs” Inherits=”MyPage” %>

Now the javascript code to call the page asynchronously using AJAX. Comment/Uncomment the particular section of code to test the functionality

<script type=”text/javascript”>

var request=null;

function CreateRequest()

{

try

{

// create a new object to talk HTTP with a web server.

// XMLHttpRequest – works on Safari,Firefox, Mozilla, Opera , IE 7 and most other browsers

request=new XMLHttpRequest();

}

catch(trymicrosoft)

{

try

{

// Msxml2.XMLHTTP – Most version of IE support this

request=new ActiveXObject(“Msxml2.XMLHTTP”);

}

catch(othermicrosoft)

{

try

{

//Microsoft.XMLHTTP – but for some, we’ll need this other type

request=new ActiveXObject(“Microsoft.XMLHTTP”);

}

catch(failed)

{

request=null;

}

}

}

if(request==null)

alert(‘Error creating request object’);

else

{

// i.e. space with %20

// if no data is to be send

var url=“MyPage.aspx”;

// open-initialize the connection

// GET – specify how to send data to the server

// url- url to send the request

// asynchrounous – true

request.open(“GET”,url,true);

// telling the browser what to do with the server’s response

// i.e. the function to be called when response is received

// onreadystatechange- this property affects every ready state not just the one indicating

// that the server is finished with request

request.onreadystatechange=updatepage;

// send the request

// no data is required so send null

// for using send() to pass data to a server requires POST method for the request and need to specify content type

request.send(null);

// if data is to be send using GET i.e. as query string

var name=“MyName”;

// escape() function replaces characters like space with something that will work as a part of a request URL.

var url=“MyPage.aspx?myGetData=”+escape(name);

request.open(“GET”,url,true);

request.onreadystatechange=updatepage;

request.send(null);

// if more data is to be send than use post

var name=“MyName”;

var url=“MyPage.aspx”;

request.open(“POST”,url,true);

request.onreadystatechange=updatepage;

//setRequestHeader()- allows us to add information to the request usual intended for use by the server

// Content-Type – is the name of the request header

// application/x-www-form-urlencoded – the value of the request header

// this tells the server that the data is encoded like it would be in a request URL

// for passing XML content replace “application/x-www-form-urlencoded” with “text\xml”

request.setRequestHeader(“Content-Type”,“application/x-www-form-urlencoded”);

// specify the data to be send

// escape() function replaces characters like space with something that will work as a part of a request URL.

request.send(“myPostData=”+escape(name));

}

}

// updatepage – this function will get run every time the ready state changes

function updatepage()

{

// readyState=this property of the request object stores the current state

// if 4 means server is done with the request

// if 0 i.e uninitialized

// if 1 i.e open, the object has been created but the send method has not been called

// if 2 i.e. sent, the send method has been called.

// if 3 i.e. receiving , responseText is not available but some data has been received

// if 4 i.e. loaded, all the data has been received, responseText is available

if(request.readyState==4)

{

// check for the status send by the server

// if 200 i.e. everything is fine

// if 404 i.e. if the page specified in the url is not found

if(request.status==200)

{

var myResponse=request.responseText;

alert(myResponse);

}

else

{

alert(“Error! Request status is “ +request.status);

}

}

}

</script>

<input id=”Button1″ type=”button” value=”button” onclick=”CreateRequest()”/>

Bye…

Calling an ASP.NET web service asynchronously.


When we add a web reference to a web service behind the screen wsdl.exe is run which creates the proxy class. Proxy class contains both synchronous and asynchronous flavors of each web method.For simple HelloWorld() web method following methods are there in the proxy class

Public string HelloWorld()

Public string HelloWorldAsync();

Public string HelloWorldAsync(object userState);

We call the HelloWorldAsync() method which in turn calls the following method of the proxy class InvokeAsync()

// Summary:

// Invokes the specified method asynchronously.

// Parameters:

// methodName:

// The name of the method to invoke.

// parameters:

// The parameters to pass to the method.

// callback:

// The delegate called when the method invocation has completed.

protected void InvokeAsync(string methodName, object[] parameters, SendOrPostCallback callback);

HelloWorldCompletedEventArgsThis class is also created by wsdl.exe which contains the result of our operation.

Suppose this is our simple web service, we have introduced delay to understand the asynchronous behavior.

[WebMethod]

public string HelloWorld() {

Thread.Sleep(5000);

return “Hello World”;

}

Now to call the above webservice method asynchrously in a windows application client we need to do the following

Say we have want to call the HelloWorld method asynchronously on the click of the button,

private void btnCallService_Click(object sender, EventArgs e)

{

// Create the instance of the proxy class

Service myService = new Service();

// Register an eventhandler for HelloWorldCompleted event

// The eventhandler would be called when the request is

// completed

myService.HelloWorldCompleted += new

HelloWorldCompletedEventHandler(this.HelloWorldCompleted);

// instead of calling the synchronous HelloWorld() we need

// to call the HelloWorldAsync() method

myService.HelloWorldAsync();

}

void HelloWorldCompleted(object sender,HelloWorldCompletedEventArgs args){

// Display the reutrn value

MessageBox.Show(args.Result);

}

To call the above web method in an asp.net client we need to add the following attribute in the @Page directive

Async=”true”

Bye..

FileUpload : Page Cannot be displayed and maximum request length exceeded error


By default, ASP.NET permits only files that are 4,096 kilobytes (KB) or less to be uploaded to the Web server.  To upload larger files, we must change the maxRequestLength parameter of the <httpRuntime> section in the Web.config file. By default, the <httpRuntime> element is set to the following parameters in the Machine.config file:

<httpRuntime

executionTimeout=90

maxRequestLength=4096

useFullyQualifiedRedirectUrl=false

minFreeThreads=8

minLocalRequestFreeThreads=4

appRequestQueueLimit=100

/>

We can change the value of maxRequestLength to a desired value in our web.config of the application. For 10 mb we can set it to 10240 KB. Even in this case if user tries to upload a file with size more than 10 mb we than get the above “Page cannot be displayed error ” or the page simply hang up. In this case we can catch the error in the Application_Error event handler of the Global.asax file.

void Application_Error(object sender, EventArgs e)

{

if (System.IO.Path.GetFileName(Request.Path) == “Default.aspx”)

{

System.Exception appException = Server.GetLastError();

if (appException.InnerException.Message == “Maximum request length exceeded.”)

{

Server.ClearError();

Response.Write(“The form submission cannot be processed because it exceeded the maximum length allowed by the Web administrator. Please resubmit the form with less data.”);

Response.Write(“<BR><a href=’Default.aspx’>Click Here to go back to page</a> </BR>”);

Response.End();  } } }

I tried with the above code, but it isn’t consistent.

The best solution for this could be to set the value of maxRequestLength to a very high value.

and checking in the code for the size.

Say changing the value to say 700mb ( not sure what the maximum length of request could be)

<httpRuntime useFullyQualifiedRedirectUrl=true

maxRequestLength=716800

/>

And checking for the length in your code

// Putting the constraint of 1 mb

if (FileUpload1.FileContent.Length < 1024){

FileUpload1.SaveAs(@”C:/MyFolder/” + FileUpload1.FileName);}

else{

return;}

At least the above solution would save us from the page not displayed error.

And the last solution which i found was creating an httpmodule to intercept the web request.

using System;

using System.Collections.Generic;

using System.Text;

using System.Web;

namespace HAMModule{

public class MyModule : IHttpModule{

public void Init(HttpApplication app){

app.BeginRequest += new EventHandler(app_BeginRequest);

}

void app_BeginRequest(object sender, EventArgs e){

HttpContext context = ((HttpApplication)sender).Context;

// check for size if more than 4 mb

if (context.Request.ContentLength > 4096000){

IServiceProvider provider = (IServiceProvider)context;

HttpWorkerRequest wr = (HttpWorkerRequest)provider.GetService(typeof(HttpWorkerRequest));

// Check if body contains data

if (wr.HasEntityBody()){

// get the total body length

int requestLength = wr.GetTotalEntityBodyLength();

// Get the initial bytes loaded

int initialBytes = wr.GetPreloadedEntityBody().Length;

if (!wr.IsEntireEntityBodyIsPreloaded()){

byte[] buffer = new byte[512000];

// Set the received bytes to initial bytes before start reading

int receivedBytes = initialBytes;

while (requestLength – receivedBytes >= initialBytes){

// Read another set of bytes

initialBytes = wr.ReadEntityBody(buffer, buffer.Length);

// Update the received bytes

receivedBytes += initialBytes;

}

initialBytes = wr.ReadEntityBody(buffer, requestLength – receivedBytes);}}

// Redirect the user to an error page.

context.Response.Redirect(“Error.aspx”);}}

public void Dispose(){}

}}

and add the following information to web.config

<httpModules>

<add type=HAMModule.MyModule name=MyModule/>

</httpModules>

inside

<system.web>

The last solution worked properly!!!!

BeginRequest event –The BeginRequest event signals the creation of any given new request. This event is always raised and is always the first event to occur during the processing of a request.

Article on creating a custom http module

http://msdn.microsoft.com/en-us/library/ms227673(VS.80).aspx


Bye..

Using Encryption and Decryption in an ASP page


Hi I was looking for implementing cryptography in an ASP page.

I found this following article of great use

http://www.4guysfromrolla.com/webtech/010100-1.shtml

The inc file

<%
Dim sbox(255)
Dim key(255)

Sub RC4Initialize(strPwd)
dim tempSwap
dim a
dim b
intLength = len(strPwd)
For a = 0 To 255
key(a) = asc(mid(strpwd, (a mod intLength)+1, 1))
sbox(a) = a
next

b = 0
For a = 0 To 255

b = (b + sbox(a) + key(a)) Mod 256
tempSwap = sbox(a)
sbox(a) = sbox(b)
sbox(b) = tempSwap
Next
End Sub

Function EnDeCrypt(plaintxt, psw)

dim temp
dim a
dim i
dim j
dim k
dim cipherby
dim cipher

i = 0
j = 0

RC4Initialize psw
For a = 1 To Len(plaintxt)
i = (i + 1) Mod 256
j = (j + sbox(i)) Mod 256
temp = sbox(i)
sbox(i) = sbox(j)
sbox(j) = temp
k = sbox((sbox(i) + sbox(j)) Mod 256)

cipherby = Asc(Mid(plaintxt, a, 1)) Xor k
cipher = cipher & Chr(cipherby)
Next
EnDeCrypt = cipher
End Function

%>

And following is the code for my asp page

<!–#include file=”g.inc”–>

<html>
<head>
<title>TestPage</title>
</head>
<body>
<form action=”G.asp” method=”post”>
<%
dim psw, txt
dim strTemp
txt=”NishantRana”
psw=”myPassword”
strTemp=EnDeCrypt(txt,psw)
response.write “Encrypted Text =” & strTemp & “</Br>”
txt=EnDeCrypt(strTemp,psw)
response.write “Decrypted Text =” & txt
%>
</form>

</body>

</html>

Just copy and paste the code

That’s it …


IIS not serving ASP.NET pages


It mostly happens when IIS is installed after .NET is installed. So in this case we need to make use of aspnet_regiis.exe utility.
1) Go to command prompt
2) Go to the following path
“C:WINDOWSMicrosoft.NETFrameworkv2.0.50727”
depending on the version.
3) Enter “aspnet_regiis.exe -i”
4) It will display the message finished installing
5) Open your IIS
6) Select web service extensions
7) Click on Allow for ASP.NET v2.0.50727

That’s it . Now the IIS has been configured properly

%d bloggers like this: