mandag 4. juni 2012

Nyttige Sharepointlenker

Building Information Architecture in SharePoint 2010 using Taxonomy

http://msdn.microsoft.com/en-us/magazine/hh456396.aspx

Setting Up the Development Environment for SharePoint 2010 on Windows Vista, Windows 7, and Windows Server 2008

http://msdn.microsoft.com/en-us/library/ee554869.aspx

http://www.ericharlan.com/Moss_SharePoint_2007_Blog/how-to-install-sharepoint-2010-guide-a166.html

Automated SharePoint 2010 Installations: Step-by-step 

http://blog.lekman.com/2010/11/automated-sharepoint-2010-installations.html
http://www.wahidsaleemi.com/2011/11/autospinstaller-configuration-2/

Use SPLongOperation to display SharePoint Processing Page for Lengthy Operations and avoid Timeout Issues

 http://nikspatel.wordpress.com/2011/04/27/use-splongoperation-to-display-sharepoint-processing-page-for-lengthy-operations/

How to Build SharePoint Projects with TFS Team Build


http://msdn.microsoft.com/en-us/library/ff622991.aspx

.Net Managed Client Object Model: Fetch All Webs, Libraries, Items


http://shahjinesh11.wordpress.com/2012/06/14/net-managed-client-object-model-fetch-all-webs-libraries-items/



lørdag 17. september 2011

Field Control Labels

I Recently created an pagelayout for a customer showing some text...

Hower she was not that impressed by the result. She wanted the field to show an extra asterix. The field was after all required!
Then again without a notice she returned with a requirement that there should be added a description if needed...

I tried to add som html at various places in my pagelayout realising the result was not that good :-)
The the customer returned with an ather requirement... "Any text is displayed in the language the user pleaces".
I realized this was the end of doing minor tweeks in the html...

I started to investgate my pagelayout finding that I wanted something simmilar to the standard Sharepoint Web Control (Microsoft.SharePoint.WebControls).

<sharepointwebcontrols:userfield fieldname="PublishingContact" id="eUserFieldContact" runat="server" />

I wanted to add required indicator, decription text or, - not display anything (I guess my customer will return)
Like this:
<webcontrols:textfield description="..." descriptioncssclass="edit-mode-field-description" fieldname="PublishingContact" hidetitle="False" id="eTextFieldTitle" requiredtext="*" requiredtextcssclass="edit-mode-required-field-marker" runat="server" title="..." />
Having learned a Sharepoint lesson or two I also figured I could need an extra Title field to override default text.
No more talking do some coding:
I created a class that inherits TextField Control

public class TextField : Microsoft.SharePoint.WebControls.TextField, IBaseFieldControl
{
    public bool HideTitle { get; set; }
    public string Title { get; set; }
    public string Description { get; set; }
    public string DescriptionCssClass { get; set; }
    public string RequiredText { get; set; }
    public string RequiredTextCssClass { get; set; }

    protected override void Render(HtmlTextWriter output)
    {
        if (!HideTitle)
            this.RenderCustom(output);
        else
        {
            DisableInputFieldLabel = true;
            base.Render(output);
        }
    }

    public void RenderFieldForCustomInput(HtmlTextWriter output)
    {
        RenderFieldForInput(output);
    }
}
and an interface mathing the requirement.

public interface IBaseFieldControl
{
    string Title { get; set; }
    string Description { get; set; }
    string DescriptionCssClass { get; set; }
    string RequiredText { get; set; }
    string RequiredTextCssClass { get; set; }
    bool HideTitle { get; set; }

    void RenderFieldForCustomInput(HtmlTextWriter output);
}
The RenderFieldForCustomInput is just a wrapper for RenderFieldForInput which unfortionatly is protected!
I Also creatd a RenderCustom Extention method to render the label ++
public static class BaseFieldControlExtentions
{
    public static void RenderCustom(this BaseFieldControl field, HtmlTextWriter output)
    {
        var iField = field as IBaseFieldControl;
        if (iField == null)
            throw new ArgumentException("control must implement IBaseFieldControl", "field");

        output.Write("<div align=\"left\" class=\"ms-formfieldcontainer\" >");
        var container = GetDivControl("ms-formfieldlabelcontainer");
        container.Attributes.Add("nowrap", "nowrap");

        var labelText = GetSpanControl("ms-formfieldlabel", string.IsNullOrEmpty(iField.Title) ? field.Field.TitleResource.GetValueForUICulture(field.Web.Locale) : iField.Title);
        labelText.Attributes.Add("nowrap", "nowrap");
        container.Controls.Add(labelText);

        var lableRequired = GetSpanControl(iField.RequiredTextCssClass, iField.RequiredText);
        container.Controls.Add(lableRequired);

        var labelDecription = GetSpanControl(iField.DescriptionCssClass, iField.Description);
        container.Controls.Add(labelDecription);

        container.RenderControl(output);
        output.WriteLine("<div class=\"ms-formfieldvaluecontainer\" >");
        output.WriteLine("<span dir=\"none\" >");

        iField.RenderFieldForCustomInput(output);

        output.WriteLine("</span>");
        output.WriteLine("</div>");
        output.WriteLine("</div>");
    }

