29 diciembre 2009

An error has occured which stops Business Contact manager for Outlook from starting

You install BCM successfully, you start Outlook normally, a dialog to configure BCM turns into the screen, you follow the wizard and at the end of the process you receive the following message which prevents from configuring:

An error has occured which stops Business Contact manager for Outlook from starting.

Try the following: run Outlook as administrator, only once. It worked for me.

My configuration: W7 32 bits + Office 2007 + BCM

20 diciembre 2009

BPOS: Application is unable to connect; if this problem persists, contact your service administrator

Configuring the BPOS Sign in tool the following message appears:

  • Application is unable to connect;  if this problem persists, contact your service administrator.
  • La aplicación no puede conectarse; si el problema persiste, contacte con su administrador.

The root of the problem is a miss-configuration of the permissions of the certificates store. To solve it try the following command (run it from an admin account):

cacls "%appdata%\Microsoft\Crypto\RSA" /t /e /c /g %userdomain%\%username%:F

Solution originally posted here: http://social.technet.microsoft.com/Forums/en/onlineservicessigninapplication/thread/548c57b4-dc62-4638-9e81-57eabc8af6d2

28 noviembre 2009

Using a GridView only with code in a SharePoint (2007) WebPart, or in asp.net

(Without using SmartPart)

Using a GridView binded to a (Sql)DataSource is pretty easy in a asp.net application where we can drag and drop the components onto the designer, and follow the related wizards. However, this is not that easy in a SharePoint WebPart, as we have to do everything programmatically.

My objective was creating a grid in a WebPart in which one of the columns was editable, with a drop down list. I started playing with the WebPart, but as the problem was how to use the components by code I switched to a asp.net application, to make it work. What I am presenting here is how to create a GridView linked to a SqlDataSource by code. Moving this to a WebPart is trivial.

First of all the scenario:

  • We are going to create a GridView.
  • Linked to a SqlDataSource
  • We are going to use Northwind database.
  • We will present the Products table, only two fields for simplicity:
    • ProductId: readonly
    • SupplierId: editable with a combo

To better illustrate the example below you have two screenshots. The first one is the GridView showing all the values. The second one is the GridView in editing mode, with the drop down list on the supplier column.

image image

As I told you to make it easy I started creating an asp.net application. As we want to do everything by code I just added a simple Panel to dinamically add the GridView inside afterwards.

    1 <%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %>

    2 

    3 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

    4 

    5 <html xmlns="http://www.w3.org/1999/xhtml">

    6 <head runat="server">

    7     <title></title>

    8 </head>

    9 <body>

   10     <form id="form1" runat="server">

   11         <asp:Panel ID="Panel1" runat="server"/>

   12     </form>

   13 </body>

   14 </html>

In the code behind is where we find the interesting part. Here you have the using statements I needed.

    1 using System;

    2 using System.Collections.Generic;

    3 using System.Linq;

    4 using System.Web;

    5 using System.Web.UI;

    6 using System.Web.UI.WebControls;

    7 using System.Data;

    8 using System.Data.SqlClient;

    9 using System.Collections.Specialized;

   10 

 

This is the Page definition. In case of a WebPart this would be a child class of the asp.net WebPart class. We will need to use both a SqlDataSource and a GridView in many events, so we declare them globally and we create them.

To bind data to a GridView there are many other ways, but SqlDataSource just streamlines all the operations of selecting and modifying data to the database.

