Technical blog archive

.NET King Technical blog
 This is the real Alireza! jumping from one technology to another every day. Here you can read my technical blogs. Just select the right category and enjoy.
 By the way, don't miss the general blog.


Get rid of HTML and XML tags (5/30/2008)

 When you work with word xml files and locate a field in the schema what you read usually contains XML decorating tags that most probably you don’t need them in your code. How can we get rid of them?
It is pretty simple. Brush up your .NET knowledge and remember we have a class called Regex which is a short name for Regular Expression object. Using Regex you can simply define a pattern for XML or HTML tags. This pattern will be something like this: "<[^>]*>".
The very same Regex class has Replace function that works just like Replace in String class. Having them all together in C# you will have a code like this:
 

  public string RemoveTags(String originalMessage)

  {

      Regex rgx = new Regex("<[^>]*>");

      return rgx.Replace(originalMessage, "");

  }

This function simply gets an HTML/XML String and returns pure text. Don’t forget to add
using System.Text.RegularExpressions;
to your file header.
Enjoy
Alireza
 

2 comments by now. Add your comments
How to delete an SQL Server 2005 database (Somehow SharePoint)? (5/2/2008)

It looks like a silly question but I’d like to mention some cool stuff about it. When you drop the database it should delete the database file and the log file accordingly. At least this is what we expect. But what if the database is off-line? Haha, give it a try. Your drop script will delete the data but the data and log files stay there. Now if you want to create another database with the same name you see this:

 

But how this is related to SharePoint?
Remember that when you create MOSS or WSS Site collections it gives you the chance to pick a database name? Now remember when you uninstall SharePoint it doesn’t delete the databases?
Ok, here is what happens. You uninstall MOSS or delete Site Collection. Then you may think that, I may use these data in the future or for any reason database is in use and you cannot delete it so you take it off-line and then you delete and forget it while the files are still there. When you want to create another site collection or a new installation the existing files will not let you create the new database.
But why do you want to take the database off-line?
Taking the database off-line means that we don’t want anybody connect to the database anymore but we are polite enough to let the current users to the database finish their work. It doesn’t kill the existing connections and it takes some time for all the live users to finish their work and disconnect and in the meanwhile no new connection is made to the database. Usually when junior database administrators want to delete a database that there is live connection to that and they come up to related errors they try to take the database off-line, which is a good move, but do you really want to keep the current users when you want to delete what ever the data that they enter? So to drop a database simply go to SQL Server 2005 management studio and Management -> Activity Monitor. If you just double click on the activity monitor you can see a list of all the databases and existing connections to them. Simply right click on the database and kill the connection. Then you will be good to delete the database.
Cheers
Alireza

0 comments by now. Add your comments
Busy days with project (5/1/2008)


The bad news is that I am very busy with the project deployment with Loblaw so I can hardly find time to blog something considering that I come home sometimes after 10:00 or 11:00pm. The good news is that I am learning lots of cool stuff in this project that I can share with you in the coming days. So stay tuned with my latest updates.
Cheers
Alireza

1 comments by now. Add your comments
There are no primary or candidate keys in the referenced table (4/25/2008)

Msg 1776, Level 16, State 0, Line 1
There are no primary or candidate keys in the referenced table 'dbo.Products' that match the referencing column list in the foreign key 'FK_Sales_Products'.
Msg 1750, Level 16, State 0, Line 1

Have you seen this error before? Hah, you just noticed it? Cool! Let's see where the error is coming from.

I created two tables as Products and Sales. There is a foreign key that forces the sales table to use only valid values for ProductAbbreviation in Products table. To create a foreign key constraint I can simply run this script:

ALTER TABLE [dbo].[Sales]  WITH CHECK ADD  CONSTRAINT [FK_Sales_Products] FOREIGN KEY([ProductAbbreviation])

REFERENCES [dbo].[Products] ([Abbreviation])

GO

ALTER TABLE [dbo].[Sales] CHECK CONSTRAINT [FK_Sales_Products]

Here is the point. This foreign key refers to a field called Abbreviation. There is just one simple rule on this game. You cannot make a reference to a field that is not unique. In better word your foreign key can only refer to a field that has a unique constraint like Primary Key or Unique Index. Now read the error again and you can simply understand what is going on.

