Wednesday, March 05, 2008

Thoughts and best practices around the "Smart Part"

In the last few years i have been meeting with a lot of developers who had just been introduced to sharepoint web part development, and immediately switched to developing using SmartPart. I think it is time for me to write something about it here in the blog to help people decide when and how they should be using that solution.
I want to make one thing clear. I know that Jan Tielens put a huge effort into the smart part solution, and I think the results is fantastic. It is a great example of how one can embed an ascx control in a web part and display it in sharepoint. The addition of ajax connections between two smart parts is awesome, and I applaud it.
But while I appreciate it, and will recommend it as an example of how such things can be done, I don't think starting developers should forgo learning how web parts work and settle down to use smart part out of the box as their development platform.
I will explain.
Another small note - I gave Jan the option to comment on this article, and I am including his remarks, in green.

What is "SmartPart"?


To quote from the official (and quite out of date - Jan: I forgot about the smartpart.info site, thanks for reminding me, I’ll update it immediately.) smart part web site:
"The SmartPart is a SharePoint Webpart that can host any ASP.NET user control. Create your webparts by using the VS.NET designer instead of coding everything by hand!"
Yes- you read it right - it allows you, the frustrated sharepoint developer to create web parts by just dragging and dropping controls on a canvas, just like ASP.NET developers do it! how great is that (note - I am not being sarcastic - it is great).
Why am I saying the site is outdated? because it shows a huge link to gotdotnet, which doesnt exist anymore. The real link should be to the smartpart codeplex project, which does exist and works.
The codeplex project's home page explains that smartpart is "The SharePoint web part which can host any ASP.NET web user control. Create your web parts without writing code!" (Well, one would argue that if you want web parts without code, use SharePoint Designer - but that is opening a completely different discussion)

