SharePoint 2013 and Windows Server 2012 R2 – developer’s way

Yesterday I’ve tried to install SharePoint 2013 on Windows Server 2012 R2. Prerequisites installer run and suddenly it crashed on step ‚Application Server Role, Web Server (IIS) Role’. But wait, that is something new – never before had such a problem. Manual installation of Web Server Role also didn’t help – installer had just been stuck on this step. Just figured out that my last successful installation of SharePoint 2013 has been performed on Windows Server 2012 but not R2. Why bother then … for developer purposes only final result matters, so reverting back to Windows Server 2012 feels ok to me.

Rails installation on Ubuntu

In this post I would like to share with you with a quick description of how to install Rails 4.0 on Ubuntu.

Simple steps after opening a terminal:

1. sudo apt-get update

2. sudo apt-get install apache2 curl git libmysqlclient-dev mysql-server nodejs

3. sudo apt-get install ruby1.9.3

4. sudo gem install rails –version 4.0.0 –no-ri –no-rdoc

5. sudo apt-get install sqlite3 libsqlite3-dev

6. Open .bashrc in user’s home folder and at the add the following line – „source .rvm/scripts/rvm”

This steps have worked for me and this description is mostly based on description provided in „Agile Web Development with Rails 4” book. Please note that this steps might not be a best practice, however for basic Rails installation for dev purposes are sufficient.

Internet Explorer – bookmarks search

I was always wondering if there’s an option to search in Internet Explorer bookmarks. Recently I’ve found the following answer: open windows explorer and in current folder path just enter „shell:favorites” – then in search box you can enter any phrase in order to search in your bookmarks. Quite life saver, especially if you have so many bookmars as I have 😉

Sublime Text 2 on Ubuntu

My text editor choice is Sublime Text 2 (for all operating systems). It should be sufficient for my current needs, but in future I would like to get to know Vim also.

Anyway, I’ve found this great post how to setup Sublime Text 2 on Ubuntu, along with adding it to Unity Dashboard.

http://www.technoreply.com/how-to-install-sublime-text-2-on-ubuntu-12-04-unity/

 

Btw. in order to improve speed of dashboard search, I highly recommend disabling online search results. You can do this by searching for ‚Security & Privacy’, then go to search tab and move the slider so that it shows ‚off’ value.

Ubuntu and VirtualBox

Every time Canonical releases new version of Ubuntu I give it a try. Every new version gets better and better and this time I felt that it requires more attention from me.

So I’ve installed the latest Ubuntu 13.10 (Saucy Salamander) on VirtualBox (these days I’m a huge fan of virtualization). However from my perspective with Linux there are always problems. This time was no different. The biggest problem I have with many virtualization platforms is to have it work in fullscreen mode. It always ends up with searching and reading many posts in the Internet, which doesn’t help in any case.

This time, in one of posts, I’ve found a solution. It seems like Ubuntu (probably many other distros also) requires proper VBox version also in order to get Guest Additions working correctly. For me installation of 4.2.18 did the trick and with Guest Additions installed user experience is pretty good.

English posts

I’ve decided to continue blogging in English. This is because I feel that I need to improve my English skills. No one is perfect but in order to master any skill then you have to practise.

This is my personal blog, so if you don’t like my language or you want to point my grammar mistakes etc. then please don’t read it, quote or link it.

SharePoint–rozwiązywanie konfliktów zapisu

Jednym z częstych problemów występujących podczas developmentu rozwiązania dla SharePoint jest występowanie konfliktów zapisu. Sytuacja taka zachodzi gdy dopuszczona zostanie sytuacja w której dwóch lub więcej użytkowników może zmienić zawartość elementu listy jednocześnie (czy to poprzez wybraną architekturę rozwiązania, czy też przez błąd w kodzie). Problemem w stwierdzeniu (a właściwie uwierzeniu w to), że występuje konflikt zapisu, zwłaszcza przez początkujących jest komunikat występujący w tym przypadku. Zobaczmy zatem taką sytuację na przykładzie oraz potencjalny sposób jej rozwiązania.

W zaprezentowanym poniżej przykładzie zasymulowana została sytuacja próby jednoczesnej aktualizacji elementu listy przez dwóch użytkowników:

