June 2007 - Posts
This is relatively straight forward but it took me a little while to figure out since I am just not all that familiar with the MOSS/WSS object model yet. The first thing to know is that MOSS refers to My Links as QuickLinks. Once you know that it makes it easier to find the needed objects. The key to working with QuickLinks is the QuickLinkManager. However before you can create one of these you have to get access to the UserProfile object of the current user.
Start by creating a UserProfileManager and pass in the current server context.
UserProfileManager userProfileManager = new
UserProfileManager(ServerContext.Current);
Next you can use this object to get access to the current user profile. This method can also be used to get other users as well. In this case, the true parameter tells MOSS to create the User Profile in the MOSS store if the user doesn't have one already.
UserProfile userProfile = userProfileManager.GetUserProfile(true);
Now you can finally acess the QuickLinkManager by passing it the UserProfile object.
QuickLinkManager quickLinkManager = new
QuickLinkManager(userProfile);
The QuickLinkManager class has a Create method that takes the title of the page, the URL, which group to use (QuickLinkGroupType.General by default) and the accessibility of the links (i.e. public, private, etc.).
quickLinkManager.Create(SPContext.Current.File.Title,
Page.Request.Url.ToString(),
QuickLinkGroupType.General, null, Privacy.Private);
Hopefully this will help someone out there that needs to implement this functionality. Make sure that none of the values are null (i.e.: Title or Url), because it will cause an exception that does not at all indicate what the actual error is. As always be sure and use CAS on your class as described in my prior post.
So you went through the hassel of creating a new web part and you have written something fairly elaboration that actually makes use of the WSS Object Model only to find that you get a message such as the following:
Request for the permission of type 'Microsoft.SharePoint.Security.SharePointPermission, Microsoft.SharePoint.Security, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c' failed..
Although there is a wealth of samples out there on how to build web parts few I have found actually show you how to install them correctly. There are basically three ways to correct this issue, one of them being the cowboy way. One a sort of ok solution and the last one is the correct way. If you are curious the Cowboy way is to install the DLL of your web part into the GAC. This gives the DLL full trust which is obviously not the way you want to do it. The other way to do it is to create a custom security policy and explicitly give the needed permissions to your assembly in that policy.
However, the last way is the correct way. Looking at the error, you should be able to deduce that this is a result of Code Access Security (CAS). That means it is actually easy to fix. You just need to know what permission to demand. The SharePointPermissionAttribute is what you need. If you need access to the object model, specify ObjectModel = true. There are also a few other permissions you can demand with this but they are not as common. A typical CAS attribute for use with SharePoint would look like this above your class declaration.
[SharePointPermissionAttribute(SecurityAction.Demand, ObjectModel = true)]
Hopefully this helps those out there that need it. I found very little information out there that gave me the exact attribute to add.
Ok, so I thought this was on of those things that goes without saying. You know something that you expect every half decent programmer to know inately, but aparently that is not the case. Do not name your stored procedures with the prefix sp_. Honestly, I thought everyone knew this. Why do you not want to do this? It causes a CacheMiss because SQL Server always looks for stored procedures with sp_ in the Master database. So if you have things named this way, go change them so you don't look like a noob.
Besides, sp_ is considering hungarian notation, so you should know better. Here is some more info on why not to use it as well.
SQL Server Locking caused by compile locks
Since I have Orcas installed, I thought I would give extension methods a try. By now, you have probably heard what they are. They give you the ability to supplement existing objects with your own methods. I'll do a quick example and then I'll tell you about some things I ran into as I was implementing it.
For this example, let's say I want to add a method to int to check if a number is even or not. The first thing to do is create a static class (has to be static and non-generic) along with a static method. The key to telling the compiler that it is an extension method is the use of the keyword this in the parameter list.
namesapce MyExtensions
{
public static MyExtensionClass
{
public static IsEven(this int myInt)
{
return (myInt % 2);
}
}
}
That is all that is necessary to create the extension method. The class can be named anything and is not used in any way, shape, or form when using the extension method. To use the extension method, simply reference the same namespace and use it like it was a native member of int.
using MyExtensions;
...
int x = 10;
bool isEven = x.IsEven();
That is all there is to it. It will show up in IntelliSense and everything. So in implementing extension methods, so far my general conclusion is that it is best to keep them in their own assembly. The reason being is that I had not luck using an extension method in another class in the same assembly. Another thing to keep in mind is that, you do not have access to the private member varaibles of the object that you are extending in this manner (although you can use any of the public properties).
Another thing to point out is that you can even use extension methods with classes that are sealed. For example I added a method to SqlDataAdapter. Some people may like this. Some may not. Overall, I think extenion methods are pretty neat. I'll be interested in seeing the best practices on when it is appropriate to use them an when it is not.
In reading blogs today, I had overlooked this feature and I am not sure what to think about it so I thought I would put it out there and see what you all think. Take the following simple class with a property.
public class MyClass
{
private string myString;
public string MyString;
{
get { return myString; }
set { myString = value; }
}
}
A new feature in C# 3.0, allows you to simplify the syntax to the following.
public class MyClass
{
public string MyString;
{
get;
set;
}
}
Behind the scenes, this stll functions as a property and the C# compiler does in fact generate a hidden private variable. The compiler automatically generates the get/set logic for you. From accessing the class from another object this makes things great and you access these public properties just like you would normally do. However, there is no access to the "hidden" private variable. So from within the class you have to access the public property. This I am not sure if I like. What do you all think?
Want to know how it really works when it comes down to the IL? Read the following post.
C# 3.0 Automatic Properties Explained
One of the feature in Orcas that I mentioned yesterday was the ability to target which version of the .NET Framework it compiles to. Although technically 3.0 and 3.5 are just extensions to 2.0, Orcas gives you the ability to select which one to target. By doing so it filters out project types and things you can't do if you are using a lower version of the framework. For example, it won't compile LINQ statements if you have 2.0 selected.
Since this is the first version that truly allowed framework targeting (technically you can get VS2005 to target 1.1 and 1.0 but its not ideal), I had to give it a try. I needed to compile the Ajax Control Toolkit, so I thought this would be the perfect opportunity to try it out. The first thing I noticed is when I opened the solution it popped open the familiar solution migration wizard. I thought this was odd but then on the next step it pointed out that 2.0 projects would not be converted. So basically it just converted the solution file to a different format.
Once the project was loaded, I built the solution. It compiled just fine. I took my compiled AjaxControlToolkit.dll and copies it to the VM that I needed it on (which didn't have the 3.5 framework or anything) and it worked just fine.
For new projects there is a drop down list on the new project dialog to choose the framework. For an existing project, you can also still change the target framework by going to the properties of that project. On the application tab as shown below, you will see a new drop down list to choose the framework.
So far I am pretty impressed. What this means if that I can use Orcas to work on my 2.0 projects today even though I won't be using 3.5 framework features. The benefit is I get to use the improved designer and I have cool things lke JavaScript IntelliSense. If things don't work out when I am using Orcas, I can always switch back to VS2005 which coexists just fine.