Identifying assembly version conflicts

I got a ‘No way to resolve conflict between “System.Runtime.Serialization, Version=5.0.5.0…’ error recently after pulling out the latest code from the source control. The cause of this error was because projects in my solution were referring to different version of the same assembly. After searching on the net, I
found a great tool to check the assemblies referenced by my project. The tool is called AsmSpy written by Mike Hadlow. You can find it on http://mikehadlow.blogspot.com.au/2011/02/asmspy-little-tool-to-help-fix-assembly.html.

Unit test private methods?

There has been a lot of discussion about whether we should unit test private methods, which I find it very interesting to read on my spare time). However, in this post I am not going to add more arguments on this subject (I will leave it to your own discretion 🙂 ). Here, I am going to show an example on using PrivateObject class which can be handy if you need to test a private method or property or field. The class exists in Microsoft Visual Studio Unit Test and you can read on MSDN for more information. In short, this class gives access to private methods (and properties). Let’s say I have an Account class which I want to test:

public class Account
    {
        public decimal InterestRate { get; private set; }        
        private decimal _balance;
        private int _accountId;

        public Account(int accountId)
        {
            _accountId = accountId;
        }

        private void InitAccount()
        {
            //Populate Account details, i.e. current balance
        }

        public decimal GetBalanceWithInterest()
        {
            return _balance + GetInterest();
        }

        private decimal GetInterest()
        {
            return _balance*InterestRate;
        }
    }

If I want to test the GetInterest method, which is private, I could do the following:


 [TestMethod]
        public void GetInterest_ReturnsExpectedInterest()
        {
            decimal balance = 1000;
            decimal interestRate = (decimal) 0.05;
            decimal expectedInterest = 50;

            var acc = new Account(1000);
            var privateObject = new PrivateObject(acc);

            privateObject.SetField("_balance", balance);
            privateObject.SetProperty("InterestRate", interestRate);

            var interest = privateObject.Invoke("GetInterest");

            Assert.AreEqual(interest, expectedInterest);
        }

The example above invokes the private method without passing any arguments. To pass arguments, you can use an array of object as follows:


privateObject.Invoke("APrivateMethod", new object[] { param1, param2});

That’s it, quite simple isn’t 🙂

Building custom OData service on SharePoint 2010

Recently I had a task to build a custom OData service for SharePoint, so here are the steps:

First, need to make sure that ADO.Net data service framework is installed on SharePoint server:
ADO.Net for Windows 2008
Or
ADO.Net for Windows 2008 R2

After that, add the following references on the project:

  • System.ServiceModel
  • System.ServiceModel.Web
  • System.ServiceModel
  • System.Runtime.Serialization
  • System.Data.Services
  • System.Data.Services.Client
  • Microsoft.SharePoint.Client.ServerRuntime

The next step is to create a SharePoint Mapped Folder and then select ISAPI. This is the folder where we are going to create our .svc file. Open the svc file and make sure it uses MultipleBaseAddressDataServiceHostFactory.

<%@ ServiceHost Language="C#" Debug="true" Factory="Microsoft.SharePoint.Client.Services.MultipleBaseAddressDataServiceHostFactory, Microsoft.SharePoint.Client.ServerRuntime, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
    Service="TestODataService.EmployeeService,$SharePoint.Project.AssemblyFullName$" %>

In my project, I have created the following classes

[Serializable]
    [DataContractAttribute(IsReference = true)]
    [DataServiceKey("EmployeeId")]
    public class Employee
    {
        [DataMemberAttribute]
        public int EmployeeId { get; set; }

        [DataMemberAttribute]
        public string FirstName { get; set; }

        [DataMemberAttribute]
        public string LastName { get; set; }
    }
public class DataContext
    {
        public IQueryable<Employee> Employees
        {
            get
            {
                List<Employee> employeeList = EmployeeStore.GetEmployees();

                return employeeList.AsQueryable();
            }
        }

        
    }

In this case the DataContext class will be used as the data source type.

The last one is the EmployeeService itself, which inherits from DataService class

[BasicHttpBindingServiceMetadataExchangeEndpoint]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
    [System.ServiceModel.ServiceBehavior(IncludeExceptionDetailInFaults = true)]
    public class EmployeeService : DataService<DataContext>
    {
        [WebGet]
        public IQueryable<Employee> GetEmployeeByName(string name)
        {
            var searchResult = EmployeeStore.GetEmployees()
                                        .Where(e => e.FirstName.Contains(name) || e.LastName.Contains(name));

            return searchResult.AsQueryable();
        }

        public static void InitializeService(DataServiceConfiguration config)
        {
            config.SetEntitySetAccessRule("*", EntitySetRights.AllRead);
            config.SetServiceOperationAccessRule("*", ServiceOperationRights.AllRead);
            config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
        }
    }

Please note that I have set access to all entities and service operations to AllRead since I only need to read the data.

To consume the above service, we can add a service reference in our test project and use the url to the service, e.g.: http://localhost/_vti_bin/EmployeeService.svc

To get access to the entities, we can use the data context as below:

var ctx =
              new ServiceReference1.DataContext(new Uri("http://localhost/_vti_bin/employeeService.svc"));
            ctx.Credentials = System.Net.CredentialCache.DefaultCredentials;

            ctx.Employees.ToList().ForEach(e => Console.WriteLine(e.FirstName + " " + e.LastName));

To use the service operations:

var ctx =
              new ServiceReference1.DataContext(new Uri("http://localhost/_vti_bin/employeeService.svc"));
            ctx.Credentials = System.Net.CredentialCache.DefaultCredentials;
var query = ctx.CreateQuery<Employee>("GetEmployeeByName").AddQueryOption("name", "'Blogg'");
            var result = query.Execute();

            result.ToList().ForEach(e => Console.WriteLine(e.FirstName + " " + e.LastName));

Using SharePoint PeopleEditor user control

I had the chance to play with PeopleEditor user control on my previous project and just thought would be good to put another blog about it out there, so here you go:

Started with creating a visual web part and the next step is adding the control to the ascx page

<SharePoint:PeopleEditor ID="peUser" ValidatorEnabled="true" runat="server"
                        SelectionSet="User" Width="350px" IsValid="true" AllowTypeIn="true"
                        MultiSelect="true"></SharePoint:PeopleEditor>
<SharePoint:InputFormRequiredFieldValidator ID="rfvUser" 
                        SetFocusOnError="true" runat="server" ControlToValidate="peUser" BreakBefore="true"
                        ErrorMessage="Required field." EnableClientScript="false"
                        Display="Dynamic"></SharePoint:InputFormRequiredFieldValidator>

To get the selected users we can iterate through its resovedEntities property

for (index = 0; index <= peControl.ResolvedEntities.Count - 1; ++index)
{
    PickerEntity entity = (PickerEntity)peopleEdControl.ResolvedEntities[index];
    SelectedUser selectedUser = new SelectedUser(){ Id = Convert.ToInt32(entity.EntityData["SPUserID"])
                                                    , Name = entity.DisplayText
                                                    , LoginName = entity.Key };
    selectedUserList.Add(selectedUser);
}

To assign a value to PeopleEditor user control (in my case I use a string of login name separated by a semicolon)

string[] delimiter = { ";" };
string[] loginNames = loginNameString.Split(delimiter, StringSplitOptions.RemoveEmptyEntries);

foreach(string loginName in loginNames)
{
     PickerEntity pe = new PickerEntity();
     pe.Key = loginName;

     pe = peUser.ValidateEntity(pe);
     ArrayList entityList = new ArrayList() { pe };

     peUser.UpdateEntities(entityList);
}

Hope that helps 🙂

Create a new Wiki Page

The code below adds a new wiki page and then inserts a web part into the new page’s rich text editor

SPList pagesList = web.Lists["Pages"];

SPFolder rootFolder = pagesList.RootFolder;

SPFileCollection fileCollection = rootFolder.Files;

string pageUrl = rootFolder.ServerRelativeUrl + "/MyNewPage.aspx";

//Create the page
SPFile newFile = fileCollection.Add(pageUrl, SPTemplateFileType.WikiPage);

//Checkout and add custom web part to the newly created page
newFile.CheckOut();

//Use a new Guid as the web part id
Guid storageKey = Guid.NewGuid();

string wpId = String.Format("g_{0}", storageKey.ToString().Replace('-', '_'));

//Get web part manager
using (SPLimitedWebPartManager manager = newFile.GetLimitedWebPartManager(System.Web.UI.WebControls.WebParts.PersonalizationScope.Shared))

{

//Initialize the web part and insert it into 'wpz' web part zone.
//Web part zone is hidden in Rich text editor and its name is fixed ('wpz')

MyWebPart webPart = new MyWebPart();

webPart.ID = wpId;

webPart.Title = "My New Page";

manager.AddWebPart(webPart, "wpz", 0);

string content = String.Format(CultureInfo.InvariantCulture
, "<div class=\"ms-rtestate-read ms-rte-wpbox\" contentEditable=\"false\"><div class=\"ms-rtestate-read {0}\" id=\"div_{0}\"></div><div style='display:none' id=\"vid_{0}\"></div></div>"

, new object[] { storageKey.ToString("D") });

SPListItem item = newFile.Item;

item["WikiField"] = content;

item.Update();

}
newFile.CheckIn(string.Empty);

Hope that helps 🙂

Working with Oracle Object Types part 2

Following previous post about working with Types in Oracle, this post will focus on using the types from .Net.