Please do not take into account I didn’t follow any naming conventions and some good practices were just ignored –I just created it to discover how to make it work.

 

 

   11 public partial class _Default : System.Web.UI.Page

   12 {

   13     SqlDataSource sqlSource = new SqlDataSource();

   14     GridView datagrid = new GridView();

   15 

   16 

 

According to MSDN documentation the event to create controls is PreInit, so we will configure the GridView and SqlDataSource properties here. I was not sure if the Init method would be suitable to do this too; if someone wants to post his/her opinion it will be appreciated. In a WebPart the equivalent to this event is OnPreInit –just write down override inside the class definition and Intellisense will show you the event signature.

First of all we create the SqlDataSource. Some tips to avoid weird errors, and annotations:

  • Remember to add the SqlDataSource control to the Controls matrix.
  • Obviously, substitute the connection string with a suitable one for you, as well as the select and update commands. Remember to add the parameters if you change them.
  • UpdateCommand, DeleteCommand and InsertCommand are actually optional. In this example I just implemented UpdateCommand, because it was the only operation (appart from selecting) that I needed.
  • Notice that we set an ID of the control.

 

   17     protected void Page_PreInit(object sender, EventArgs e)

   18     {

   19         sqlSource.ConnectionString = "Data Source=MUNTANER\\sqlexpress;Initial Catalog=Northwind;Integrated Security=True";

   20         sqlSource.SelectCommand = "SELECT [ProductID], [SupplierID] FROM [Products]";

   21         sqlSource.UpdateCommand = "UPDATE [Products] SET [SupplierID] = @SupplierID WHERE [ProductID] = @ProductID";

   22         //DeleteCommand="DELETE FROM [Products] WHERE [ProductID] = @ProductID"

   23         //InsertCommand="INSERT INTO [Products] ([SupplierID]) VALUES (@SupplierID)"

   24         sqlSource.UpdateParameters.Add(new Parameter("supplierid", System.TypeCode.Int32));

   25         sqlSource.UpdateParameters.Add(new Parameter("productid", System.TypeCode.Int32));

   26         sqlSource.ID = "sqlSource";

   27         Controls.Add(sqlSource);

   28 

 

After configuring the SqlDataSource we configure the GridView. A GridView is composed of a sequence of fields (columns). We could make the GridView to create them automatically, but then we could not use a dropdownlist for the Supplier field (instead I think it always present a Textbox). Therefore we set the attribute AutoGenerateColumns to false and we create:

  • One CommandField, the column with the edit button.
  • One BoundField, the column with the ID. A boundField is the default field type. It just displays information and it presents a textbox to edit it. In this case we set it readonly, as we do not want to edit it.
  • One TemplateField. If we want to use custom controls in a column we have to use this kind of field. A template field has templates for some usages of the field, for example a template when it is presented without editing (Item template) and a template when it is in edit mode (EditItemTemplate). There are more templates to be customized, such as Header and Footer templates. Here we find one of the tricky aspects we we use GridView in code: we have to create a template field, which means we have to create a class following a special interface. We will see it after.
  • Some configurations of the GridView I used:
    • As I told you: AutoGenerateColumns must be false.
    • DataKeyNames: this is the primary key of the table. I think it should be mandatory, but I didn’t try to run the example without setting this property.
    • AllowSorting: optional; it creates a link on the headers to sort the columns.
    • Be very careful on this attribute: DataSourceID. We use it to bind with the datasource. There is something very weird on this: I tried to set the property DataSource  with the variable sqlSource and do a DataBind (which is for me the normal way) but it didn’t work. But setting it with the ID it does work. I do not understand why, if anyone has the solution it will be appreciated.

As I told you before remember to add the GridView to the Controls matrix.

 

   29         // Columna 0

   30         CommandField buttons = new CommandField();

   31         buttons.ShowEditButton = true;

   32         datagrid.Columns.Add(buttons);

   33 

   34         // Columna 1

   35         BoundField productIdField = new BoundField();

   36         productIdField.HeaderText = "Product";

   37         productIdField.DataField = "productid";

   38         productIdField.SortExpression = "productid";

   39         productIdField.InsertVisible = false;

   40         productIdField.ReadOnly = true;

   41         datagrid.Columns.Add(productIdField);

   42 

   43         // Columna 2   

   44         TemplateField comboField = new TemplateField();

   45         comboField.HeaderText = "Supplier";

   46         comboField.SortExpression = "supplierid";

   47         comboField.ItemTemplate = new ComboTemplate(ListItemType.Item, "supplierid");

   48         comboField.EditItemTemplate = new ComboTemplate(ListItemType.EditItem, "supplierid");        

   49         datagrid.Columns.Add(comboField);

   50 

   51         datagrid.AutoGenerateColumns = false;

   52         datagrid.DataKeyNames = new string[] { "productid" };

   53         datagrid.AllowSorting = true;

   54         datagrid.DataSourceID = "sqlSource";    

   55         Panel1.Controls.Add(datagrid);

   56     }

 

This is the template class. One of the tricky things I had to discover is that it has to implement IBindableTemplate. Be careful as in MSDN there is an example with ITemplate, which works fine to show information but it is not suitable to return back information when the user changes it in editing mode.

Most important to understand about this class is:

  • There is a method called InstantiateIn (automatically created by Visual Studio when the interface is created). Here is where we are going to create the control in Item mode, Edit mode or others. In our example in Item mode we will create a simple literal, and in edit mode a dropdownlist.
  • ExtractValues method is where we push back the user changes in edit mode.
  • We facilitate the usage of the templates by storing the template type (Item, Edit, other) and the column name which relates the information (in the database, in our case). This information is initialized in the constructor of the class.

Here you can see the class definition, the class members and the constructor. The DropDownList must be a class member as it is used in some events.

 

   57 

   58     public class ComboTemplate : IBindableTemplate

   59     {

   60         ListItemType templateType;

   61         string columnName;

   62         DropDownList ddl = new DropDownList();

   63 

   64 

   65         public ComboTemplate(ListItemType type, string colname)

   66         {

   67             templateType = type;

   68             columnName = colname;

   69         }

   70 

 

Maybe you should read this part after you have understood instantiateIn. Here is where we create the data binding between the literal, in item mode, and the database information.

To do this we use the DataBinding event. This event occurs when the binding should be done. To be sincere I copied and pasted this code from a MSDN example of DataBinding, and it worked. I guess what the code does: it stores the database value by using a DataBinder object and evaluating the data of the container, and taken the given column… but I do not understand fully the details, so I can not really explain you (again if someone knows…).

What you should care in this method is the type of control you use for assigning the value. If you use a Literal control its ok; if you instead use another control (such a Label) you should cast the sender to a Label type (or the appropriate one for you). Maybe you should change as well the lc.Text line accordingly.

 

   71         void lc_DataBinding(object sender, EventArgs e)

   72         {

   73             Literal lc = (Literal)sender;

   74             GridViewRow container = (GridViewRow)lc.NamingContainer;

   75             object dataValue = DataBinder.Eval(container.DataItem, columnName);

   76             if (dataValue != DBNull.Value)

   77             {

   78                 lc.Text = dataValue.ToString();

   79             }

   80         }       

   81 

 

ExtractValues is the method to push back the changed information to the SqlDataSource. It gets the value and assigns to a newly created dictionary (the method expects a hashtable to be returned).

 

Be careful if you do not use a DropDownList to change the 88th line. In this line you should assign the data that the user has edited.

 

   82         #region IBindableTemplate Members

   83 

   84         System.Collections.Specialized.IOrderedDictionary IBindableTemplate.ExtractValues(Control container)

   85         {

   86             OrderedDictionary dict = new OrderedDictionary();

   87 

   88             string value = ddl.SelectedValue.ToString();

   89             dict.Add(columnName, value);

   90 

   91             return dict;

   92         }

   93 

   94         #endregion

   95 

   96         #region ITemplate Members

   97 

 

InstantiateIn is the method that creates the controls. As we designed the class to allow many templates to be created, it checks which template should be created and it creates a control according to it.

 

The only interesting ones for this example are:

  • Item template: it creates a Literal control. To databind this literal control DataBinding event must be implemented (see upwards). Remember to add it to the container Controls array.
  • EditItem: it creates a DropDownList control. When we edit our combo should show us a list of suppliers, which actually is not the same datasource as our GridView (products). Here a new SqlDataSource with a select query for suppliers should be done, but with the aim of reducing the amount of code the same datasource as before is used. If you try this example you will see that the dropdown show a lot of suppliers, and repetitions of them, as it actually queries the column suppliers of the product table. But as I told you the aim of this was just learning about how to use it.

 

   98         public void InstantiateIn(System.Web.UI.Control container)

   99         {

  100             Literal lc = new Literal();

  101             switch (templateType)

  102             {

  103                 case ListItemType.Header:

  104                     lc.Text = "<B>" + columnName + "</B>";

  105                     container.Controls.Add(lc);

  106                     break;

  107                 case ListItemType.Item:

  108                     lc.DataBinding += new EventHandler(lc_DataBinding);

  109                     container.Controls.Add(lc);

  110                     break;

  111                 case ListItemType.EditItem:

  112                     ddl.DataSourceID = "sqlSource";

  113                     ddl.DataTextField = "supplierid";

  114                     ddl.DataValueField = "supplierid";

  115                     container.Controls.Add(ddl);

  116                     break;

  117                 case ListItemType.Footer:

  118                     lc.Text = "<I>" + columnName + "</I>";

  119                     container.Controls.Add(lc);

  120                     break;

  121             }

  122         }       

  123 

  124         #endregion

  125     }

  126 

 

That’s all, what it comes now is not necessary for the example.

 

I also did a trial with a TextBox template; I just posted it just in case it is useful for someone.

 

  127     public class TexBoxTemplate : IBindableTemplate

  128     {

  129         ListItemType templateType;

  130         string columnName;

  131         TextBox tb = new TextBox();

  132 

  133 

  134         public TexBoxTemplate(ListItemType type, string colname)

  135         {

  136             templateType = type;

  137             columnName = colname;

  138         }

  139 

  140         void lc_DataBinding(object sender, EventArgs e)

  141         {

  142             Literal lc = (Literal)sender;

  143             GridViewRow container = (GridViewRow)lc.NamingContainer;

  144             object dataValue = DataBinder.Eval(container.DataItem, columnName);

  145             if (dataValue != DBNull.Value)

  146             {

  147                 lc.Text = dataValue.ToString();

  148             }

  149         }

  150 

  151         void tb_DataBinding(object sender, EventArgs e)

  152         {

  153             TextBox lc = (TextBox)sender;

  154             GridViewRow container = (GridViewRow)lc.NamingContainer;

  155             object dataValue = DataBinder.Eval(container.DataItem, columnName);

  156             if (dataValue != DBNull.Value)

  157             {

  158                 lc.Text = dataValue.ToString();

  159             }

  160         }

  161 

  162         #region IBindableTemplate Members

  163 

  164         System.Collections.Specialized.IOrderedDictionary IBindableTemplate.ExtractValues(Control container)

  165         {

  166             OrderedDictionary dict = new OrderedDictionary();

  167 

  168             string value = tb.Text;

  169             dict.Add(columnName, value);

  170 

  171             return dict;

  172         }

  173 

  174         #endregion

  175 

  176         #region ITemplate Members

  177 

  178         public void InstantiateIn(System.Web.UI.Control container)

  179         {

  180             Literal lc = new Literal();

  181             switch (templateType)

  182             {

  183                 case ListItemType.Header:

  184                     lc.Text = "<B>" + columnName + "</B>";

  185                     container.Controls.Add(lc);

  186                     break;

  187                 case ListItemType.Item:

  188                     lc.DataBinding += new EventHandler(lc_DataBinding);

  189                     container.Controls.Add(lc);

  190                     break;

  191                 case ListItemType.EditItem:                   

  192                     tb.DataBinding += new EventHandler(tb_DataBinding);

  193                     container.Controls.Add(tb);

  194                     break;

  195                 case ListItemType.Footer:

  196                     lc.Text = "<I>" + columnName + "</I>";

  197                     container.Controls.Add(lc);

  198                     break;

  199             }

  200         }

  201 

  202         #endregion

  203     }

  204 

  205 }

