Update your feed to point to www.wssguy.com/blogs/dan

My blog has moved to www.wssguy.com/blogs/dan.  It has not disappeared.  As a matter of fact, I plan on blogging more than ever before.  I had taken quite a break from blogging over the last few months but it was mainly due to me being inundated with project work at my current client.  That work has slowed down somewhat, deliverables have been or are being delivered so I am now able to dedicate some time to doing what I really love, and that is sharing my experiences in and around SharePoint as a development platform with the community as a whole.

The feed url remains the same: http://feeds.feedburner.com/Attis

I also wanted to take this opportunity to thank both Brendon and Matt for graciously supplying me with this space over the last few years.  It was here that my blogging life actually began.  I don't expect this site to be taken down or to go away anytime soon, but if it does I am sure I will be given the opportunity to move my content off to my new blog, which I plan on doing over time anyways as time permits.

Posted 10-29-2008 by Dan Attis
Advanced Developers SharePoint 2007 Training

There are a ton of training opportunities out there today for SharePoint.  Sahil Malik, one of my SharePoint MVP colleagues and most excellent speaker, will be conducting a week of some serious advanced training, including things like Windows Server 2008, SQL Server 2008, Visual Studio 2008, IIS 7, .NET 3.5, WCF, Silverlight, LINQ and Entity Framework and how they all related to SharePoint.

This is aimed at advanced developers and is being held in NORWAY.  That's right, NORWAY.  So in between session you can enjoy the Scandinavian luxuries, like snow, snow and more snow.  You can get additional information here, http://blah.winsmarts.com./2008-6-Advanced_Developers_SharePoint_2007_Training_in_Norway.aspx, and as an added bonus, see a mug shot of Sahil as well.

Free SharePoint Training by Microsoft

