Thursday, 16 October 2008

Chrome crashed


In fact I thought Chrome would never crash when one of the tab got screwed since there was this concept of each tab executing within a
different process.  A behaviour easily verified by browsing to about:memory and cross checking the PID with the windows process ID.

Sadly this near perfect browser crashed today :(











Should have noted down the steps that caused this. Have now enabled chrome to generate crash dumps as detailed here

While you are here, also check out chrome's process model here

Sunday, 12 October 2008

WCF Service and a SilverLight 2 beta 2 Application

While trying to call a simple WCF service from a silverlight application, not everything goes smoothly from within VS 2008. Though coding itself did not take more than half an hour, to hack the stuff to work good took me around a day.
You would usually require to get past the following hurdle's:

1.) The default binding for the WCF service appears to be secured - wsHttpBinding, which is not currently supported by silverlight. This mean editing the web.config to use basicHttpBinding instead.

2.) Even if the WCF service project and the silverlight application is in the same solution, you would not be able to call the WCF service directly since silverlight does not support cross-domain calls. This appears to be a security check from the silverlight end. To get past this, you would have to specify that both the project (WCF and the silverlight host web application) to use the same virtual directory from the project properties (check the 'Use IIS Web Server' under project properties, web tab). 

In my case, I used "http://localhost/NumberService" for the WCF service and "http://localhost/SilverLightApplication1Web" for the web application.

The above changes should get the silverlight to successfully call the WCF service from within the VS 2008 IDE. Incase you still get cross-domain errors say when your WCF service is on a different host, host the web applications directly under IIS and make sure you have created a 'clientaccesspolicy.xml' file in the root of the virtual directory with the following content :

<?xml version="1.0" encoding="utf-8"?>
<access-policy>
  <cross-domain-access>
    <policy>
      <allow-from http-request-headers="*">
        <domain uri="*"/>
      </allow-from>
      <grant-to>
        <resource path="/" include-subpaths="true"/>
      </grant-to>
    </policy>
  </cross-domain-access>
</access-policy>

The above bit just makes sure that cross domain access is allowed from all URLs (check out the allow-from tag). I could not get this to work while debugging from within the VS IDE though.

If you are still having trouble making cross domain calls, the easiest option is to create a proxy webservice within the same domain as the web application. This proxy webservice can make the actual call to the webservice on a different domain.

3.) When trying to host the silverlight web application under IIS, you might get an IIS error about unknown MIME type 'xap'. In this case, just create a new entry under the MIME types within IIS for 'xap' as 'application/x-silverlight-2-b2'

4.) Strangely, once you have setup the above two projects, VS 2008 fails to load later when you try to reload the solution. It fails with a System.Runtime.InteropServices.COMException each time. The only way to get past this while making sure that the solution loads good is to load VS 2008 under the administrator credentials. From Vista, right click on the VS 2008 shortcut and click on 'Run As Administrator'

Further Silverlight Notes:
1.) Starting Silverlight 2 beta 2, It is quite easy to get a simple timer to work under Silverlight 2 beta 2. Just use the System.Windows.Threading.DispatcherTimer class.

2.) All calls to the WCF service is by default async. The service reference within the silverlight application always generates an async reference (the one with the 'Async' suffic to the method)

Sunday, 9 March 2008

Bounce that spam please!

Looking at the number of spam emails (approximately 3 spams for 1 good email!), something needs to make sure that the same sender does not send a different spam. To handle this, we could have an auto-bounce feature such that once a spam is marked manually for auto-bounce, the next spam from the same user results in an 'invalid email-address' or 'inbox full' kind of messages.

The only issues we might face:

1.) This involves the mix-up of user-requirement with the underlying protocol!. No purists would like this.

2.) The spam-generators would start getting intelligent in sending spams - It might start using different 'from' addresses and messages against the same Inbox. If either of the email was delivered, it can safely assume that the email-id is valid. This could be resolved by letting the email-server perform auto-bounce using the same logic it uses currently for spam, rather than explicitly marking it for an 'auto-bounce'.


3.) In cases of the server automatically handling it, we might loose a couple of good emails since it was identified as spam and got auto-bounced.