I hope this helps to anyone that needs to use GridView programmatically in a WebPart or asp.net application.

04 junio 2009

Recursos de MOSS2007 para Project Managers

Planificación y metodología

Arquitectura y diseño tecnológico

Aceleradores de desarrollo

29 marzo 2009

Generic code to serialize a DataTable

Just add this code in your project, and call to the XmlSerialize solution:

///
/// Gets the XML of the passed object.
///

public static string XmlSerialize(object obj)
{
// Validate argument 'obj'
if (obj == null)
throw new ArgumentNullException("obj", "Argument 'obj' is null");

XmlSerializer ser = new XmlSerializer(obj.GetType());
UTF8Encoding utf8 = new UTF8Encoding(false, false);
string xml = null;

using (MemoryStream ms = new MemoryStream())
{
using (StreamWriter sw = new StreamWriter(ms, utf8))
{
ser.Serialize(sw, obj);
xml = utf8.GetString(ms.GetBuffer());
}
}

return xml;
}




17 febrero 2009

Microsoft en el Mobile World Congress

A parte de la visita de Steve Ballmer, que después de algunas presentaciones
un tanto estrafalarias aparece en los cursos de oradores (recordemos
http://www.youtube.com/watch?v=wvsboPUjrGc), la atención de esta edición del
Mobile World Congress se me la ha llevado un par de novedades.

HTC continua sorprendiéndoos en positivo con dos magníficos teléfonos: la
HTC Diamond 2
y la HTC Touch Dual
.

Por cierto que ambos teléfonos llavan preinstalados la segunda novedad que
destaco: Windows Mobile 6.5. Aunque mejor que sus predecesores, Microsoft
parece ser que lo único que puede hacer por el momento es seguir los pasos
(muy evidentemente por detrás) del famoso iPhone. No obstante, aparte de lo
obvio (interfaz táctil) se empieza a ver un filón de algo interesante de lo
que probablemente pueda ser un factor diferencial en los próximos meses o
próximas versiones: la sincronización de datos entre todos los dispositivos.
Si no conocéis todavía la tecnología Live Mesh os recomiendo que la provéis
(es gratuita) (Live Mesh Website).

01 febrero 2009

Infopath and Forms Server: Schema validation found non-datatype errors

While developing a browser enabled Infopath 2007 Form with code I got this
error: " Schema validation found non-datatype errors".

The error was thrown when I tried to set a field of the form to a blank
value (String.Empty).

XPathNavigator nav =
this.MainDataSource.CreateNavigator().SelectSingleNode("/my:" +
DATASOURCE_ROOT + "/my:" + field, NamespaceManager);

Nav.SetValue(value);

After many times of trial and error I found that the problem was actually to
set a value to a field that had not had yet a value, so just making this
check was enough:

if (nav.Value != value)
{
nav.SetValue(value);
}

I.e. if the value is still empty and I want to set String.Empty it actually
does nothing.

31 enero 2009

This site may harm your computer - a Google's bug?

No matter the search I do just below each link in Google there is another
which says "This site may harm your computer", and if I want to browse it
I get a big advert from Google. May this be a Google search bug?

The first image shows a search of "Microsoft", and the second one the
message I get when I click the link.