Albert Jan Schot
 

Tired of waiting for membership updates on your devmachine?

17

Jun

Building code that retrieves memberships most of us will do by using the Publishedlinksservice that returns all the memberships. However normally those memberships only update every hour, so if you have a development machine and you want to test code (or check whether the memberships actually get updated), you are stuck waiting. Sadly you cannot force an update on the timer job that syncs those memberships; luckily you can speed up things, the STSADM sync operation allows you to set the time it takes between syncing.  So the next command will force the timer job to sync every minute:  

stsadm -o sync –SyncTiming M:1

This might cause some load, but on my development machine I don’t really care about that, as long as I can see results. And of course you can set it back to its original 60 minutes afterwards.

Share:

Albert-Jan Schot schreef

Comments (0)

Albert-Jan Schot

UserProfile and ChoiceLists, reading and saving

19

Feb

Last few days I have been struggling with a piece of code that should update a UserProfile. The idea was to make a nice feature that allows a WebPart to display a link that would open a screen showing the user some options to change UserProfile values. Those change options should be rendered based on three pieces of information; a Site Column containing possible values, a ControlType and the UserProfileProperty to save it to.

The first few versions worked pretty well since I only had to save strings or checkboxes, however further along the way I decided that ChoiceLists from the UserProfile should be supported, and there it all went wrong, even with Google it took me quite some time figuring out how to do it, so here a few tips: 

Saving a single value to a UserProfileProperty even when its a ChoiceList is pretty easy:

    userprofile[item.Key].Value = item.Value;

Saving multiple values to a userProfileProperty took me some more time, but finally even that appeared to be possible:

   foreach (string choice in choiceList)
   {
      userprofile[item.Key].Add((Object)choice);
   }

Minor detail on that part appeared that the .add option does as it says, it only adds items; ergo if you would already have selected option1 in your profile, and try to update it with an option2, it would keep the option1 saved, and adds the option2.

So before you are actually try to save values that way do a:

   userprofile.clear();

   userprofile.update();

Now that’s for ‘saving’ values to your UserProfile, reading them is another story, reading a ‘normal’ string can be done with a simple:

   userprofile["PropertyToRead"].Value;

Reading a ChoiceList should be done like:

   if (userprofile["PropertyToRead"] is UserProfileValueCollection)
            clValue = userprofile["PropertyToRead"] as UserProfileValueCollection;

Whenever you done that you can simple loop trough the UserProfileValueCollection for reading the selected items.

Albert-Jan Schot schreef

Comments (0)

Albert-Jan Schot

Adding a ItemTemplate into a repeater the new way

21

Aug

A colleague recently found a very easy way to add a ItemTemplate into your repeater without having to create the ‘classic’ myTemplate : ITemplate class. So a nice example of how less can be more:

1: rptPager.ItemTemplate = new CompiledTemplateBuilder( new BuildTemplateMethod(

BuildItemTemplate ) );

   2:  
   3:  
   4:         void BuildItemTemplate( Control container ) {
   5:             LinkButton lbPage = new LinkButton() { ID = "lbPage" };
   6:             container.Controls.Add( lbPage );
   7:         }

Albert-Jan Schot schreef

Comments (0)

Albert-Jan Schot

Create a List based on a Template (.stp)

17

Jun

So here you found yourself clicking together a list to let users add items early in your development process, next thing you know the list is too big, and they want it to be deployed on their production servers. Or you want to upload an stp and create a list based on it (in my case; I rather upload and deploy an stp create a list based on that, then create an event receiver that added the items by code).

So I spend some time searching the net and created a FeatureReceiver containing the following code:

   1:  /// <summary>
   2:  /// Uploads site Templates
   3:  /// </summary>
   4:  /// <param name="templateGallery"></param>
   5:  /// <param name="templateFiles"></param>
   6:  private void UploadTemplates(SPDocumentLibrary templateGallery, 
string[] templateFiles)
   7:  {
   8:      if (templateGallery != null)
   9:      {
  10:          foreach (string template in templateFiles)
  11:          {
  12:              System.IO.FileInfo fileInfo = new System.IO.FileInfo
(template);
  13:              SPQuery query = new SPQuery();
  14:              query.Query = string.Format("<Where><Eq><FieldRef 
Name='FileLeafRef'/>" +

15: "<Value Type='Text'>{0}</Value></Eq></Where>",

fileInfo.Name);

  16:              SPListItemCollection existingTemplates = 
templateGallery.GetItems(query);
  17:              int[] Ids = new int[existingTemplates.Count];
  18:              for (int i = 0; i < existingTemplates.Count; i++)
  19:              {
  20:                  Ids[i] = existingTemplates[i].ID;
  21:              }
  22:              for (int j = 0; j < Ids.Length; j++)
  23:              {
  24:                  templateGallery.Items.DeleteItemById(Ids[j]);
  25:              }
  26:              byte[] stp = System.IO.File.ReadAllBytes(template);
  27:              templateGallery.RootFolder.Files.Add(fileInfo.Name, stp);
  28:          }
  29:      }
  30:  }