To have this script work you need to create a unique index on Abbreviation field in Products table or make it a primary key that guarantees uniqueness. So simply go to index management and create a unique index on that field or run this script to create it like old fashioned developers:

CREATE UNIQUE NONCLUSTERED INDEX unq_abbr ON dbo. Products

(Abbreviation)

Then you can create your foreign key happily ever after.
Enjoy
Alireza

1 comments by now. Add your comments
Active task shouldn't be deleted in SharePoint workflow (4/18/2008)

One of the typical problems in workflow development is task deletion. Usually users that interact with the task, have contribute permission to the task which means they can simply delete the tasks that are created as a part of workflow processing. Deleting a task can mess up the workflow and we may need to handle it as a part of the workflow. But how can we stop the users from deleting tasks? The solution is very simple. Item event handlers in MOSS/WSS 2007 can easily take care of this case. Item event handlers are events that are registered to a list and mapped to a dll that is already deployed to GAC. When an event (insert, delete and update) happens the event handler fires and execute the code that can do something in response or may even cancel the event trigger progression. This is exactly our scenario. We need to build an event handler that when a user tries to delete a task, it checks the task status. If the status is not "Completed" then in cancels the deletion and displays an error message. To implement this simply create a class library project in Visual Studio .NET and make a reference to Windows SharePoint Services Library. Then add the following code. Inline code description is included.

using System;
using
System.Collections.Generic;
using
System.Text;
using
Microsoft.SharePoint;

namespace StopActiveTaskDelete
{
    //Inhertit your class from SPItemEventReceiver
    public class CActiveTasksDelete: SPItemEventReceiver
    {
        // Override the ItemDeleting function. You will find also ItemDeleted
        // function that fires when the item is deleted. For your scenario we
        // need ItemDeleting to stop the delete process before it is complete.
        public override void ItemDeleting(SPItemEventProperties properties)
        {
            //Built in call to the initial definition
            base.ItemDeleting(properties);
            // Get reference to the current item being deleted
            SPListItem myItem = properties.ListItem;
            // Read the status field of the item being deleted
            String taskStatus = myItem["Status"].ToString();
           

            // Is the task status is Complete it is not active task any more
            // Otherwise we cancel the deletion
            if (taskStatus != "Completed")
            {
                // This is the message that we'd like to show to the user
                // if he/she tries to delete an active task
                properties.ErrorMessage = "This task is still in progress and cannot be deleted";
                // This line actually cancels the delete
                properties.Cancel = true;
            }
        }
    }

}

Sign the assembly with a strong name key and deploy it to the global assembly cache. Now all you need to do is to introduce the this assembly to a task list in SharePoint. There are different ways of doing it, but the simplest way is using a simple consol application to do so.

Your script should look like this:

using System;
using
System.Collections.Generic;
using
System.Text;
using
Microsoft.SharePoint; 

namespace RegsiterEventReceiver
{
    class Program
    {
        static void Main(string[] args)
        {
            // Get reference to the the site that containd your task list
            SPSite mySite = new SPSite("http://sharepointSiteURL");
            SPWeb myWeb = mySite.OpenWeb();
            // Get the reference to your task list
            SPList myList = myWeb.Lists["Tasks"];
            myList.EventReceivers.Add(SPEventReceiverType.ItemDeleting,
                "StopActiveTaskDelete, Version=1.0.0.0, Culture=neutral" +
                //Replace this key with your own assembly publick key token
                ", PublicKeyToken=8a1a592e4ca85c4c",
                "StopActiveTaskDelete.CActiveTasksDelete");
            // Don't forget to update the list
            myList.Update();
            // Make sure you add this life to feel good after your
            // Solution is deployed successfully
            Console.WriteLine("Haha, done!");

        }
    }
}

Now go to the SharePoint Site and try to delete an incomplete task. You will get this error page.

And this code will protect active tasks from deletion happily ever after.
Cheers
Alireza

0 comments by now. Add your comments
Setting Item Level Security programmatically for SharePoint list items (4/15/2008)

 This is not a unique post. You may find this post in many weblogs and websites, but I am putting this code here for my own reference. In this code I break the security inheritance for a list item and provide contribute permission for a group that has been already created in SharePoint site.

 

            SPListItem myItem = properties.ListItem;
//This line detaches the item security from the list
            myItem.BreakRoleInheritance(false);
            myItem.Update();
            SPWeb myWeb = properties.OpenWeb();
