[Home] [Recent] [Site Map] [SharePoint] [XBOX]
Okay, I confess that I have been thinking about blogging now for some time, but like everyone I have my excuses. Joel Oleson has convinced me now that I should be part of the SharePoint Blogging Revolution. So I am in. Reading and searching SharePoint blogs have become an almost daily part of my everyday life, and have proven to me to be extremely useful in my team"s development on top of the SharePoint platform.
A little about me. My name is Tom Chmielenski (had to shorten the blog name, if I wanted any visitors) and I currently work for Bentley Systems, Inc (we develop software for the world"s infrastructure.). I am the senior technical lead on a product called ProjectWise StartPoint (this product integrates CAD files (.dgn and .dwg file formats) with the SharePoint platform.). Thus, our integration relies heavy on the OpenDocuments ActiveX Control to accomplish this integration.
But to date, I haven"t heard people talk much about the use of this control with SharePoint 2007 nor have I heard from other third party vendors who want to integrate their file formats to play nicely in the SharePoint environment. Therefore, the goal for me here in this blog is to share what my team has learned (mostly the hard way) in this area. Maybe some day you can help my team out along the way as well.
Before I go farther, let me state the normal disclaimer applies to all postings on my blog:
The information in this weblog is provided "AS IS" with no warranties, and confers no rights. This weblog does not represent the thoughts, intentions, plans or strategies of my employer. It is solely my opinion. Inappropriate comments will be deleted at the authors discretion. All code samples are provided "AS IS" without warranty of any kind, either express or implied, including but not limited to the implied warranties of merchantability and/or fitness for a particular purpose. In addition, nor do my opinions do not reflect those of my blog host, SharePoint Experts.
--Tom
This is one of those cases where I went down several dead ends and spent way too much time chasing after all kinds of reasonable, yet ineffective, approaches, only to collapse in a heap, look up, and see the solution, glimmering above me, all shiny and simple.
The problem at hand: Now that I"ve got a hold of a SharePoint list (SPList) object, and I also have the View I want to use to display this list (SPView), what are my options for rendering?
Stated more clearly: I have a particular View that is configured on the site that I want to use to drive which items, columns, and sort rules are used when I display my SPList. I want to do all this in a loosely-coupled way so that future changes to the site"s view will be reflected in my rendered SPList.
Dead End #1: Bind the SPList to a GridView. This is surprisingly ugly, though it does reveal a lot of details about what"s going on under the hood of the SPListItems. Try it some time just for fun. It"s educational, but not what you want.
Dead End #2: Attempt to create some other object that I can then bind to a GridView. How about a DataTable? Simple enough: build a bunch of columns, then populate the rows. Tried this, would have worked, but the effort to do so was a lot more steep than I"d expected, and it seemed like it would be error prone to continue going that route.
The shiny, simple, hindsight-is-20-20 solution: ahem...
myListObject.RenderAsHTML(myQuery);
d"oh.
Ok, here"s what I ended up doing (roughly, my actual code is sprinkled across several methods, much of the error handling is removed for clarity):
// SPSite = site collection
SPSite mySite = SPControl.GetContextSite(Context);
// You really need to set the following CatchAccessDeniedException = false setting!
// In the event the current logged in user does not have access to the Web
// (or any other resources) you are attempting to open later,
// this prevents SharePoint from automatically redirecting them to a
// "Authorization Required" page. Instead you will throw a catch-able exception
// which is not ideal as the answer to UserHasPermission() but it seems to be
// all we have.
mySite.CatchAccessDeniedException = false; // now we won"t redirect on error
SPWeb myWeb = mySite.AllWebs["sitename"];
SPList myList = myWeb.GetList(SPEncode.UrlEncodeAsUrl("/Lists/MyListName"));
SPView myFavoriteView = myWeb.GetViewFromUrl(SPEncode.UrlEncodeAsUrl("/Lists/MyListName/MyFavView.aspx"));
SPQuery query = new SPQuery(myFavoriteView);
Literal litOutputGoesHere = new Literal();
litOutputGoesHere.Text = myList.RenderAsHtml(query); // easy!
One of the things I have been asked recently has been to do with changing the “Email Link To” menu item. Sometimes this link works, sometimes it doesn’t. Before we can look at changing it let’s take a look at the code that is used to create this link. The code block can be found within the “AddSendSubMenu” function within the “CORE.JS” file. Here is the code block in full:
Now let’s step through it line by line. The first line:
This line is used to check that the current user has the correct permissions, i.e. Permission to the document or item. Next we simply populate the local variable “strDisplayText” with the globally declared variable from the top of the “CORE.JS”.
Now we get to the interesting bits. Each list and library when viewed within the standard pages such as “AllItems.aspx” can be accessed via JavaScript by using some built in functions. One of these is “GetAttributeFromItemTable”. This function is actually called from the “INIT.JS” file; along with a few more that you will see further down the code. This code line is connecting to the table and grabbing the “URL”, which in reality is the direct link to the document or item.
Once we have the actual link then we find the root URL (the server URL) using a built in property of the list item which is referred to as CTX.
Once we have the root URL it is then chopped up slightly, so we have the length, and location of the relevant slashes. The local variable “fileUrl” is also declared at this point, this is used later on. Now we populate the local variable by concatenating the root URL and the variable called “currentItemUrl” which is actually populated previously from the item table.
Now we have the new variable “fileUrl” populated and ready to use, the next variable to get populated is the “serverFileRedir”. This is used to hold any redirection page that is needed as part of the menu item link.
Now that we have all the variables populated the next few lines of code simply build the menu item. The “strAction” variable contains the action that will happen when the relevant menu item is pressed. In this case it calls another function that exists within the “INIT.JS” file. This function simply encodes the relevant URL and does a “window.location” redirect. Notice also in the code we pass auto populate the body of the email with the newly populated variable “fileUrl”.
Next an image is assigned to the menu item. The images used for this are stored here:
C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\TEMPLATE\IMAGES
Now we put it all together using a built in function called “CAMOpt” which exists within the “CORE.JS”. The syntax for this is shown below but let me explain it here:
CAMOpt({menu or parent menu item}, {display name variable}, {code action variable}, {image variable})
Notice that in this example the first parameter is set as “sm”. This is the ID of the “Send To” menu item on the main item menu. Some of the functions refer to the variable called “m”. This is the main menu itself and gets populated from the function called “CreateMenuEx”. In one of the last posts we looked at creating nested menun items. To achieve this we made use of this method. Last but not least it assigns a global ID to the menun item. Thisn is great as you can then create custom CSS styles that map direct to the menu item.
So now we have stepped through the code let’s modify it slightly. One of the errors you sometimes get is caused by the fact that the JavaScript URL Encodes the path before it adds it to the body of the email. An example of this is when the main server URL gets encoded also and makes the link unusable from an email client but works in the browser.
http://intranet%2Elabs%2Elocal/StaffDirectory/Team%20Documents/DemoDoc1.docx
By modifying the code we could make sure that the first part of the URL does not get encoded. The URL would then look as below:
http://intranet.labs.local/StaffDirectory/Team%20Documents/DemoDoc1.docx
To make this work we need to add the following line(s) into the code:
Notice that in this line we are calling a built in function called “UnescapeProperly” around the “httpRootWithSlash” variable and then we are using the “EscapeProperly” around the “currentItemUrl”, both of these functions are called from the “INIT.JS”. Both of these functions simply replace any spaces or special characters with their HTML (ASCII) equivalent. Next we need to tweak the link that is rendered into the body of the email. The first variable “NewEmailLength” simply grabs the item table value called “DREF”. This is used to get the relative location of the item or document. The second variable takes the current item URL and substrings the length from the previous variable which leaves us with the actual name of the file plus the extension. The idea behind this was so the subject would read: “Emailing Document Link: {Document Name}“. The “NewEmailBody” variable is populated by the variable we created earlier called “fileUrlNonEscaped”.
You will also notice that the action variable is calling a function called “CreateMailMessage”. This is a simple function that just does a “window.location” redirect for the email. The function is:
Once it all together when you access the link the email now renders as:
As you can see by using lots of the inbuilt functions you are able to change the way that the default menu items or new menu items work within MOSS2007. As a side not I have just noticed that fellow MVP Ishai Sagi has posted his findings on what all the variables are used for from within the “itemTable”. Check his post here:
http://www.sharepoint-tips.com/2007/05/meanings-of-variables-in-context-menus.html
Hope this helps.Well give a huge pat on the back to MS for really listening to the customers on this one! MOSS 2007 has officially passed the DOD 5015.2 test and will be offering a free add-on for the records management feature. This add-on will enable organizations to run DOD compliact records management solutions.
Get the official word from the SharePoint blog here: http://blogs.msdn.com/sharepoint/archive/2007/05/30/dod-5015-2-certification-for-moss-2007-we-ve-passed-the-test.aspx
Congrats MS that is an awesome accomplishment...
Documentum be afraid be very afraid ![]()
Cheers
Here are some useful SharePoint links. These will be very useful if you are choosing a proper solution for your customer. Here you will find more about SharePoint editions and how much your solution might cost. Microsoft Office
Ok, so you’ve set up your portal, and you’ve created a custom security policy so that you can run web parts without giving full trust to the entire portal. So, you’re ready to start writing web parts, right? Sure, but there is still more that you can do to protect you web parts from attack, as well as protect your portal from poor code – not that we ever write any poor code. J We can still add a little additional insurance with the help of the .Net Framework 2.0 Configuration Tool.
The problem that I have found with creating custom trust policies for my portal is that I have to grant full trust to the assemblies in my portal’s \bin directory. So now I don’t have to worry about my assemblies not having the required permissions, but what about all those permissions that .NET will now grant the assemblies that I don’t need. Also, since they are now running in a fully trusted mode, I can’t even use CAS (code access security) to refuse unwanted permissions.
Let’s step back for a second and take a look at how permissions are assigned to assemblies in .NET. When using the framework (at least in version 2.0), you can’t simply assign permissions (or refuse them for that matter) to an assembly. Each assembly that you create has certain pieces of “evidence” attached to it such as the ones on the following list:
Types of Evidence
· The application directory that contains the assembly
· A cryptographic hash of the program
· Whether or not the assembly is installed in the GAC
· Digital signature of the publisher
· The site where the assembly was downloaded from
· *The strong name of the assembly
· The URL where the assembly was downloaded from
· The zone that the assembly is running in
· Zones include Internet, Intranet, My Computer,
· Trusted and untrusted sites
This evidence is used to assign an assembly to a specific Code Group. Code groups exist to relate assemblies to permission sets, and permission sets are just groups of permissions. The evidence that your assembly contains – such as it’s strong name or web address– can grant membership to more than one Code group, and therefore more than one permission set. If this happens, the assembly receives the union of the all permission sets that its Code groups assign to it. Hope this makes sense so far, but if not there is a lot of information written on the web about this subject.
In order for this solution to work for you, you’ll have to have the .NET 2.0 SDK installed on your portal server. This is a little unfortunate if you’re as pressed for space as I am, but installing the SDK is the only way I know to get access to the .NET 2.0 Configuration Tool, and that is by far the simplest way to create a code group. There is a command line tool that can do the things that I demonstrate here. It’s called caspol, code access security policy tool, but its use won’t be discussed here. Also, in order to use the exact steps that I’m about to outline, you’ll need to provide a strong name for your assemblies. Here’s a good article for strong naming .NET assemblies http://www.codeguru.com/columns/experts/article.php/c4643/#more for those who need help.
Open up the .Net Framework 2.0 Configuration Tool on the machine which contains your portal.
Expand ‘My Computer’ -> ‘Runtime Security Policy’ -> ‘Machine’ -> ‘Code Groups’
Right click ‘All Code’ and select ‘New’
Right click ‘All Code’ and select ‘New’
Select ‘Create a new code group’
Select ‘Strong Name’ for the condition type, click the import button, and then select a web part assembly that has been strong named. The wizard will extract the public key for you.
Check ‘Use existing permission set:’, and then select ‘Everything’ from the drop down. One note here: Everything is not the same as full trust. Everything provides all the permissions to your assembly that it would get from full trust, but this is still considered a partial trust situation and therefore .NET will test the assembly later to see if you want to remove any permissions. If you use full trust, no test will occur.
Now just click ‘Finish’ and your code group is created.
The follow code snippet shows a web part class with unwanted permissions removed:
Hope this helps. :)
Had a need today to programmatically get the outgoing SMTP server that is setup in the Central Administrator. Luckily, I found a sample of how to do this with WSS V3 from the folks at Covelle Corner. Worked like a champ for me!
They use the following code (obvious credit to Covelle Corner for this):
///
/// Returns SharePoint smtp server
///
///
private string GetSmtpServer()
{
SPWebApplicationCollection spWebApplicationCollection = SPWebService.ContentService.WebApplications;
SPOutboundMailServiceInstance smtpServer = new SPOutboundMailServiceInstance();
if (spWebApplicationCollection != null)
{
foreach (SPWebApplication spWebApplication in spWebApplicationCollection) {
smtpServer = spWebApplication.OutboundMailServiceInstance;
return smtpServer.Server.Address;
}
}
return string.Empty;
}
MOSS2007 has passed it"s certification for compliance with level DoD 5015.2. This means that soon you will be able to install an add-in that will bring the world of "records management compliance" closer to the MOSS2007 world. You can read an article about this using the link below:
http://www.cmswire.com/cms/records-management/microsoft-delivers-on-dod-50152-cert-promise-001323.php
Big shout to the Microsoft Guys for this!!! ![]()
In the last article we looked at hiding existing menu items and also adding new sub menu items. In this article we will look at adding our own custom menus and sub menu items within the same framework as before. We will use the same code as last time but build on it slightly. The objective now is to create a new menu at the same level as the “Send To” menu and then add some sub menu items. For this example the sub menu items will simply link to external website addresses. To start with let’s modify the code as shown below:
This code block will add the relevant menus we described above. When you now access the UI the menu items should be shown as below:
We could enhance this slightly further also by adding a simple hierarchy of menu items. In the real world you probably wouldn’t do this as it can be quite complex to use and administer. The code needs to be changed as below:
This will then render as below:
With a little extra JavaScript and a little creativity you can create very complex menu structures with different events that are fired based on the link clicked. The above examples are just some of the things you can do with it. ![]()
Site List:
>>Xbox Live_s Major Nelson
>>Xbox 360 & SharePoint 2007 Weblog
>>Carsten Keutmann_s Blog
>>Mohamed Zaki_s Blog [Sharepoint MVP]
>>The Mit_s Blog
>>Mart Muller_s Sharepoint Weblog
>>Microsoft SharePoint Products and Technologies Team Blog
>>SharePoint Solutions Blog
>>4GuysFromRolla.com Headlines
>>ASP.NET Blogs
>>SharePoint Blogs
>>SharePoint Blogs
>>Joel on Software
>>ADO Guy_s Rants and Raves
>>Microsoft Live Labs
>>GadgetNews
>>Windows Vista Team Blog
>>VoIP & Gadgets Blog
>>schrankmonster blog
>>Via Virtual Earth Blog
>>Feed
>>MSDN Blogs
>>Mashable!
Links:
Jack's Readings
Month Archives:
Oct 2007
Sep 2007
Top Tags:
social software social networking .NET mashable Sharepoint ASP.NET Web 2.0 Web2.0 Startups Community News Search Marketplace General Software Development AJAX Windows Vista Visual Studio Microsoft myspace Silverlight People Powered! YouTube Vista MOSS Featured News C# Events MOSS 2007 Google WPF Office 2007 Web Community Security General Personal Xbox 360 facebook Tools development SharePoint 2007 Fun Atlas Architecture ASP.NET AJAX myspace codes TheLongTail IIS SQL Server Developers Revenue Sharing Video Pictures WCF Mobile 2.0 Announcements Orcas MIX07 Arcade Team System JavaScript News
@2007 All rights Reserved |