Category Archives: .NET

How did I changed ProjectDocs

This is my first post as part of “Experience” series. In these posts I’ll discuss on my previous projects about why I worked on it, how I made them, what mistakes I made and my learning while working on them. Hope you will enjoy these boring stuff.

“ProjectDocs” is my first application that i worked on in Omni Offshore. It is 2010, July 1st, my first day in Omni Offshore. I completed the formal introduction and received my ID card and regular stationary like pencil, notebooks and etc. and my manager shown my work space. I was relaxed and had a brief chat with my co-workers and learned about their hobbies and interests. Then comes my manager with few documents and introduced me yo my first project to maintain and it is “ProjectDocs”

I quickly gone through the BRD (Business Requirements Document), a kind of SRS. Let me explain briefly about the project. It is ASP.NET application but depends on Documentum from EMC. Basically this system allows users from shipyard to review drawings from engineering team and make comments on them if they are not clear. Once all clear they use them to build ships. By the way, our company builds big ships for oil and gas companies. We call them FSOs (Floating Storage and Off-take) and FPSOs (Floating Production Storage and Offloading).

So this gave me the opportunity to learn more about Documentum, DQL, DFC and DFS. The system is already in production and I received a list of issues and enhancement requests from business users. I went through the code and started to understand what all about Documentum. I sat with our Documentum resource to learn more about its structure and its query language (DQL). Made few POCs to understand the interfacing part between ASP.NET and Documentum using DFC (Documentum Foundation Classes). Within a week time I was ready to take on those issues and enhancements.

Documentum is a self contained JAVA based system. It hold metadata as well as content of the documents. It supports organising the documents by doctypes and each doctype is defined by its attributes. Consider each doctype is a table in DBMS and attributes as columns for the table. Documentum exposes an API by means of DFC or DFS. DFC is a COM component  that should be installed on each client machine. DFS are services exposed from Documentum server. We also can use DQL, a query language to retrieve or update the data from the Documentum system. Initially our ASP.NET application communicates Documentum through DFC.

When I was gone through the code I found that our ASP.NET application is nothing but a wrapper around Documentum functionality and there are many pull and push requests between Documentum and the application. Also I found that the system is very tightly coupled with shipyard name in such a way that they have to create virtually every thing from Documentum structure to ASP.NET application if there is a new shipyard to deal with. In fact that’s what happened, they have 4 such applications with different code base to deal with different shipyards. That means any change have to be done manually on those code bases and deploy separately to the production server.

I concluded that, with the current setup its not possible to make the changes. Also since there are many pull and push requests between Documentum and our application the overall responsiveness is worst and it is getting only to much worse. So I talked to our manager and said we needs to seriously think about this and asked to have a meeting with all the stakeholders.

There are 10 participants in the meeting room and one of them is our GM. That’s hardly one week of me taking the charge and my GM is interested in my opinion. That made me aware of the importance of the system as well as the risk in my recommendations. But I did proceed to the meeting room any my hands and shaking a bit as I am thinking about what to say. Everybody looked at my manager who started the meeting and listed all issues with the current setup. Now all looking at me for my opinion and i said “scrap current setup and build a better system from ground up”. My GM seems not convinced but agreed anyway after couple of discussions.

Now the interesting part, design the new system. I still took Documentum into consideration as that is our central repository of documents and many workflows running on those documents. But this system is internal and becuase of that we need ASP.NET application to interface between public user (shipyard user/Engineering team) and Documentum. The change I made was, keep Documentum only to store documents and moved system data to Oracle. Because of this, the whole business process like commenting and approvals happens on ASP.NET system and final documents will go to Documentum. Due to this, unless I need the document the system does not talk to Documentum where as previously the whole business process is on Documentum.