And call that with a:

   1:   string directory = properties.Definition.RootDirectory;
   2:  if (!directory.EndsWith(@"\"))
   3:                          directory += @"\"; directory += "ListTemplates";
   4:                      if (System.IO.Directory.Exists(directory))
   5:                      {
   6:                          string[] templates = System.IO.Directory.
GetFiles(directory, "*.stp", System.IO.SearchOption.TopDirectoryOnly);
   7:                          SPDocumentLibrary listTemplates = 
thisWeb.GetCatalog(SPListTemplateType.ListTemplateCatalog) as SPDocumentLibrary;
   8:                          UploadTemplates(listTemplates, templates);
   9:                      }
  10:                      else
  11:                      {
  12:                          //log error or empty message
  13:                      }

That small piece of code will upload all .stp files to your ListTemplateGallery allowing you to create Lists based on them with the following code:

   1:  foreach (SPListTemplate template in thisSite.GetCustomListTemplates
(thisWeb))
   2:  {
   3:  if (template.Name == "YourTEmplateName")
   4:      {
   5:          listTemplate = true;
   6:          Guid processGuid = subWeb.Lists.Add("ListName", "ListDescription", 
template);
   7:          SPList processlist = subWeb.Lists[processGuid];
   8:   
   9:          processlist.Update();
  10:          subWeb.Update();
  11:      }
  12:  }

For me it saved me a lot of work, hope it will do the same for you.

Albert-Jan Schot schreef

Comments (0)

Albert-Jan Schot

SPList ItemCount on a > 100.000 items list

20

Apr

Having a list containing more than 100.000 items provided us with some challenges, apparently it is not possible to retrieve the ItemCount based on certain criteria using the object model.

The problem is that we actually had to retrieve those items.

So a colleague came up with a rather dirty but very useful  fix for that.

It’s a small piece of code that makes a View based on a desired query, and sort this on the Author (all the items are created by the same account). By setting the Collapse property on true SharePoint renders a HTML Header containing the total amount of items. By actually reading that piece of HTML he found a quick&dirty way to retrieve those totals.

Below you can find the code, and we were wondering if any of you out there would know another way without using the Search or talking directly to the Content Database.

/// <summary>

/// This function will return the count of the items found by the query, using the RenderAsHTML() method of the SPView object

/// IMPORTANT: It asumes that all Items are created using the same account (Author), if this is not the case,

/// please find or provide an other property that is equal for all ListItems

/// NOTE: This function has no error-handling inside.

/// </summary>

/// <param name="list">SPList object that holds the items to count</param>

/// <param name="query">CAML query-string</param>

/// <returns>-1 on error, otherwise number of items found</returns>

private static int GetItemCount(SPList list, string query)

{

    return GetItemCount(list, query, "Author");

}

private static int GetItemCount(SPList list, string query, string GroupByProperty)

    {

        //Since files are added by the system, author will be the same for all

        //adding GroupBy and setting the Collapse to true, the view will be rendered collapsed and show only the itemcount

        query = String.Format("<GroupBy Collapse=\"TRUE\" GroupLimit=\"1\"><FieldRef Name=\"{0}\" /></GroupBy>{1}",GroupByProperty, query);

 

        //create temp view

        list.ParentWeb.AllowUnsafeUpdates = true;

        string TempViewName = "TempViewForItemCount";

        SPView newview = list.Views.Add(TempViewName, new StringCollection() {"Soep1", "Author" }, query, 10000000, false, false);

        newview.Update();

        list.Update();

        //RenderAsHtml creates a small piece of HTML that contains the itemcount

        string html = list.Views[newview.ID].RenderAsHtml();

 

        //remove the temp view

        list.Views.Delete(newview.ID);

 

        list.ParentWeb.AllowUnsafeUpdates = false;

 

        //init a counter

        int count = 0;

 

        //grab the count which is in brackets right after the '&#8206;'-character

        if (html.IndexOf("&#8206;(") <= 0)

            return -1;

        html = html.Substring(html.IndexOf("&#8206;(") + 8, html.IndexOf(")", html.IndexOf("&#8206;(")) - (html.IndexOf("&#8206;(") + 8));

       

        //try to parse the count

        if (!int.TryParse(html, out count))

            return -1;

        return count;

    }

 

 

//testfunction

private void Test()

{

    using (SPWeb myweb = new SPSite("http://somedomain.com").RootWeb)

    {

        SPList SomeList = myweb.Lists["SomeList"];

        Console.WriteLine("End loading web at: " + DateTime.Now.ToLongTimeString());

        string q = "<Where><Eq><FieldRef Name=\"SomeField\" /><Value Type=\"Text\">SomeValue</Value></Eq></Where>";

        int count = GetItemCount(MenuVanDeDag, q);

    }

}

 

Albert-Jan Schot schreef

Comments (0)

Albert-Jan Schot
Page 1 of 2 in the c category Next Page