Smartpart is basically a simple but genius idea - it is a web part, that can host ascx controls inside it. That way, all you have to do as a sharepoint developer is to write the ascx control, and you can do it with the Visual Studio canvas - just drag and drop, and then when you want the web part on a sharepoint page, you load the generic smartpart, and tell it to load the ascx that you want. it supports ajax, and ajax web part connections - which is cool. overall - a cool solution. I totaly respect Jan Tielens, I love his blog, and his U2U CAML Query Builder is the first tool I install on every sharepoint development server I work on (or is it Patrick's?).Jan: U2U CAML Query Builder is created by Karine

Pro

The Pro is obvious -

  1. you gain so much in development time - you just drag and drop on a canvas
  2. you can easily use all the complex web controls and not worry about web part life cycle and binding times and events.
  3. Fantastic if you are a asp.net developer who needs to learn sharepoint development but doesnt really want to.

Con

  1. The biggest con I can see is that people who use smartpart from the start do not learn about web parts and how web parts work.The solutions they create will be run in a wrapper solution and not natively on sharepoint itself. This leads to people developing user controls that require full trust from the web.config and they totaly disregard sharepoint security, resulting in solutions that require you to change the security settings in sharepoint to full trust. (Jan: If people have questions about CAS I usually point them to an old blog post (http://weblogs.asp.net/jan/archive/2005/06/23/414699.aspx), which still works for SharePoint 2007. Bottom line, deploying the SmartPart doesn’t require Full Trust on the server. WSS_Minimal should be fine! Of course it is possible that the user controls you are building will require a higher trust level.)
  2. Another issue is with the fact that at the end of the day, the smartpart is a generic wrapper around a ascx that lies somewhere on the server. Since it is generic, and since deployment of ascx controls do not require administrative priviliges on the server, it can be used to override sharepoint security. In other words - sharepoint trusts smartpart (because it was installed by an administrator) and smartpart gives that trust to any ascx that is on the server. Combine this with the fact that learning developers do not hesitate to give full trust on the web.config without realizing what it does, and you end up with a potential security risk. Not smartpart fault - it is the fault of the developer, but my fear is that the ease of use of smart part will lead to a lot of unsecure solution like this.
    A friend of mine has shown how a person with permissions to create\edit files on the sharepoint machine can use smart part to run unsecure sharepoint code. This can be corrected in the smartpart, if administrators will be able to specify in a configuration file what locations should be considered trusted by smartpart - but that would basically be repeating what .NET framework already does out of the box.
  3. Performance hit.
    SmartPart is a wrapper. It loads another control - meaning it is another layer of code between the user and the end result. Additionaly, To expose the properties of the control it is hosting to the user it is using reflection - performance hit.
  4. Deployment - hard to deploy, hard to debug. I can't tell you how many people who tried to use the smartpart asked me for help on deployment and debugging. Remember, the debugging of problems in your web part now needs to also debug the smartpart code, because the problem may be in the smartpart and not your code.
    Jan: I have to agree with you: debugging a user control (ASCX) with a code behind file (CS) is not as easy as debugging web parts. What I recommend people is to make use of the Web Application project template (available in VS2005 SP1 and VS2008). This will give you a DLL containing the code behind instead of a CS. You can debug that DLL just like you would debug a web part DLL. If you really want to do this in VS2005 (without SP1 or without a Web Application project) you can use precompilation.
  5. Does not support cross page connections, and marginally supports other forms of webpart connections. If you want to support all kind of webpart connections you still need to write your own web part.
    Jan: I’m not sure about the cross page connections (never tried it), but cross page connections won’t work with ASP.NET 2.0 web parts either I think (please correct me if I’m wrong). Of course flexibility comes with a price; there is only one interface implemented which will allow you to send objects between web parts. The result is that the SharePoint UI won’t prevent you from making connections between web parts that can’t work. It will be the responsibility of your code to check if the data that is received is of the correct type etc.

For more info I suggest you read Eli Robillard's blog about What to know about SmartPart, and LoadControl().

So what instead

Ok, so Ishai is a "bloody annoying purist who wants everyone to develop bloody hard web controls and do it all by code". That wont win me any popularity contests!
Well, my first to the question what is my genius recommendation is, "yes! develop a web control like I do". Who needs canvas? by writing the code behind we have total control of what is happening in the webpart, and we dont rely on the canvas to do what we want.

But I understand that this approach doesnt appeal to a lot of developers - and to them I suggest, just develop your own smartpart (you can start from the smartpart code! that is why its there for on codeplex, or read Eli's blog post about the Eli Robillard's blog about LoadControl), but dont make it generic - write it so that it is strongly bound to the ASCX control, and users cant use it to load other controls, or make it so that only a specific folder on the sharepoint machine is trusted by the generic webpart, and make sure that folder gives "write" permissions only for the right people. Performance will still take a hit and deployment and debugging will still be hard but at least you will be (a very small bit) more secure, and in control of what is happening.

PS: I have a friend who claims that Microsoft has a tool that generates web controls out of ASCX controls - he claims that MS used it to create most of the webcontrols that come builtin in sharepoint. I don't know if it's true or not, but if it is I hope that MS will consider publishing that tool - that would be a big step forward towards the developer experience that so many developers want.

Before I end this article, I want to add that I may update this article with more info, since I am sure I will be getting a lot of comments (online or offline) on this article. I hope everyone understands that this is not a flame against Jan and his solution - quite the opposite. I think the smartpart is a magnificent piece of code, that is very useful as an example, but I don't think it should be used without learning how it works and what it means when you use it.
What do you think? comment on this article!
If you want me to respond to you only, you will have to leave contact details, so you'd better do it through the "Email Ishai" link. I hate it when people comment on my article and say "I had a problem doing it - what am I doing wrong" and don't leave personal details how to help them.

4 comments:

Douglas Leung said...

Interesting article Ishai. Two years ago, I asked the question: "Which is better, SmartPart or Custom WebPart"? Actually, when I developed my first SharePoint web part it was using the CreateChildControls() method. It DID actually help me understand how everything in a web part works.

At one stage I came to use Smart Parts (and son of smart parts), and came to see the same pros and cons as Ishai. And yes, back then as a novice, I did have quiet some trouble doing debugging using it, and also at times, it actually made things more complex for development when it came to deploying to environments with restricted trust.

I guess the SmartPart is the generally a good approach for some "quick and dirty" POC's in SharePoint. At some instances, I just created a web part from scratch that hosts ascx (essentially the same principal as SmartParts).

Actually, just like in MOSS 2007, there's the delegate control - which actually sits on OOTB master pages to host other controls like the Microsoft.SharePoint.Portal.WebControls.MySiteLink ascx control. I don't work for Microsoft, neither do I know any insiders, but just from the observation, I know definitely SharePoint uses similar techniques equivalent to the smart part to render ASCX user controls.

I guess as a personal preference however, I would tend to prefer to develop web parts using the CreateChildControls method simply because I feel more comfortable and feel like I have more control.

It would be interesting to see some lab test results on the impact of using SmartParts VS WebParts on Performance, Resources, etc...

Arbon said...

Thanks for the great article.

Do you have any insight as to how to set custom properties of the ASCX control that is living within a smartpart?

IE, i want to set a separate CSS class through a property in the ASCX control... not through the SmartPart... is this possible?

Mark said...

Great post. I have tried to use both methods and find I like the smart part except for the debugging issue. I noticed that Jan says you can use the web application project template to create a dll then you can debug it. I am trying to do this, so I created a web application project created a test web form but where do I putt the dll? I tried putting it in the /usercontrols and it didn't show up in my smart parts list. Do I have to add the dll to the GAC? And if so how would I add it as a smart part?

thanks

dattard said...

@Mark; Recently I had an issue where i needed to debug "Smart Part user controls" but within SharePoint. After some testing and playing around, I figured out a nice clean way to do it: Check it out here:
http://dattard.blogspot.com/2009/11/debugging-smartpart-user-controls.html