Ratko Ćosić - lamentations of one programmer

utorak, 16.09.2008.

Sharepoint Web Part - a friend or foe?

As Sharepoint taken seriously, it seemed cumbersome to code some extensibility code, until I realized there is a possibility to create some programmability inside the SharePoint system and proclaim it a web part.

You can find very good documentation about SharePoint Web Parts here.

Be aware that you can build Web Parts for Windows SharePoint Services 3.0 in two ways:
- Create custom ASP.NET 2.0 Web Parts.
- Create SharePoint-based Web Parts.

We'll make our path to the victory a little bit tougher and make custom ASP.NET 2.0 Web Part!



Imagine you have a client which you would present SharePoint system and tell that it can be customized. Well, it's easy to say it, but more convincing is that you show'em something real. The following example is just one tiny possibility on how to do it.

A developer's side of story:

Firstly, open your dearest tool, Visual Studio, and create a new ASP.NET project, name it arbitrary, and start to edit Default.aspx page. Inside, you'll make one user control contained inside of it, as web part is actually a web user control!

As such, register your web control inside Default.aspx, and fill out the body with the definition of it.
Also, good idea would be to in-line embed the style to this page, because it could be glued to the portal later.
Name it uniquely, because you'll probably have lots of stylesheets already on your sharepoint server.

Next, you should establish some sort of navigation inside of your web control, as this is the actual entry point of user's interaction with the application. Also, note that web part is not intended to be used for building large applications, but rather small ones (typically calling some web service, or providing just entry point to the bigger application).

I created one enumeration of web pages (i.e. controls) which I call, as I have 4 different layouts to show (2 data grids, and 2 entry forms). On Page_Load, the display is been routed on the corresponding content (physically it is done by triggering visibility on and off). And that's it from developer's point of view!

Anyway, keep it simple and miniaturistic, alas you never know how tiny it will be resized on the portal for each user. Consider it a "banner" or "snippet" application. Typically it will display one data view, or couple of user controls (labels, textboxes, and buttons), not MDI or master-details kind a stuff...

An admin's side of story:

As these web parts are integral part of the server, probably the development infrastructure for SharePoint programmabiliy will be installed on a SharePoint server, not on a developer's machine. Therefore, you can make another VS solution (if not exists already), referencing Microsoft.SharePoint.dll and optionally web services you use for these web parts.

There should be couple of files needed this to work:
- a class based on WebPart class (.cs),
- a manifest file occupied arount web part's appearance (.webpart), and
- a stack of files from your development project (if possible, a link to these files).

Firstly, create a new class and derive it from WebPart base class. You need only to override CreateChildControls method of the base class and stuff it with your user control:

protected override void CreateChildControls()
{
base.CreateChildControls();
try
{
Control userCtrl = Page.LoadControl( "/wpresources/MyWebParts/MyWebPart/MyWebPart.ascx");
}
catch (Exception ex)
{
this.Controls.Clear();
this.Controls.Add(new LiteralControl(ex.Message));
}
}

Second file is actually a xml file which contains web part definition and some appearance stuff:

[webParts]
[webPart xmlns="http://schemas.microsoft.com/WebPart/v3"]
[metaData]
[type name="MyWebParts.MyWebPart, MyWebParts,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=c156b4e974af0491" /]
[importErrorMessage]
There is an error during loading of web part.
[/importErrorMessage]
[/metaData]
[data]
[properties]
[property name="Title" type="string"]My Web Part[/property]
[property name="Description" type="string"]testing[/property]
[property name="AllowClose" type="boolean"]false[/property]
[/properties]
[/data]
[/webPart]
[/webParts]

And finally, just paste or link the bunch of files you've already created when you code the stuff. Pay attention to the correct file paths inside the .cs and .webpart files - it's vital.

And you're done!

Making use of AJAX in web part

Wouldn't be great if whole page wouldn't constantly beeing refreshed if I click on some button inside this web part? Well, with a little trick of AJAX, you can do it and impress your boss ;)

From developer's side, nothing has to be changed. Only thing you should include is UpdatePanel into the web part class (MyWebPart.cs), and it would look like this:

public class MyWebPart : WebPart
{
protected override void CreateChildControls()
{
base.CreateChildControls();

try
{
this.EnsureUpdatePanelFixups();
UpdatePanel up = new UpdatePanel();
up.ID = "MyUpdatePanel";
up.ChildrenAsTriggers = true;
up.UpdateMode = UpdatePanelUpdateMode.Conditional;
this.Controls.Add(up);

Control userCtrl = Page.LoadControl( "/wpresources/MyWebParts/MyWebPart/MyWebPart.ascx");
up.ContentTemplateContainer.Controls.Add(userCtrl);
}
catch (Exception ex)
{
this.Controls.Clear();
this.Controls.Add(new LiteralControl(ex.Message));
}
}

private void EnsureUpdatePanelFixups()
{
if (this.Page.Form != null)
{
string formOnSubmitAtt = this.Page.Form.Attributes["onsubmit"];
if (formOnSubmitAtt == "return _spFormOnSubmitWrapper();")
{
this.Page.Form.Attributes["onsubmit"] = "_spFormOnSubmitWrapper();";
}
}
ScriptManager.RegisterStartupScript(this, typeof(AjaxUpdatePanelPart), "UpdatePanelFixup", "_spOriginalFormAction = document.forms[0].action; _spSuppressFormOnSubmitWrapper=true;", true);
}
}

Ah, yeah. I forgot to mention, there is a nasty trick used to override the submitting of the whole page (portal page) on Submit button of web part. In that case, if user presses a Submit button on MyWebPart, the form will not be submitted, but rather just the contents of the web part only.


- 14:06 - Comments (0) - Print - #

<< Arhiva >>

Creative Commons License
Ovaj blog je ustupljen pod Creative Commons licencom Imenovanje-Nekomercijalno-Dijeli pod istim uvjetima.