// Creates an object of type SPMember to represent a group
            SPMember member = myWeb.SiteGroups["TestGroup"];
// We can simply cast a SPMember object into a SPPrincipal variable
            SPPrincipal principal = (SPPrincipal)member;
// A role definition is required to represent a permission level in SharePoint site
            SPRoleDefinition roledefinition =
                myWeb.RoleDefinitions.GetByType(SPRoleType.Contributor );
            SPRoleAssignment myRoleAssignment = new SPRoleAssignment(principal);
            myRoleAssignment.RoleDefinitionBindings.Add(roledefinition);
            myItem.RoleAssignments.Add(myRoleAssignment);
            myItem.Update();

 Enjoy the code.
Alireza

0 comments by now. Add your comments
SharePoint Conference 2008 Dubai follow up (4/14/2008)

I finally got enough e-mails to start bloging my presentations in the conference. Here is the answer to some of the requests that I received after conference.

Enjoy
Alireza

2 comments by now. Add your comments
SharePoint Conference 2008 in Dubai (4/5/2008)

 After a long and very busy time working on projects and books I am back online with some cool stuff. I will be speaker in SharePoint Conference 2008 Dubai. I have picked up 3 subjects for my presentations that you can find the complete conference agenda here.

  • Using Excel Services to build BI solutions: I personally believe this title is not well articulated. I guess Excel Services is something that everybody should explore it personally so I am not going to completely cover features and capabilities of excel services. I will do my best to deliver the presentation so that the audience can repeat the experience themselves. This lecture will include:
    • Excel services from scratch (how to have it running from a clean installation)
    • Excel services architectural design (Data sources, trusted locations, security structure)
    • Using Excel Services to bring data from SQL Server to MOSS interface with data graphs
    • Using Excel Services to bring Analysis Services Cube data and graphs to MOSS Server
    • Excel Services and BI components (Introducing MOSS out of box and how excel services interacts with MOSS BI lists and BI Dashboard)
    • Q&A
  • Building applications using MOSS 2007 web services: Don't get me wrong, this presentation is not for developers. I am targeting IT-Professionals and I am trying to keep it at 200 level. Here is my presentation outlines:
    • What is XML Web Service?
    • How can we call XML Web Services without code (I am targeting InfoPath)?
    • Introducing built-in XML Web Services in MOSS 2007.
    • Connecting XML Web Services and MOSS 2007 document libraries using InfoPath 2007 glue (Hay InfoPath 2007 glue is NOT a product name - lol).
    • How to deploy these XML Web Service containing InfoPath forms to the MOSS 2007 forms server
    • How can developers build custom Web Services to expose more MOSS features
  • Office Automation using Microsoft Word 2007 and MOSS 2007: This is basically a case study around using Microsoft Word 2007 XML file that is also called WordML. This presentation is basically an open discussion around using WordML files instead of normal word files. I am just trying to explain how easy it is to utilize your basic XML Programming skills to manipulate sections of the WordML files.

I really appreciate if you spare a minute or two and give me your feedback.
Alireza

19 comments by now. Add your comments
American or Canadian C# Code? (2/28/2008)

 The worst thing that I can imagine is that the compiled code works properly on your development/staging environment but fails to work on production. The nightmare starts when you just remember that you don't have debugger on production. Here is what happened to me yesterday. I developed a web service for the Time-Off time calculation. The code was excluding Ontario statuary holidays. This service apparently without any external dependency was working beautifully on my development laptop, but failing with some strange error on the server.

Take a look at this code:
DateTime holiday = DateTime.Parse("28/02/2008");

Sounds ok and works well on my Canadian computer (hey, it is made in China but Windows regional options is set to English(Canada)). But the very same line of code fails to run on an American machine. Simply because the American version of this code should be like this:
DateTime holiday = DateTime.Parse("02/28/2008");

That's just the date format but what can you do in a compiled code for this? Aha, .NET Framework is the answer. If you read the time variable from a Calendar or a DateTimePicker then the control is smart enough to do that, but if you are reading a preformatted string or you are hard-coding the date in your application then this issue come up. Here is the right way of solving this problem:

using System;
using System.Globalization;

namespace DotNetKing
{
    class Program
    {
        static void Main(string[] args)
        {
            CultureInfo culture = new CultureInfo("en-CA");
            DateTime holiday = DateTime.Parse("28/02/2008", culture);
            Console.Write(holiday.ToString());
        }
    }
}