    private enum HtmlContolType
    {
        div, span
    }
    private static HtmlGenericControl GetControl(HtmlContolType contolType, string className)
    {
        var ctrl = new HtmlGenericControl(contolType.ToString());
        ctrl.Attributes.Add("class", className);
        return ctrl;

    }
    private static HtmlGenericControl GetDivControl(string className)
    {
        return GetControl(HtmlContolType.div, className);
    }
    private static HtmlGenericControl GetSpanControl(string className)
    {
        return GetControl(HtmlContolType.span, className);
    }
    private static HtmlGenericControl GetSpanControl(string className, string innerText)
    {
        var ctrl = GetSpanControl(className);
        ctrl.InnerText = innerText;
        return ctrl;
    }

}

Now I thought I was good to go, but i spoke too soon... My customer wanted the same feature for the Taxonomy control. Great another inherit... Well, this time Microsoft was so nice that they planned for this crazy requirement. The made the TaxonomyFieldControl sealed. Using Reflector and som guess I wrapped the field using the same IBaseFieldControl interface. Whola! A fully working Taxonomy Field...

public class TaxonomyFieldControl : BaseFieldControl, IBaseFieldControl
{
    private BaseFieldControl _wrappedFieldControl;

    public bool HideTitle { get; set; }
    public string Title { get; set; }
    public string Description { get; set; }
    public string DescriptionCssClass { get; set; }
    public string RequiredText { get; set; }
    public string RequiredTextCssClass { get; set; }

    public void RenderFieldForCustomInput(HtmlTextWriter output)
    {
        RenderFieldForInput(output);
    }

    #region Public Override
    public override object Value
    {
        get { return _wrappedFieldControl.Value; }
        set { _wrappedFieldControl.Value = value; }
    }
    public override void Validate()
    {
        _wrappedFieldControl.Validate();
    }
    public override void UpdateFieldValueInItem()
    {
        _wrappedFieldControl.UpdateFieldValueInItem();
    }
    #endregion