public partial class InitialPage : LayoutsPageBase
 {
    private SPList _employeesList; 
    public SPList EmployeesList
    {
        get
        {
            if (_employeesList != null)
            {
                return _employeesList;
            }
 
            return Web.GetList(string.Format("{0}{1}", Web.ServerRelativeUrl, "/Lists/EmployeesList")); 
        }
    }
 
    protected void Page_Load(object sender, EventArgs e)
    {
        try
        {
            if (Page.IsPostBack)
            {
                // clear error message
                lblErrorMessage.Text = string.Empty; 
            }
        }
        catch (Exception ex)
        {
            ShowErrorMessage(ex);
        }
    }
 
    /// <summary>
    /// Adds one item to list
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void btnPopulateList_Click(object sender, EventArgs e)
    {
        try
        {
            SPListItem item = EmployeesList.AddItem();
            
            item[SPBuiltInFieldId.Title] = "First";
            item.Update(); 
        }
        catch (Exception ex)
        {
            ShowErrorMessage(ex);
        }
    }
 
    private void ShowErrorMessage(Exception ex)
    {
        lblErrorMessage.Text = ex.Message; 
    }
}
 

Powyższy kod jest wycinkiem dla utworzonego Application Page, przygotowującym do właściwych operacji. Przy deployu tworzona jest lista o nazwie “EmployeesList”, która po wciśnięciu przycisku “Populate list” wstawia na listę element o tytule “First”.

Zobaczmy teraz kod właściwy dla aktualizacji elementu listy przez dwóch użytkowników:

protected void btnSave_Click(object sender, EventArgs e)
{
    try
    {
        string name = txtName.Text.Trim();
        if (string.IsNullOrEmpty(name))
        {
            return;
        }
 
        // Simulate situation where two users try to update the same item at once
        SPListItem firstUserItem = EmployeesList.GetItemById(1);
        SPListItem secondUserItem = EmployeesList.GetItemById(1);
 
        // Try to update item 
        firstUserItem[SPBuiltInFieldId.Title] = name;
        secondUserItem[SPBuiltInFieldId.Title] = "concurrent change";
 
        firstUserItem.Update(); // ok - I was first
        secondUserItem.Update(); // error - save conflict
 
        // If exception not thrown then show message
        lblErrorMessage.Text = "Title of item has been changed";
    }
    catch (SPException ex)
    {
        ShowErrorMessage(ex); 
    }
    catch (Exception ex)
    {
        ShowErrorMessage(ex);
    }
}
Dla pierwszego użytkownika będziemy próbowali zmienić tytuł pobranego elementu na wpisany ciąg znaków do pola tekstowego. Drugi natomiast będzie próbował zmienić tytuł stałym wpisem “concurrent change”. Konflikt zapisu wystąpi w tym przypadku ponieważ dwóch użytkowników pobrało ten sam element z listy, pierwszy z nich zmienił tytuł i zdążył wykonać update na elemencie, zanim wykonał tę samą operację drugi. Zobaczmy jak to wygląda w praktyce:

conflict

Do pola tekstowego wpisany został tekst “changed by first”. Ze względu na to, że wystąpił konflikt zapisu dla drugiego użytkownika, który próbował zapisać tekst “concurrent change”, na liście pojawi się tekst wpisany do pola tekstowego:

conflict result

Rozwiązaniem dla konfliktu zapisu jest ponowienie operacji zapisu, z zaznaczeniem jednak, że element na którym chcemy wykonać operację musi posiadać aktualne dane zapisane do bazy contentowej. Element taki musi zatem zostać pobrany z listy ponownie w sytuacji kiedy wystąpił konflikt i jeśli ponownie nie zmieni on swoich danych w trakcie zapisu operacja zapisu powiedzie się. Wykrycie konfliktu zapisu następuje poprzez wyłapanie wyjątku typu SPException. Zobaczmy zatem odpowiednią modyfikację kodu dla zdarzenia btnSave_Click:

 

try
{
    // ... existing not modified coded
}
catch (SPException ex)
{
    // Exception has been thrown but that gave second user chance to update item once again 
    SPListItem secondUserConflictedItem = EmployeesList.GetItemById(1); 
    secondUserConflictedItem[SPBuiltInFieldId.Title] = "Save conflict but i'm gonna win :)";
    secondUserConflictedItem.Update();
}
catch (Exception ex)
{
    ShowErrorMessage(ex);
}
 

Po wyłapaniu wyjątku i zapisaniu zmian powinniśmy na liście zobaczyć zamiast tytułu elementu “changed by first” wstawiony w tym bloku tekst “Save conflict but i’m gonna win : )” :

second user wins