This change brought flexibility in maintaining the system as you can create as many shipyards you want and assign users to represent them. Due to this we don’t need to touch Documentum every time we have a new shipyard to introduce. As a byproduct to this whole exercise I have a robust understanding over Documentum, DQL, DFS and DFC. This way I am able to bring flexibility and speed into the system which helped the end users. It also helped our IT department in terms of maintenance and reduced the dependency on Documentum resource. And finally reduced cost of ownership to the company as system become very popular so that all our shipyards started using them.

Advertisements

Telerik RadControls IE11 javascript error

I encountered an issue after I deploy my .NET 4.0 (ASP.NET) web application to out new testing server. That server is running Windows Server 2008 R2. After deployment I started testing the web application. Soon I ended up with script error like;

Unable to get property ‘PageRequestManager’ of undefined or null reference

The issue is related to browser detection. .NET 4.0 could not detect the IE11 browser correctly to let the telerik serve correct javaScript. You can ressolve this issue by installing a patch available with Microsoft at here.

If you want to read more then head to the original Telerik artical.

 

Microsoft AJAX, Business Objects at Client Side–Part 1

When I started working on the ASP.NET, its all about the server side coding and database connectivity. JavaScript is more like a validation tool, this is the mind-set that i had. But recent days in my new company changed my mind-set. Now I am exploring the JavaScript into very much details. I am very much delighted to have such a type of colleagues who helped me to change this mind-set. During this time I experimented with many thing and one of them is effective use of Microsoft AJAX.

Most of the “ASP.NET” programmers has this habit of using UpdatePanels, and ScriptManagers to work with Microsoft AJAX and stops there. But few people go beyond that. That is where actual beauty begins. Now i just wanted to share them with you.

My goal here is to access or use the server side business objects in the java script with the same signature. The advantage is here is, i don’t need to worry about the data types and JSON string. For me it is just like another server side function. To achieve this many programmer use many methods offered by the Microsoft AJAX framework.

In my case I used WCF services to expose my business logic. One can use normal web service for this. So what are the tools I require to build this?

  1. AJAX Enabled WCF Service.
  2. Script Manager (Microsoft AJAX)

Let us see these points in detail,

1. AJAX Enabled WCF Service:

In my project, I have my business logic in one business layer. Since it is already there, I don’t want to change them. So i created one WCF service in which I written the proxy classes to exactly match with my business class.

Here I am using the default SQL Database, “AdventureWorks” in that three tables Employee, Departments, EmployeeDepartmentHistory and EmployeeAddress. My dbml is as follows,

image

Now I need to create a WCF service to access these tables.

image

In my case, service name is Employee.svc. the following is the default code that visual studio generates,

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Web;
using System.Text;