Can this work ? How else can I avoid that spam from reaching my email box and avoid skimming through the hundreds of spam in search of that one good-email ?

Wednesday, 5 March 2008

Injections

Dependency Injection:

Dependency Injection refers to the process by which functional components ('concerns' in AOP terms) are induced into an object such that the object could use its functionalities. Say, you had a Customer Management module and one of the function it does was audit the name of all users who updated a customer record. On the simplest terms, we might have the following classes :


MyBusinessObject - A base class for each the business entity classes.
Customer - The business entity containing the customer details - name, DOB, Address etc. This being derived from MyBusinessObject.
CustomerManager - Manages all business functions related with the customer. Say, adding customer, deleting, searching, modifying etc
MySimpleAudit - A class which does the audit the various operations.

In simplest case, CustomerManager class would directly instanstiate the MySimpleAudit class and call the appropriate Audit function. All good. If we have more Audit classes , say StackTraceAudit (which audits the stack trace too..why? I dont know), ObjectStreamAudit (Audits the current state of the object) , the standard design logic would call for interfaces to separate the functionality out, in our case perhaps into an IAudit interface.

IAudit
AuditDelete(MyBusinessObject)
AuditCreate(MyBusinessObject)
AuditModify(MyBusinessObject)

We would then make sure that all our Audit classes (MySimpleAudit, StackTraceAudit, ObjectStreamAudit) implement this interface. The only confused class is the CustomerManager class which does not know which IAudit implementing class to use. Ofcourse it could depend on a configuration entry to get the audit class name or it could just hard-code to use one of the class etc.

What if we could tell directly to the CustomerManager which audit object to use ? The crux of dependency injection is this . Injecting an object (IAudit Instance) instance into another object (CustomerManager) such that the injectee (the object that got injected! sic indeed) can use the functionality of the injected object (IAudit instance).

You could pass the instance of the injected object in three standard ways as part of the constructor , use a property or use an interface definition.

For our customer example, passing the object via a constuctor would be in the lines of :

class CustomerManager
{
private _audit IAudit;
CustomerManager (audit IAudit)...

DeleteCustomer(Customer customer)
{
_audit.AuditDelete(customer as MyBusinessObject)
}
}

In this case, when the CustomerManager class is instantiated, the right audit instance is passed along - eg :- new CustomerManager(new StackTraceAudit)

Stuff noted:
1.) CustomerManager is not disturbed for any changes/additions to the IAudit implementation
2.) Any new IAudit implementation class can be created without affecting the consuming class.
3.) What is depicted is effectively an 'Inversion of Control'. The control of locating, creating of the audit class being inverted to a different object.
4.) This pattern decouples the logic of - which object, from where etc out from the consumer object.


Policy Injection

For the similar scenario as above, assume you had a single Audit object consumed by CustomerManager. Now if there is a new requirement to include the functionalities of StackTrace, ObjectLogging too into the audit system, what would you do?


Though there are numerous immediate solutions to get the stuff working (modify existing Audit class to call the other audits as well, create yet another master class which calls all the audit objects etc), Policy Injection calls for creating a proxy object class for the currently available Audit class. It would be this proxy class which gets used by at the CustomerManager object instead of the Audit object.

The CustomerManager object might end up using a Factory pattern or a dependency injection pattern (!) to get the right proxy audit class (reread this line again till it makes sense.)

Now interestingly, what the Audit proxy object class would perform is this:
1.) On the way in (when the request for audit happened) , it would call the 'Pre' step routines of all registered audit handlers (StackTrace, ObjectStream etc) in a sequence and finally call the original Audit class routines.
2.) On the way back (when the request for audit is done), it might call further 'Post' step routines on each of the handlers in the reverse order.

As seen, from the point of view of the CustomerManager, it is dealing with only one object, which is the new Audit proxy object. Whenever it calls the proxy Audit class to audit, all the handlers would perform its audit (either in the pre/post routines) and finally call the original Audit object.


Monday, 3 March 2008

Revisting Workflows in Sharepoint - Part 2

Creating workflows using Sharepoint Designer
It should be noted that any workflow you create using Sharepoint Designer is effectively a sequential workflow, wherein you define the sequence of the steps to be performed. Each step being composed of actions and conditions. Any new functionality would require you to create new custom activity in VS.NET and deploy it as an action such that it could be used from within Sharepoint Designer.

Some of the stuff noted in case of sharepoint designer (SD) :
a.) It does not allow for coding/scripting. The best you can define are rules.
b.) The association with a list/library/content type is done immediately when the workflow is first created.
c.) Unlike workflows created in VS.NET, SD does not allow for modification of active workflow.

Breaking out from SD
In case the limitations of sharepoint designer gets on your head, you might want to export the workflow from sharepoint designer to VS.NET. For this :

a.) Export the workflow as an FWP from within the designer.
b.) Rename .FWP to .CAB.
c.) Extract the .CAB file.
d.) Open the extracted .XOML, rules and other files from within VS.NET.


VS.NET namespaces
In addition to the activities which WWF provides, MOSS adds onto this list by enhancing the Base Activity Library (BAL) using custom activities. These activities are available in Microsoft.Sharepoint.WorkflowActions & Microsoft.Sharepoint.Workflow.

Interaction Points
From a developer perspective, there are usually four points in the life of a workflow task when the end user can interact with the workflow. Effectively, its these four interaction points that can be handled/customised by the developer.

Association : When the workflow template is associated the first time with a library/document/content type.
Initialization : When the workflow instance is initialized/created.
Completion : When each user completes their task/step.
Modification : When the workflow itself is modified.

All of the above interactions require you to create custom ASPX pages (for both WSS and MOSS). In case of MOSS, you also have the option to create these forms in InfoPath, which tends to be a lot easier to develop. The table at this blog should clear up any queries regarding which event to handle at each of the interaction points.

Developer Notes
1.) Unlike a WWF workflow, the base class the sharepoint workflow is either SharePointSequentialWorkflowActivity or SharePointStateWorkflowActivity based on your workflow type (sequential or state).
2.) OnWorkFloActivated needs to be first activity for a sharepoint workflow.
3.) Correlation Token (we had discussed this in an earlier post) needs to be set the same for the related activities.
4.) In WWF while you must have used ExternalDataExchangeAttribute , in MOSS most of the data exchange stuff is handled internally. (Is this a right assumption ?)
5.) DependencyProperty makes it simpler to access workflow object properties which are available after activation.

Wednesday, 27 February 2008

Revisting Workflows in Sharepoint - Part 1

There are quite a few stuff which remains to be talked about workflows in Sharepoint, the ones we did not cover in the earlier posts (filter the blog posts by the WWF tag). Lets revisit some of these in this post.

We now know that workflows act as a facilitator for automating system (including human) interactions and let you define the business process. WWF being the framework provided by Microsoft for building these workflows using the concept of Activities. Note that WWF itself could be hosted in many possible environments, ranging from a .NET console application to a service.


In case of MOSS, the WWF is hosted within the MOSS environment. MOSS also appears to have replaced the following core WWF services within WWF to its needs - transaction, persistence, notification, roles, messaging. While using WWF workflows in MOSS, the idea is to link the workflow template which we created using WWF with either a list/document type or content type as the first step. Once this is done, instances of these items (documents/list/content type) could trigger off a workflow instance (based off a workflow template).

You could configure MOSS to create a new workflow instance when either of the following happens:
a.) Automatically, say whenever an item is added to the library
b.) Manually start the workflow against an item instance
c.) Or start the workflow by writing code.

In MOSS terms, the flow of work is notified to the user by using 'tasks'. User tasks gets shown up in their tasks list and also against the item's task list. You would usually configure to sent email notifications to the user simultaneously when the task is created. Completing one task might create further tasks for different users in normal scenarios.

OOTB Workflows and Office Support

Out of the box, MOSS provides workflows (Signature collection, feedback collection, translation management etc) which could be used with minimal configuration. Do note that WSS does not provide these OOTB workflows, though it should not be difficult to create one.

The name change from sharepoint server to MOSS and the related integration with Office 2007 based systems are quite extensive. You can now create MOSS workflows against new documents in MS Word, synchronise MOSS tasks against outlook tasks such that most/all of the workflow related actions can be accomplished from within the office 2007 systems, without ever visiting MOSS portals. Do note that to exploit Office 2007 systems, you would need to make sure that the interacting pages in MOSS are created in InfoPath.

In the next post while we revist more into workflows in MOSS, lets have a developer perspective.

Tuesday, 26 February 2008

Webparts in MOSS 2007 - Part 4

The examples we have seen until now talks about webparts that worked independently (and good :)). Assuming we need to get two webparts to talk with each other, you need to follow this :

1.) Setup a data object interface which would be shared by the two webparts.
public interface ISharedData
{
string data { get; set; }
}

2.) On the source/provider webpart, perform the following actions :

a.) Implement our data object interface. The below sample returns the value from a text field.
string ISharedData.data
{
get { return txtData.Text; }
set { txtData.Text = value; }
}


b.) Setup a connection point which the consumer object can use. For this, use the ConnectionProvider attribute.
[ConnectionProvider("Sample Shared Data Provider")]
public ISharedData GetCommunicationPoint()
{
return this as ISharedData;
}

3.) On the consumer webpart , access the connection point (and effectively the shared data) by implementing a method which is marked with the ConnectionConsumer attribute.
[ConnectionConsumer("Shared Data Consumer")]
public void InitializeProvider(ISharedData provider)
{
SharedData = provider;
}


Note that the argument of this custom method is set to the shared interface. When MOSS calls this routine (since we have used the ConnectionConsumer attribute), the parameter provider would be set to the source webpart's interface. Save this value in a local variable for later usage.

Do note that the value maintained in the above private variable was available for usage ONLY the PreRender function of the WebPart. Is it because I have not saved it in a session object ?

protected override void OnPreRender(EventArgs e)
{
if (_sharedData != null)
{
/*use the shared data*/
lblData.Text = "Data from other web part = " + _sharedData.data;
}
}

Anyways, the above bits should get you started with inter webpart communication. Once you have deployed the above two webparts, use the design mode of the zone to setup the source and destination connections.

Note that for intra-webzone webpart communication, things appear to get a bit different. I havent tried it, but you would need to start with changing the parent class for the WebPart (mentioned in Part 1) .

Webparts in MOSS 2007 - Part 3

We might have user customisable properties within our webpart which we think could be customised during design time. Here design time means the mode when you add the webpart into the appropriate webzone from the webpart gallery. At this point, all properties which had the WebBrowsable attribute set (check out Part 1) are available for customization.

For simple properties (say integers/string etc), MOSS automatically renders the editors for you. It even figures out the enumerations and renders the appropriate listbox..all good. For properties which need customisation, say you need to list down custom values from a DB, you would need to create a custom editor class separately and map it within the webpart.

Steps
1.) Create the editor object for the webpart

a.) Create a new class deriving from EditorPart class and create any control which you would need to use by overriding the CreateChildControls(), similar to the way we created child controls for WebParts.

b.) Now listen carefully. When we think about the Editor which would be shown, there are two important data handling instances - when the editor is shown the first time, we would need to load the currently set value in the webpart and when the editor value is applied/saved, we need to save the selected value back to the webpart.


To handle these two instances, we need to override the SyncChanges() and ApplyChanges() routines. The WebPart being edited at these points is available using the WebPartToEdit property.

Thats it, the webpart editor is ready. What is remaining is linking this editor with the WebPart.

2.) Link the editor with the WebPart.
Our WebPart needs to implement the IWebEditable interface to tell MOSS that it supports custom editors such that the right editor gets shown when our webpart is selected.

IWebEditable requires one method and one get property to be implemented:

Method CreateEditorParts - Override this method to specify all the editors which you need this web part to use (havent tried with more than one). It is at this routine we add our custom editor which we just created and return the editors list.

Property WebBrowsableObject - This expects you to return the current webpart which is currently being edited. (simplest to implement I guess :) )

Once we have the above two steps done, we are nearly done with the editor. Following is a code snippet for a quick look:


public class CustomEditorWebPart : WebPart, IWebEditable
{
private string _reviewer;

public string Reviewer
{
get { return _reviewer; }
set { _reviewer = value; }
}

#region IWebEditable Members

EditorPartCollection IWebEditable.CreateEditorParts()
{
List<EditorPart> editors = new List<EditorPart>();
editors.Add(new ReviewerEditor());
return new EditorPartCollection(editors);
}

object IWebEditable.WebBrowsableObject
{
get { return this; }
}

#endregion

protected override void Render(HtmlTextWriter writer)
{
writer.Write("Reviewer : " + Reviewer);
}
}

public class ReviewerEditor : EditorPart
{
private ListBox myListBox;

public ReviewerEditor()
{
ID = "ReviewerEditor";
Title = "Edit the Reviewer";
}

protected override void CreateChildControls()
{
myListBox = new ListBox();

myListBox.Items.Add("John");
myListBox.Items.Add("Thomas");
myListBox.Items.Add("Bipin");

Controls.Add(myListBox);
}

public override bool ApplyChanges()
{
EnsureChildControls();
CustomEditorWebPart oPart = (CustomEditorWebPart) WebPartToEdit;
oPart.Reviewer = myListBox.SelectedValue;
return true;
}

public override void SyncChanges()
{
EnsureChildControls();
CustomEditorWebPart oPart = (CustomEditorWebPart) WebPartToEdit;
myListBox.SelectedValue = oPart.Reviewer;
}
}




Next time lets look at inter communication between webparts :)


Webparts in MOSS 2007 - Part 2

In the first part, we talked about creating the simplest of WebPart and the classes of concern. This time, lets render something meaningfull in our webpart. How about the list of all the users in the system ? We would be using the MOSS libraries to get this information.

Steps
As usual, create a blank class derived from System.Web.UI.WebControls.WebParts.WebPart and override the render method as :

protected override void Render(HtmlTextWriter writer)
{
writer.Write(GetHTML());
}

private string GetHTML()
{
string result = "<table border=\"0\">";
try
{
ServerContext context = ServerContext.GetContext(Context);
UserProfileManager profileManager = new UserProfileManager(context);
foreach (UserProfile profile in profileManager)
{
if (profile.PublicUrl.AbsoluteUri != null)
{
result += "<tr><td><a href=\"" + SPEncode.HtmlEncode(profile.PublicUrl.AbsoluteUri) + "\"/>" +
SPEncode.HtmlEncode(profile[PropertyConstants.AccountName].ToString()) + "</a></td></tr>";
}
}
result += "</table>";
}
catch (Exception ex)
{
result += "<tr><td>" + ex.ToString() + "</td></tr></table>";
}
return result;
}


As seen, the GetHTML function returns the HTML string which needs to be rendered at the Render() function. GetHTML uses the server context together with the UserProfileManager to get all the user profiles in the Sharepoint system. In addition to this, we have rendered a link for each of the user such that it takes you to the home page of the user.

You would need to include the following namespaces in the 'using' section if not already done : Microsoft.Office.Server, Microsoft.Office.Server.UserProfiles, Microsoft.SharePoint.Utilities, Microsoft.SharePoint.

Follow the either of the two steps mentioned in the previous post to register this webpart on the server and test it out.

More rendering with data from the DB

Lets create another WebPart which renders data from the DB onto a DataGrid. The core idea remains the same. You perform the render on the items that you know and for your child controls (DataGrid, Label etc), you ask them to render themselves.The crux of the code is contained in the following :

protected override void Render(HtmlTextWriter writer)
{
EnsureChildControls(); //makes sure the child control were created

LoadData();

writer.RenderBeginTag("table");

writer.RenderBeginTag("tr");
writer.RenderBeginTag("td");
lblSubmit.RenderControl(writer);
writer.RenderEndTag();
writer.RenderEndTag();

writer.RenderBeginTag("tr");
writer.RenderBeginTag("td");
gridProductList.RenderControl(writer);
writer.RenderEndTag();
writer.RenderEndTag();

writer.RenderEndTag(); //end table
}

protected override void CreateChildControls()
{
base.CreateChildControls();

lblSubmit = new Label();
lblSubmit.Text = "Employee List";
Controls.Add(lblSubmit);

gridProductList = new DataGrid();
Controls.Add(gridProductList);
}