This way you not only hardcode the date but also hardcode the date culture, so your code behaves Canadian even on an American server!
Cheers
Alireza

4 comments by now. Add your comments
Forms Server on the MOSS Farms - Silly error (2/27/2008)

Take a look at this error first:

An error occurred accessing a data source.
An entry has been added to the Windows event log of the server.
Log ID:5566

 

Does it look familiar? No? How about this one?

I assume that you love it because without these errors we could never have a job as consultant. I got this error when I deployed an InfoPath 2007 form to MOSS 2007 forms server. There was nothing wrong with the form but it was getting the user information from MOSS profile to have some part of the form pre-populated. First of all when I checked the application log on the front end server I found nothing. Considering the farm installation I could find the error on the server box that was hosting the SharePoint Central Administration service. Here is the error in the application log:

A runtime exception was detected. Details follow.
Message: Access Denied! Only site admin can access Data Source object from user profile DB.

Techinal Details:
System.UnauthorizedAccessException: Access Denied! Only site admin can access Data Source object from user profile DB.
at Microsoft.Office.Server.UserProfiles.SRPSite.AdminCheck(String message)
at Microsoft.Office.Server.UserProfiles.DataSource._LoadDataSourceDef(IDataRecord rec)
at Microsoft.Office.Server.UserProfiles.DataSource._LoadDataSourceDef(String strDSName)
at Microsoft.Office.Server.UserProfiles.DataSource..ctor(SRPSite site, Boolean fAllowEveryoneRead)
at Microsoft.Office.Server.UserProfiles.DataSource..ctor(SRPSite site)
at Microsoft.Office.Server.UserProfiles.UserProfileConfigManager.GetDataSource()
at Microsoft.Office.Server.UserProfiles.BDCConnector.RefreshConfiguration(String sspName)

For more information, see Help and Support Center at

It seems that the forms server is trying to access to Profile Services on MOSS and it is complaining that Only Site Admin can do that. Here was the tricky part. On the top of the page I could see the spadmin login account. This account was site admin for MOSS, SharePoint Central administration and also Shared Services Provider site. So what else is missing?

The answer is here:
Go to SharePoint Central administration --> Application Management --> Authentication Providers. Then select the default zone. Make sure the right Web Application is selected on the top of the page. Clear the checkbox for the anonymous access. And now you can run your form with the forms server happily ever after.

Important point:
When you are using Forms Server with MOSS the site security is not applied to the underlying services. It means even if your MOSS website requires authentication, if Provider is anonymous enabled forms services uses anonymous login for the external access, because it looks at the provider, not the site that is hosting the form. It took me a long time to find it out because I had the impression that Forms Server impersonates the user login information and when I see the user ID on the top of my SharePoint page, this is not anonymous call. I was wrong.

With special thanks to Infusion SharePoint Technical team that gave me wonderful guides to resolve this issue.

 Cheers
Alireza

7 comments by now. Add your comments
How I fell in love with Microsoft .NET (2/13/2008)
On Feb 14, 2002 I was living in Dubai. February 14 is a very special day and every body expects e-mails and gifts from lovers. On that day early in the morning when I opened my mailbox and I was expecting lots of e-mails with pink hearts in it, I found just one e-mail that announced the final release of the .NET Framework 1.0. My god, is Microsoft .NET the only one who remembers me on Valentines day? I was working with Beta release of Visual Studio .NET but from that day I fell in love with .NET. Today is the 6th anniversary of Microsoft .NET first release. So happy birthday .NET and Happy birthday Visual Studio.

Remember that first version of .NET was released on February 13th, 2002.

I Wish all .NET Developers a
wonderful birthday

1 comments by now. Add your comments
WebPart audience targeting is not appearing (2/8/2008)
 

 I had a funny problem today. On one of the client sites we were trying to enable audience targeting on a development server box and simply I couldn't find the Target Audiences box. Simply it was not there. Guess what the problem was!

Shared Service Provider was not created on the server.

Morale:

  1. Please do the setup steps completely and review the Setup tasks
  2. If the problem is very weird, look for some weird cause
  3. When you find the cause share it with the others

It is interesting that I couldn't find any cause for this problem by searching the internet.

Cheers
Alireza

 

2 comments by now. Add your comments
 

 -