Microsoft is stepping up and providing free SharePoint training webcasts to those who want it on 10 critical developer tracks.  On top of that they are asking for feedback on what they can do better to provide more great content to the SharePoint development community.  Check out this blog post (http://blogs.msdn.com/sharepoint/archive/2008/05/20/developers-developers-developers-sharepoint-wants-you.aspx) to learn more.

The content should be excellent since it is being delivered by 2 awesome SharePoint MVP's, Andrew Connell and Robert Bogue.

Instant SharePoint GAC deployment gratification

Often times, while working on SharePoint projects, I find myself needing to deploy only the code.  I don't care about the Feature .xml files, or any of the other wonderfully useful files in a typical SharePoint project.  Up until today, deploying this code was either a Solution upgrade, or launching a command file containing only the gacutil command along with an application pool recycle.

What prompted this post was that my current project contains multiple Visual Studio Solutions and each of those contain multiple Projects.  Neither of the above two methods are very efficient since Solution upgrades take forever, and switching directories or having multiple command windows open at the same time is not manageable.

Visual Studio External Tool to the rescue!

You will need to create a command (cmd) file that contains the commands you want to launch using the External Tool.  In my case, my file contained the commands listed below.  Don't worry about %1 and %2, those are the arguments that will be supplied by the External Tool when we create it and are outlined below.  Essentially, all this is doing is adding a folder to the PATH so that gacutill can be called, it's then calling gacutil to place the assembly into the GAC.  The last line is recycling my application pool for my SharePoint site.  This last line is optional.  I needed it, you may not.

@set PATH=C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin;%PATH%

gacutil /i %1 /f

C:\WINDOWS\system32\cscript.exe C:\WINDOWS\system32\iisapp.vbs /a %2 /r

It needed to work across multiple projects and be contextually aware of the current project that I am working in so that it can deploy the assembly for that project.  The solution was to create an External Tool to do this for me.

Under the Tools menu in Visual Studio, there is an External Tools... menu option.  Clicking that gives you the External Tools dialog.  Clicking on Add will add a new empty tool to the listbox.

Give the tool a tool a name, I named mine "Deplo&y Code Only".  The ampersand in the name simply assigns a keyboard shortcut to this command (the best part in my opinion), as I will be able to launch this by simply clicking ALT-T-Y.

In the command textbox, enter the command you want to call.  At first I was not sure that what I wanted to do was possible but after some experimenting, I found out that it was.  What I mean here is that if you click on the buttons beside the Arguments or Initial Directory textboxes you will see that they bring up a list of possible macros you can use that provide dynamic references to places you care about, like the current project root folder, the current output path, etc...  This button is not available next to the Command textbox.  The macros ARE however usable in that textbox.  My DeployCode.cmd is always at the root of my project but I don't want to have to create a new External Tool for every project.  That would be silly.  By using the $(ProjectDir) macro, I always get a reference to the root of my project.

In the Arguments textbox I am passing in the assembly path and the name of my application pool, since I am recycling it at the same time (this second argument is optional).  The cool part here is that it will use the Debug or Release version of the assembly here depending on the Build Configuration you have selected in your project.

The Initial Directory textbox tells the External Tool to run in the project directory for the command.  This is not required in this case.

I also checked the Use Output window checkbox so that I can see the output inside the Visual Studio environment.

 

image

 

This has made my life quite a bit easier since now it takes me about .5 seconds to deploy only the code for my project.  I hope you find it as useful as I did.

Forms Based Authentication - Application Pool Account Permissions

Early last year, I posted a couple of articles on how to setup Forms Based Authentication (FBA) in Windows SharePoint Services (WSS v3).

Here are the links:

FBA Walkthrough Part 1

FBA with MySites Walkthrough Part 2

Many people have used this to setup FBA in their environments successfully.  One of the most common issues that come up with many people is that they are not able to resolve users even though the web.config files are configured correctly.  The primary reason ends up being that the Application Pool account for either Central Administration or the Web Application in question has not been granted the appropriate permissions inside of SQL Server to access the membership information.  I referred to this step as the magic step in my earlier posts, but never documented it.  Well the time has come to document that step, so here it is.

I am documenting this for SQL Server 2005.  The same thing can be accomplished in SQL Server 2000, albeit the steps and screen shots will be different (obviously).

As mentioned in my previous post, you will need to run aspnet_regsql to setup the membership database.  This is documented nicely in FBA Walkthrough Part 1

The previous article stops there however and did not discuss permissions.  In the following steps, I assume that the database you created is called "AspNetDb_www.yourwebapplication.com".

Open up SQL Server Management Studio.  When presented with the Connect to Server dialog box, make sure the Server type drop down is set to Database Engine as indicated in the following screen shot.

image

Expand the Databases node and locate your membership database.  Then expand your membership database node, then the Security node within it.

image

Right click on the Users folder and select New User from the context menu.

image

The Database User - New dialog will appear.  Click the Browse button next to the Login name text box.

image

In the Select Login dialog, enter the object name you wish to grant access to.  Let's begin with the Central Administration application pool account.  Keep in mind, your account name will most likely be different than mine.  In my example, I browsed for and located my Central Administration application pool user named moss\ossservice.  Click OK after confirming it via the Check Names button.

image

Enter a User name that will map to the NT Login name.  I use the same name as NT minus the domain portion.  Next, in the Database role membership section, check all of the of the Role Members prefixed with aspnet_.  It is possible that all of these role members are not needed, but I have not taken the time to determine the minimum set of permissions required for this to work.  If someone has tested this and would like to share that information, please do.  This is still a whole lot better than making the application pool account a db_owner!

image

Repeat the process with the application pool account for your web application.

Keep in mind that on a development machine these may very well be the same account, but in production, I would hope that they are not.  That would be bad, very bad.

I hope this helps clear up some of the confusion around my previous post.

Happy FBA'ing!

Free Office Developer Conference 2008 Pass

Hi everyone.

Tonight, @ the Atlanta Dot Net User Group meeting, we will be giving away a pass to the Office Developer Conference in San Jose from February 10-13.

https://microsoft.crgevents.com/ODC2008/Content/default.aspx?p=UC3HYF

I know this is late notice, since the meeting is tonight, but, if you can and will go to the conference, come to the meeting tonight to drop your name in a hat.  You will be responsible for your flight and hotel, but the pass itself is a $1095 "value".

Doug Ware will be talking about SharePoint development, a GREAT topic, so leave work early so you can get a good seat!

Posted 01-28-2008 by Dan Attis
Filed under: ,
Silverlight Media Player and SharePoint v2

Back on January 14th I posted about a Silverlight media player web part that myself and Keith co-developed.  I posted the source code then as well.  The new home for the project is going to be @ CodePlex.

The project is called Media Player Web Part using SharePoint 2007 and Silverlight and the URL is http://www.codeplex.com/SLMP4SP.  If anyone wants to contribute to the project, drop me a line via my blog.  I would love to have a release ready by month's end.

Stop the Insanity!

So I was trying to install some software for the fingerprint reader on my laptop, which is running Vista x64, and I got this error.

 

EMBASSY

 

I have say, this is right up there in the list of strangest errors I have ever seen.  Needless to say, the software did not install.

Posted 01-23-2008 by Dan Attis
Filed under:
Silverlight Media Player and SharePoint

Last Monday, January 7th, Keith and I talked about how to host a Silverlight Media Player in a SharePoint Web Part and the processes used to create and deploy it to a SharePoint site.  As promised here is the slide deck and all of the code.  I apologize for the delay, I've been swamped at work, imagine that!  We have a couple of more talks in the pipe to expand on these concepts so stay tuned!

Slide Deck

Code

The contentclass and isDocument properties along with the Welcome Page caveat

My current project has me working on a custom search solution for a SharePoint public facing site.  The site has a good number of sites, each with a good number of pages, as well as many lists, libraries, etc...  One of the requirements the client had was to only display Documents and Pages in the search results.  This didn't seem like an unreasonable request at the time, so I agreed.  Well, as it turns out, it was not so simple after all.

I started looking at Search Scopes, thinking to myself that I could create a Scope with a set of rules to give the "slice" of data I wanted.  This is what I wanted.  Keep in mind that this is a publishing site.

  • Pages.
  • Documents from specific libraries.

Sounds pretty simple on the surface.  So, I started creating property rules.  I only wanted results from certain libraries.  That was fine, I created a rule to pull from certain folders (as they are described on the Scope rule screen).  I very quickly realized that scopes are pretty limiting.  I cannot group rules.  I cannot have for example, color is red OR color is yellow, only AND's.  There is very limited logic available with Scope rules.  This pretty much forced me to switch my approach from a simple Scope based solution to a SQL Syntax Query solution that would allow me to pretty much return whatever I wanted.

Now I needed only documents, regardless of extension.  At this point I was a little perplexed.  I spent a good deal of time looking thru all of the crawled properties trying to find one that would help me.  It was then that I discovered the isDocument property, which, coincidentally, was also a managed property out of the box.  I added this to my query and was now only getting documents from the specified libraries back in my search results.  Almost there.  I still needed to get Pages (from all of the sites in the site collection).

How on earth was I going to do that?  Well, in the process of testing and debugging over and over again, I have discovered a little known property that was sitting right under my nose the entire time.  If you go to create a property rule within a Scope, you will notice the contentclass property.  I wondered what this property did.  Well, it was a life saver.  Essentially, every piece of content in SharePoint seems to be tagged with this property.  I believe it's all set internal as I have yet to see it referenced anywhere (at least in my limited searching).

This entire time I was working on a custom search results page that looked very different then the out of the box version, as it was for a publishing site and as I mentioned, all they wanted searched were Pages and certain Documents.  As part of the development process of that search results page, I placed a Review control on the page so that I could see my search results in their raw format as I worked on the custom rendering.  The contentclass property was right there, already in the default properties that were searched.  I of course, had to add it to my SQL Syntax Query but nonetheless, it was crawled and managed for me already.  I found a couple of blog posts that describe the possible values for this property, but they were incomplete, so here is, as far as I can tell, a complete list of possible values, that you can use in your Scopes, SQL Syntax Queries or Keyword queries should you need to.


        case "STS_Web":                             // Site
        case "STS_List_850":                        // Page Library
        case "STS_ListItem_850":                    // Page
        case "STS_List_DocumentLibrary":            // Document Library
        case "STS_ListItem_DocumentLibrary":        // Document Library Items
        case "STS_List":                            // Custom List
        case "STS_ListItem":                        // Custom List Item
        case "STS_List_Links":                      // Links List
        case "STS_ListItem_Links":                  // Links List Item
        case "STS_List_Tasks":                      // Tasks List
        case "STS_ListItem_Tasks":                  // Tasks List Item
        case "STS_List_Events":                     // Events List
        case "STS_ListItem_Events":                 // Events List Item
        case "STS_List_Announcements":              // Announcements List
        case "STS_ListItem_Announcements":          // Announcements List Item
        case "STS_List_Contacts":                   // Contacts List
        case "STS_ListItem_Contacts":               // Contacts List Item
        case "STS_List_DiscussionBoard":            // Discussion List
        case "STS_ListItem_DiscussionBoard":        // Discussion List Item
        case "STS_List_IssueTracking":              // Issue Tracking List
        case "STS_ListItem_IssueTracking":          // Issue Tracking List Item
        case "STS_List_GanttTasks":                 // Project Tasks List
        case "STS_ListItem_GanttTasks":             // Project Tasks List Item
        case "STS_List_Survey":                     // Survey List
        case "STS_ListItem_Survey":                 // Survey List Item
        case "STS_List_PictureLibrary":             // Picture Library
        case "STS_ListItem_PictureLibrary":         // Picture Library Item
        case "STS_List_WebPageLibrary":             // Web Page Library
        case "STS_ListItem_WebPageLibrary":         // Web Page Library Item
        case "STS_List_XMLForm":                    // Form Library
        case "STS_ListItem_XMLForm":                // Form Library Item
        case "urn:content-class:SPSSearchQuery":    // Search Query
        case "urn:content-class:SPSListing:News":   // News Listing
        case "urn:content-class:SPSPeople":         // People
        case "urn:content-classes:SPSCategory":     // Category
        case "urn:content-classes:SPSListing":      // Listing
        case "urn:content-classes:SPSPersonListing":// Person Listing
        case "urn:content-classes:SPSTextListing":  // Text Listing
        case "urn:content-classes:SPSSiteListing":  // Site Listing
        case "urn:content-classes:SPSSiteRegistry": // Site Registry Listing

I spent a good deal of time coming up with this list, but if someone finds on that is not mentioned, please let me know though a comment and I will update this list.  If you are wondering how I found all of these, it was actually quite easy.  I simply started to add the different types of content to the various sites, crawled it, and then looked at the output in my GridView while developing the solution.  You can see a pattern, so it did get a little easier after that was discovered.  I'm guessing as well that the SPS* ones are left over from SharePoint Portal Server 2003.  I didn't actually see those in my research, but pulled them from a post by Jose Barreto where he mentions some of these values.

So, by limiting my SQL Syntax query to only include items that are have a contentclass equal to either STS_ListItem_850 (Pages) or STS_ListItem_Document (Documents) along with making sure that the isDocument property is true (1), I was able to meet the requirement.  Well almost.

Of course, SharePoint HAD to throw me a curve ball.  As you may or may not know, Publishing sites have the concept of a Welcome Page.  This is set via a link that appears on the Site Settings page of a Publishing site.

During my testing of the search results, I noticed that none of the Welcome Pages were being returned in the search results.  I knew they were being crawled, because I saw them in the crawl log.  It was time for some additional debugging.  I enabled my trusted ReviEw and inspected the results with the search filter off, so I was getting results for all types of content, not just Pages and Documents.  I noticed that the Welcome Pages were in fact appearing BUT the content class associated with them was STS_Web.  I have no idea whatsoever why this is, but that's the way it is.  So, I had to modify my WHERE clause in my query to include STS_Web results as well.  Once I added that, I started to get all the results I expected, and most importantly the results that the client wanted.

So there you have it.  The contentclass in all of its glory.  It is super useful, especially if you are writing your own queries.  You could use it for all sorts of things.  Just be aware of the Welcome Page caveat for Publishing sites.

Posted 12-20-2007 by Dan Attis | 11 comment(s)
Filed under:
Forms Based Authentication Articles Published

Steve Peschka has published a series of articles on forms based authentication in Office SharePoint Server 2007 and Windows SharePoint Services 3.0.  Part 1 discusses FBA itself, Part 2 talks about providers, and Part 3 discusses some of the differences between FBA and Windows authentication.

  1. Forms Authentication in SharePoint Products and Technologies (Part 1): Introduction
  2. Forms Authentication in SharePoint Products and Technologies (Part 2): Membership and Role Provider Samples
  3. Forms Authentication in SharePoint Products and Technologies (Part 3): Forms Authentication vs. Windows Authentication

This is the first real "authoritative" say on FBA to date from Microsoft.  I can't wait until I have to do is click a button to do this!

One thing that I did not see mentioned in the white papers during my initial scan was to be sure that the account that you are using as the application pool's identity for the FBA website in question has the rights it needs within SQL Server to access the ASP.NET membership schemas.

Posted 12-17-2007 by Dan Attis | 1 comment(s)
Filed under:
Spammers be gone, the email commeth and login I can

I'm sure many have you may have noticed the large volumes of spam residing within many of the posts on this blog.  Well, thanks to Brendon's hard work all weekend, not only do we have a new server, but email is also working, and most importantly, I can login to my own blog and maintain it.  With all that said, I plan on enabling moderation on all posts to help control spammers (they aren't going away), as well as doing my best to approve valid comments within 24-48 hours depending on my workload.

I am looking forward to much more frequent posts as well as great content in the next few weeks!  Also, please be patient as I muddle with the skin :)

Posted 12-10-2007 by Dan Attis | 2 comment(s)
Filed under: ,
Visual Studio 2008 Loadfest / Halo Fragfest / Guitar Hero Rockfest!

For those of you in Atlanta or the surrounding area, we (the Atlanta Microsoft Professionals, Atlanta .NET User Group and Microsoft (aka Doug Turnure)) will be hosting a Visual Studio 2008 Loadfest, followed by a Halo Fragfest / Guitar Hero Rockfest in place of the regularly scheduled "talks".  All the fun (and loading) will be happening at the Microsoft Greater Southeast District office in Alpharetta on Monday, December 3rd beginning around 6 PM or so.

Be sure to bring your laptops!  The first 150 people to arrive get a FREE copy of Visual Studio 2008 Professional.  Yes, we know it's not out yet, but trust us, you will get a pretty boxed copy (when it does come out).

The gaming facilities will include 9 very large TV's with 9 XBox 360 Elites each with four controllers.  Can you say "Holy Crap Batman, I'm there!"  Bringing your own guitar is optional!

Having an accurate count of attendees would be extremely helpful so please register here if you plan on attending.

See you then!

Microsoft Corporation
1125 Sanctuary Pkwy.
Suite 300
Atlanta, GA 30004

Posted 11-26-2007 by Dan Attis | 9 comment(s)
Filed under:
Yet Another great looking public facing MOSS Internet site!

A good friend of mine recently architected, developed and launched kroger.com using the MOSS 2007 platform.  This is yet another example of using it as a public facing site.  This isn’t to say that there weren’t a few hurdles, he mentioned many, but all in all, it seems to be a success and it "looks" awesome!

Hopefully this will be the first of many Fortune #25 companies jumping on board (Kroger is #21 at press time)!

Check it out!

Posted 11-26-2007 by Dan Attis | 5 comment(s)
Filed under:
You Don't Need to Copy PDB Files to Debug in the GAC!

I generally don't post a link without much else but this was a no brainer and I feel every SharePoint developer, heck, every .NET developer needs to know this.  My friend and SharePoint pal, Doug Ware has discovered how to debug assemblies in the GAC WITHOUT having to copy the pdb symbols file to the MSIL folder.  In other words, simply attaching to the correct w3wp worker process will work.

It's awe inspiring, I had no idea!

I'm not going to steal his thunder so you will have to read all about here!

Posted 11-15-2007 by Dan Attis | 1 comment(s)
Filed under:
More Posts Next page »