namespace ClientSideBusinessObjects.WCFService
{
	[ServiceContract(Namespace = "")]
	[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
	public class Employee
	{
		// To use HTTP GET, add [WebGet] attribute. (Default ResponseFormat is WebMessageFormat.Json)
		// To create an operation that returns XML,
		// add [WebGet(ResponseFormat=WebMessageFormat.Xml)],
		// and include the following line in the operation body:
		// WebOperationContext.Current.OutgoingResponse.ContentType = "text/xml";
		[OperationContract]
		public void DoWork()
		{
			// Add your operation implementation here
			return;
		}

		// Add more operations here and mark them with [OperationContract]
	}
}

Here “Namespace” in the ServiceContract or DataContract will tell us, under which name these classes should group together. In my case it is “BusinessObjects”. Right after that, we will observe AspNetCompatiblityRequirements, this is required and makes service available in the client side. All our methods, if need to available in client side then must be attributed by [OperationContract].

2. ScriptManager (Microsoft AJAX):

Script manager is the one who brings our web service to the JavaScript. Once we place the script manager onto the page, it is time to tell the script manage about our web service. To cater this, script manger comes with a property called “Services”. Under this we can assign our web service using ServiceReference. The following is the typical code to achieve the above,

<asp:ScriptManager ID="ScriptManager1" runat="server">
	<Services>
		<asp:ServiceReference Path="~/WCFService/Employee.svc" />
	</Services>
</asp:ScriptManager>

Now this setup brings the web service into the client side. Before going further, let us test what we have done. To test, I written one method in my service which is as follows,

public string WriteData()
{
	return DateTime.Now.ToString();
}

Now let us test the setup. To test I have taken a simple ASPx page named, Test.aspx and placed my script manager into that. Now placed one label (ASP.NET) and a Button (this is too). Considering my application is referenced to jQuery, I written the following code in my script block,

$(document).ready(function () {
	BusinessObjects.Employee.WriteData(function (result, e) {
		$get("<%=lblDate.ClientID %>").innerHTML = result;
	}, function (result, e) { alert(result.get_message()); });
});

In this code, we can observe how we are calling server side methods. The common syntax will be as follows;

<<NameSpace>>.<<ClassName>>.<MethodName>>(<<Parameters>>, OnSuccess(result, e), OnFailure(result, e));

Here the result in OnSuccess will hold the returned data from web service method in JSON format. If there is any exception while executing the method, then the exception will be captured in the “result” of the OnFailure. To get actual exception details use the member method “get_message()”.

Now this script is going to execute, once the document completed loading and ready for user input. After this for the button, I added the following javascript for the OnClientClick event,

function Update() {
	BusinessObjects.Employee.WriteData(function (result, e) {
	$get(&quot;&lt;%=lblDate.ClientID %&gt;&quot;).innerHTML = result;
	}, function (result, e) { alert(result.get_message()); });
return false;
}

Since it is returning “false” at the end of execution, the click event will not fire for post back. Now run the code and test, the following is the result.

image

Click on the button update to see the updated time. My complete aspx page looks like;

 &lt;%@ Page Language=&quot;C#&quot; AutoEventWireup=&quot;true&quot; CodeBehind=&quot;Test.aspx.cs&quot; Inherits=&quot;ClientSideBusinessObjects.Test&quot; %&gt;

 &lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;

 &lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;
 &lt;head runat=&quot;server&quot;&gt;
     &lt;title&gt;&lt;/title&gt;
     &lt;script src=&quot;Scripts/jquery-1.4.1.min.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
 &lt;/head&gt;
 &lt;body&gt;
     &lt;form id=&quot;form1&quot; runat=&quot;server&quot;&gt;
     &lt;asp:ScriptManager ID=&quot;ScriptManager1&quot; runat=&quot;server&quot;&gt;
     &lt;Services&gt;
         &lt;asp:ServiceReference Path=&quot;~/WCFService/Employee.svc&quot; /&gt;
     &lt;/Services&gt;
     &lt;/asp:ScriptManager&gt;
     &lt;div&gt;CurrentTime:&amp;nbsp;&amp;nbsp;
         &lt;asp:Label ID=&quot;lblDate&quot; runat=&quot;server&quot; Text=&quot;&quot;&gt;&lt;/asp:Label&gt;&lt;br /&gt;
         &lt;asp:Button ID=&quot;Button1&quot; runat=&quot;server&quot; Text=&quot;Update&quot; OnClientClick=&quot;javaScript:return Update()&quot; /&gt;
     &lt;/div&gt;
     &lt;/form&gt;
     &lt;script type=&quot;text/javascript&quot;&gt;
         $(document).ready(function () {
             BusinessObjects.Employee.WriteData(function (result, e) {
                 $get(&quot;&lt;%=lblDate.ClientID %&gt;&quot;).innerHTML = result;
            }, function (result, e) { alert(result.get_message()); });
         });

         function Update() {
             BusinessObjects.Employee.WriteData(function (result, e) {
                 $get(&quot;&lt;%=lblDate.ClientID %&gt;&quot;).innerHTML = result;
             }, function (result, e) { alert(result.get_message()); });
             return false;
         }
	&lt;/script&gt;
 &lt;/body&gt;
 &lt;/html&gt;

In part 2, we will discuss on business objects and accessing them in client side.