    #region Protected Override
    protected override void RenderFieldForDisplay(HtmlTextWriter output)
    {
        var renderFieldForDisplay = _wrappedFieldControl.GetType().GetMethod("RenderFieldForDisplay", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
        renderFieldForDisplay.Invoke(_wrappedFieldControl, new object[] { output });
    }
    protected override void OnInit(System.EventArgs e)
    {
        var ctrl = new Microsoft.SharePoint.Taxonomy.TaxonomyFieldControl { FieldName = FieldName };
        _wrappedFieldControl = ctrl;
        Controls.Add(ctrl);
        base.OnInit(e);
    }
    protected override void RenderFieldForInput(HtmlTextWriter output)
    {
        var renderFieldForInput = _wrappedFieldControl.GetType().GetMethod("RenderFieldForInput",      BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
        renderFieldForInput.Invoke(_wrappedFieldControl, new object[] { output });
    }
    protected override void Render(HtmlTextWriter output)
    {
        this.RenderCustom(output);
    }
    #endregion
}

At the end I added the various resurces to ensure localized user experience.
Use the App_GlobalResources deployment and add Resources to the Control Declaration
<webcontrols:textfield description="<%$Resources:layout, field_Title_desc %>" descriptioncssclass="edit-mode-field-description" fieldname="PublishingContact" id="eTextFieldTitle" runat="server" HideTitle="False" Title="" RequiredText="<%$Resources:layout, field_required_text %>" RequiredTextCssClass="edit-mode-required-field-marker" />

mandag 14. desember 2009

Testing using Database and Rollback

I've several times searched the web for good examples. I've fond Examples using TranscationScope, but It gets really conplex once there are more than one connection. Causing Distributed Transaction Coordinator (MSDTC) to complain. Only solution then is to fix both client and server configuration, geeeahh. Ugly...
An other approach is using Serviced component mechanism that enables COM+ service. I feels a bit 2000'ish.

At last I decided to write my onwn code... And I feel quite prowd doing so...
I use Linq to SQL. Giving me some limitations. But this is my first shoot.

public class DbTools<T> where T : DataContext
{

   public static void ExecuteWithRollback(string connectionName, Action<T> rollbackDelegate)
   {
      Recorder.Record(rollbackDelegate).Connection(connectionName).Rollback();
   }

   public static void ExecuteWithCommit(string connectionName, Action<T> rollbackDelegate)
   {
      Recorder.Connection(connectionName).Record(rollbackDelegate).Commit();
   }

   public static Recorder<T> Recorder
   {
      get
      {
         return new Recorder<T>();
      }
   }
}

This is used as an entrypoint for my fluid syntax. logig is in the Recorder class
public class Recorder<T> where T : DataContext
{
   private string _connectionName;
   private IDbConnection _connection;
   private Action<T> _executeDelegate;

   internal Recorder()
   {
   }

   public Recorder<T> Connection(IDbConnection connection)
   {
      _connection = connection;
      return this;
   }

   public Recorder<T> Connection(string connectionName)
   {
      _connectionName = connectionName;
      return this;
   }

   public Recorder<T> Record(Action<T> executeDelegate)
   {
      _executeDelegate = executeDelegate;
      return this;
   }

   private object GetConnectionObject()
   {
      if (_connection != null)
         return _connection;

      return ConfigurationManager.ConnectionStrings[_connectionName].ConnectionString;

   }

   private void Execute(bool commit)
   {
      if (_executeDelegate == null)
         throw new RecorderException("ExecuteDelegate not set");
      if (_connection == null && string.IsNullOrEmpty(_connectionName))
         throw new RecorderException("Connection not set");

      // Hack to make new-call Work with parameters. Constraints don't cover this case
      var dataContext = (T)Activator.CreateInstance(typeof(T), GetConnectionObject());

      dataContext.Connection.Open();
      try
      {
         using (var trans = dataContext.Connection.BeginTransaction())
         {
            dataContext.Transaction = trans;
            {
               _executeDelegate(dataContext);
               if (commit)
                  trans.Commit();
               else
                  trans.Rollback();
            }
         }
      }
      catch (Exception e)
      {
         throw new Exception("Transaction might be disposed. Try to set <TEntity>.Options.TrackingMode = TrackingMode.Connected. If this don't resove the probblme theres properbly a part of the code that calls either Transaction.Dispose/Commit/Rollback or Connection.Dispose/Close", e);
      }
   }

   public void Commit()
   {
      Execute(true);
   }

   public void Rollback()
   {
      Execute(false);
   }
}

Now I can test my code.


[TestFixture]
public class DbToolsTest
{

   [Test]
   public void TestRollback()
   {
      DbTools<BNSystemDataContext>.ExecuteWithRollback("BNSystemConnectionString", MethodBodyToRollback);
   }

   [Test]
   public void TestRecordWithComplete()
   {

      DbTools<BNSystemDataContext>.Recorder.Connection("BNSystemConnectionString").Record(MethodBodyToRollback).Rollback();
   }

   private static void MethodBodyToRollback(BNSystemDataContext context)
   {
      const string socialSecurityNumber = "24129912345";
      var boPerson = new BOPerson(context) {Options = {TrackingMode = TrackingMode.Connected}};
      var p = boPerson.LoadSecurityNumber(socialSecurityNumber);
      boPerson.Update(p, "1234567");
   }

}

mandag 9. november 2009

Sort your Arrays

Sometimes simple things get complex and visa/versa. I've done sorting of arrays many times. Finally it struck me. I've been wasting time again... Just define you sorting algoritm in the CompareTo method. Never return any default values like 1, 0 or -1. It will make you code fail...

public class Item : IComparable<item>
{
   
    public Item(int id, string name)
    {
        Id = id;
        Name = name;
    }

    public int Id
    { get; set; }

    public string Name
    {get; set;}

    public string[] Email
    { get; set; }

    public int CompareTo(Item item)
    {
        var compare = Name.CompareTo(item.Name);
        if (compare != 0)
            return compare;

        return Id.CompareTo(item.Id);
    }
}

Now I test my code...

[Test]
public void SortArray()
{
var array = new[] {new Item(1, "B"), new Item(2, "C"), new Item(3, "A")};

Array.Sort(array);

Assert.AreEqual(array[0].Name, "A");
Assert.AreEqual(array[1].Name, "B");
Assert.AreEqual(array[2].Name, "C");
}

XmlSerializer

Every project these days tend to deal with some kind of serialization. I've Created a small pice of code to make my world simpler. How to create a Generic XmlSerializer.
public static class GenericXmlSerializer { public static T Deserialize(string xml) { var serializer = new XmlSerializer(typeof(T)); using (var sr = new StringReader(xml)) { return (T)serializer.Deserialize(sr); } } public static string Serialize(T source) { var serializer = new XmlSerializer(typeof(T)); using (var sr = new StringWriter()) { serializer.Serialize(sr, source); return sr.ToString(); } } }
My next problem is how to run my code. I've created a small example class for my example
public class Item
  {
  public string Name
  {get; set;}

  [XmlElement]
  public string[] Email
  { get; set; }

}
My production code for serialize/deserialize an instance of Item is displayed below.
--Serialize
var item = new Item {Name = "Authovr", Email = new string[] {"author1@gmail.com", "author2@gmail.com"}};
var xml = GenericXmlSerializer.Serialize(item);
--Deserialize
var xml = "<item><name>Author</name><email>author1@gmail.com</email><email>author2@gmail.com</email></item>";
var item = GenericXmlSerializer.Deserialize(xml);
Note!!
My example includes serializing an Array element. Using the XmlElement atteribute makes the serialization nice and readable.