Note the usage of RenderBeginTag and RenderEndTag which generates the matching start and end tags. Within each of the tags, we render the specific control. As seen, the DataGrid (gridProductList) gets rendered in the appropriate table column within a html row.

LoadData() function referred in Render() basically loads the data into the DataGrid using standard data access calls. Any child control the webpart uses should desirably be created at the CreateChildControls method. Though we might as well do this when the WebPart gets created, writing it here ensures that EnsureChildControls() call it when required.

I hope this gives you a gist of how WebParts are created and used. In the next parts, we shall see about Custom Editors and inter WebPart communication.

Monday, 25 February 2008

Webparts in MOSS 2007 - Part 1

Webparts can be considered as reusable widgets (similar to the yahoo ones) which work independently (though they can communicate) and are individually configurable. This makes the task of showing up of different logical sections on the same web page easier; especially while doing independent development. Brought out initially with Sharepoint 2003, it was supported in ASP.NET extensively and now in MOSS 2007 .

OOB WebParts
Out of the box, MOSS provides you with numerous webparts which could be used with minimal configuration. You would want to check out the webpart gallery which list down these.

Some of the interesting O
OB webparts :
Image Webpart : To display images from sites/from another webpart

Site Aggregator : To display sites of your choice
RSS Viewer : To get feeds from any RSSContent Query : To display a content type.
Business Data List : List from LOB/Webservice configured in BDC

Development Concerns
As soon as you start to swim through webpart documentations, you are faced with the dilemma of two parent WebPart classes which provide more or less the same functionality. Which one do you use? From what I could figure out, System.Web.UI.WebControls.WebParts.WebPart is the most commonly used for WebPart development and the simplest.


The immediate descendant class defined in Microsoft.SharePoint.WebPartPages.WebPart was intentionally provided for compatibility with Sharepoint 2003 and also for performing complex webpart functionalities which include cross page web part communication, communication between webparts not in the same webzone, data caching etc.

The good part is, if you use the System.Web.UI.... WebPart, you could reuse the webpart in an ASP.NET application too, assuming your webpart does not have any MOSS specific calls. To summarise, stick onto the System.Web...WebPart for most of your regular requirements .


Classes of concern
WebPartManager - Microsoft (and now me) loves manager and provider classes. In this case, WebPartManager acts as the point of entry to access the various features of the various webparts in a page. This means that there is exactly one WebPartManager for a webpage. If you are using the masterpage provided by MOSS 2007, this would mean that the WebPartManager is already available to you (things get different when you do plain ASP.NET development)


WebPartZone - This is physical place/zone on the page where WebParts reside.

Writing the first WebPart

Now that we are decided on the parent webpart class to use for our WebPart, the main job we have is to tell what needs to be rendered. Simple enough, override the render function :)

public class MyFirstWebPart : System.Web.UI.WebControls.WebParts.WebPart
{

private string displayText = "MOSS Rocks";

[WebBrowsable(true), Personalizable(true), FriendlyName("Display Text")]
public string DisplayText
{
get { return displayText; }
set { displayText = value; }
}

protected override void Render(System.Web.UI.HtmlTextWriter writer)
{
writer.Write("Typed Text is " + displayText);
}
}


OK, so who is going to talk about the attributes? Here goes:

WebBrowsable - makes sure that this property is listed in the property editor when the WebPart is configured.

Personalizable - Setting a value of true on this attribute makes sure that the property value is maintained for individual users.
FriendlyName - The easiest of the lot, this displays the friendly text for this property in the property editor.

Deploying a WebPart
There are two ways to deploy a webpart to the server :
a.) Direct copy/register Copy the WebPart dll to the _app_bin of your application and mark the assembly as safe in web.config. There you go, WebPart is all setup in your current application and ready to use.



b.) CAB This is the recommended way to deploy webparts in the live environment. What you do is create a DWP (dashboard web part) XML file together with a manifest file, wrap it up in a CAB project. Use this CAB project together with the stsadm command line tool at the server to register your WebPart. Check out more about DWP files here.

In the next post, we shall look at rendering some meaningful stuff at the render method, Property Editors, Inter Communication between WebParts.