The easiest way to map the Oracle Types is by using Oracle .Net Data Provider (ODP) to generate the class for you:
– Open Server Explorer (Tools – Server Explorer)
– Add new connection (right click Data Connections and choose add connection), set Data source to Oracle Database and Data provider to Oracle Data Provider for .Net
– Fill up some connection details and press Ok
– At this stage you should be able to see the mapping of every Oracle object in Server Explorer (well, maybe not everything)
– Go to User-Defined Types node and choose one of the Types
– Right click on the type, Generate Custom Class, follow the wizard and click Finish

From previous post, I got USER_TYPE and USER_TAB objects generated and to use those objects from .Net:

OracleConnection conn = NEW OracleConnection(connectionString);

IF (conn.State == ConnectionState.Closed)
{
conn.Open();
}

try
{
    OracleCommand oCmd = NEW OracleCommand();
    oCmd.CommandText = "USERPKG.GetUsers";
    oCmd.Connection = conn;
    oCmd.CommandType = CommandType.StoredProcedure;
    oCmd.BindByName = true;

    OracleParameter nameParam = oCmd.PARAMETERS.ADD("userId", OracleDbType.Int32);
    nameParam.Value = userId;
    nameParam.Direction = ParameterDirection.Input;

    OracleParameter listParam = NEW OracleParameter("USER_TAB", OracleDbType.OBJECT);
    listParam.Direction = ParameterDirection.ReturnValue;
    listParam.UdtTypeName = "USER_TAB";
    oCmd.PARAMETERS.INSERT(0, listParam);

    oCmd.ExecuteNonQuery();
    USER_TAB searchResult = (USER_TAB)oCmd.PARAMETERS["USER_TAB"].Value;
    RETURN searchResult;
}
finally
{
    IF (conn.State == ConnectionState.Open)
    {
        conn.Close();
    }
}

As we are using oracle type, the UdtTypeName needs to be declared. So far this is the easiest way that I can find to use Oracle data types from .Net 🙂

Convert a string or an integer to enum type

Something that I always use whenever I use enumeration :

public enum StatusType
	{
		Approved = 1,
		Pending = 2,
		Cancelled = 3
	}

Convert a string to enum :

string currentStatus = "Approved";
StatusType status = (StatusType) Enum.Parse(typeof(StatusType), currentStatus);

Convert an int to enum :

int currentStatusId = 1;
StatusType type = (StatusType) Enum.ToObject(typeof(StatusType), currentStatusId); 

Just be careful with enum conversion, especially when you want to use Enum.IsDefined method as it is very expensive.

Working with Oracle Object Types part 1

I have been working with Oracle db for the past few days and found out that I can store objects in a table. Basically I can create a table with only one column of type ‘TYPES’ but I wouldn’t go to that extent :).

Here is an example on creating a type

CREATE OR REPLACE
TYPE MYSCHEMA.USER_TYPE AS OBJECT
(
	ID INTEGER,
        FIRSTNAME VARCHAR2(20),
        SURNAME VARCHAR2(20)
);

We can also create a collection of Types based on existing Objects

CREATE OR REPLACE TYPE MYSCHEMA.USER_TAB  AS TABLE OF  USER_TYPE;

It’s getting more interesting when I know that I can pass the object or the collection of objects to a procedure just like a normal parameter. this means that I don’t have to do a loop in .Net side when dealing with a collection of objects.

FUNCTION GetUsers(
    userId IN User.ID%TYPE
) RETURN USER_TAB
AS
  returnTab   USER_TAB;
BEGIN
    SELECT   USER_TYPE(
                ID,
                FIRSTNAME,
                SURNAME)
        BULK COLLECT
        INTO returnTab
        FROM
            USER
        WHERE
            ID = userId;

    RETURN returnTab;
END; 

Retrieving a list from Oracle function

I have spent a few hours trying to figure out how to get the return value from an oracle function and the only thing that I got was something like ” <function name> is not a procedure or defined “.

The problem was not from my function, to retrieve the returned cursor from the function we have to insert an output parameter as the first parameter.

OracleParameter refCursor = new OracleParameter();

refCursor.OracleDbType = OracleDbType.RefCursor;

refCursor.Direction = ParameterDirection.ReturnValue;

oracleCommand.Parameters.Insert(0, refCursor);

Asynchronous processing in ASP.Net using delegate

There are times when we need to get the control of the UI after telling the server to do something, i.e. Bulk upload.  The example below uses delegate to return the control after extracting a large file:

public delegate string ExtractFile(Stream fs);

public void Run(Stream fs)
{
ExtractFile ef = new ExtractFile(ProcessFile);
ef.BeginInvoke(fs, new AsyncCallback(ProcessFileEnd), ef);
}
private string ProcessFile(Stream fileStream)
{
string message = DoSomething();

return message;
}

void ProcessFileEnd(IAsyncResult result)
{
ExtractFile ret = result.AsyncState as ExtractFile;

string message = ret.EndInvoke(result);
}

Notice that I use AsyncCallback when calling the beginInvoke. This can be used if we want to do something after the long task. However I haven’t found a good way to update the UI in ASP.Net -_-