SharePoint Dragons

Nikander & Margriet on SharePoint

SPMetal looses spaces in choice field

Recently, we were creating a web part that displays entities generated with SPMetal. One of the columns is a status field called MyStatus of type Choice. In the display, it just shows “InReview”, when the actual value is “In Review”.

The code does something similar to this:

using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
using System.Linq;

namespace VisualWebPartProject1.VisualWebPart1
{
    public partial class VisualWebPart1UserControl : UserControl
    {
        AstroDataContext dc = new AstroDataContext(SPContext.Current.Web.Url);
        protected override void OnPreRender(EventArgs e)
        {
            var query = (from item in dc.MyPrintList
                                     select item).ToList<MyPrintBaseType>();

            gvOverview.AutoGenerateColumns = false;
            gvOverview.DataSource = query;
            gvOverview.DataBind();
        }
    }
}

The declarative part looks something like this:

<asp:GridView runat=”server” ID=”gvOverview” AllowPaging=”False”>
    <Columns>
        <asp:TemplateField HeaderText=”Print”>
            <ItemTemplate>
                <input type=”checkbox” id=’chkAvail<%#DataBinder.Eval(Container.DataItem, “Id”)%>’
                    value='<%#DataBinder.Eval(Container.DataItem, “Id”)%>’ checked />
            </ItemTemplate>
        </asp:TemplateField>
        <asp:BoundField HeaderText=”ID” DataField=”ID” />
        <asp:BoundField HeaderText=”Title” DataField=”Title” />           
        <asp:TemplateField HeaderText=”Status”>
            <ItemTemplate>
                <div id=”divStatus<%#DataBinder.Eval(Container.DataItem, “Id”)%>”>
                <%#DataBinder.Eval(Container.DataItem, “MyStatus”)%>                   
                </div>
            </ItemTemplate>
        </asp:TemplateField>

        <asp:TemplateField HeaderText=”Date”>
            <ItemTemplate>
                <asp:Label ID=”Label1″ Text='<%#DataBinder.Eval(Container.DataItem, “MyDate”,”{0:dd-MM-yyyy}”)%>’
                    runat=”server” />
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>

This result be seen in the next figure.

image

So, somebody stole our spaces! Our immediate response to this brutal case of space theft was to find the bandit responsible for this. We had one main suspect…

SPMetal! When we took a look at the code generated by SPMetal, it’s quite clear why the spaces are missing. The original, full-blown, values are stored as attributes in the MyStatus enumeration. However, the actual names within the enumeration, as generated by SPMetal, are used when displayed in the SPGridView:

public enum MyStatus : int {

None = 0,

Invalid = 1,

[Microsoft.SharePoint.Linq.ChoiceAttribute(Value=”Unread”)]
Unread = 2,

[Microsoft.SharePoint.Linq.ChoiceAttribute(Value=”In Review”)]
InReview = 4,

[Microsoft.SharePoint.Linq.ChoiceAttribute(Value=”Accepted”)]
Accepted = 8,

[Microsoft.SharePoint.Linq.ChoiceAttribute(Value=”Denied”)]
Denied = 16,

[Microsoft.SharePoint.Linq.ChoiceAttribute(Value=”Remark”)]
Remark = 32,
}

 

As is explained in http://msdn.microsoft.com/en-us/library/ee537010.aspx , this is normal behavior. Since SPMetal generates partial classes, one way to get around it is to create a partial class for the entity representing your content type that provides a method or property that returns the attribute associated with a given enumeration value. Another way would be to generate an extension method that does the same. The implementation of such an extension method is shown in the answer in thread http://sharepoint.stackexchange.com/questions/21750/frustrated-linq-to-sharepoint-choice-values-losing-spaces .

Another way, and we guess the cleanest way if you’re only reading data, is to override the SPMetal defaults by using a Parameters XML file. See http://msdn.microsoft.com/en-us/library/ee535056.aspx for details.

In our case, we’ve saved the following XML in a file called params.xml:

<?xml version=”1.0″ encoding=”utf-8″?>
<Web xmlns=”http://schemas.microsoft.com/SharePoint/2009/spmetal”>
  <ContentType Name=”MyPrintBaseType” Class=”MyPrintBaseType”>
    <Column Name=”MyStatus” Member=”MyStatus” Type=”String” />
  </ContentType>
</Web>

This XML file says that we want to convert our MyStatus field to the type of String, which causes the original values to be included. See http://blogs.msdn.com/b/sharepointdev/archive/2011/05/03/using-linq-to-sharepoint-with-choice-fields.aspx , it also discusses a scenario where you want to write to a choice field too.

Then, we’ve generated our entities anew using the parameters XML file:

spmetal /web:http://astro /code:Astro.cs /parameters:params.xml

The end result meets our needs:

image

One response to “SPMetal looses spaces in choice field

  1. Pingback: Link Resource # 54 : May 11 – May 17 « Dactylonomy of Web Resource

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: