Showing posts with label CAML. Show all posts
Showing posts with label CAML. Show all posts

May 28, 2009

Content Types Inheritance: How to remove a field inherited from the parent in CAML

As you know, you can inherit from a Content Type in CAML simply in specifying a valid ID. Typically, to inherit from an existing Content Type, you have to respect the following rule: Parent content type ID + "00" + hexadecimal GUID
e.g.: 0x01 (ID of the Item Content Type) + 00 + 21D64BFAA43542c0B10CB673D6445495

The problem when inheriting is that you don't specially need all fields from the parent. To remove a field inherited from the parent, you have to use the RemoveFieldRef tag in specifying the ID of the field.

In the following example, I inherit from the Item Content Type but I add two new fields (Year and Amount) and I remove the Title field:


<?xml version="1.0" encoding="utf-8" ?>

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">

    <ContentType ID="0x010021D64BFAA43542c0B10CB673D6445495"

          Name="Budget"

          Description="Create a new budget"

          Version="0"

          Group="My Inherited Content Types" >

        <FieldRefs>

            <RemoveFieldRef ID="{fa564e0f-0c70-4ab9-b863-0177e6ddd247}"/>

            <FieldRef DisplayName="Year" ID="{6FC684B4-CE06-480f-A8A5-E62277AAFB79}" Name="Year_MICT" />

            <FieldRef DisplayName="Amount" ID="{A4D2A891-27D6-4f5d-B5C2-4A9AC4D2000D}" Name="Amount_MICT" />

        </FieldRefs>

    </ContentType>

</Elements>


Have a look on the following MSDN links to understand how Content Types work:
Base Content Type Hierarchy: http://msdn.microsoft.com/en-us/library/ms452896.aspx
Content Type IDs: http://msdn.microsoft.com/en-us/library/aa543822.aspx
Creating Content Types Based on Other Content Types: http://msdn.microsoft.com/en-us/library/ms460224.aspx<

December 16, 2008

Issue: SPQuery doesn't return items from sub-folders

In using SPQuery object to get specific items from a list, you will see that it returns only the items from the root folder. To get also items from sub-folders, you have to set ViewAttributes with "Scope='RecursiveAll'" like in the following piece of code.

using (SPSite mySiteCollection = new SPSite("http://myserver/myspsite"))
{
    using (SPWeb mySite = mySiteCollection.OpenWeb(mySiteCollection.RootWeb.ID))
    {
        SPList studentsList = mySite.Lists["Students"];
        SPQuery query = new SPQuery();
        query.ViewAttributes = "Scope='RecursiveAll'";
        SPListItemCollection items = studentsList.GetItems(query);
    }
}

December 08, 2008

How to set custom forms (new, edit and display) for a specific content type by CAML definition

Let's imagine a content type e.g. Student and you want to set custom forms for it (new, edit and display). The custom forms have to be declared under the XmlDocuments node of the content type CAML definition.

<?xml version="1.0" encoding="utf-8" ?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <ContentType
        ID="0x01004037ADCF3A5C4b648FFC4DA96C965CDE"
        Name="Student"
        Description="Create a new student"
        Version="0"
        Group="Custom Content Types" >
    <FieldRefs>
      <!-- add in and rename built-in WSS Title column-->
      <FieldRef ID="{fa564e0f-0c70-4ab9-b863-0177e6ddd247}" Name="Title" DisplayName="Name" Sealed="TRUE"  />
      <!-- custom fields-->
      <FieldRef ID="{756D3B72-AC72-4e0a-8B6D-1E2573251816}" Name="CardNumber" DisplayName="Card Number" />
      <FieldRef ID="{0D6C76FD-A9B6-4613-9429-06385411E9D7}" Name="StudyYear" DisplayName="Study Year" />
    </FieldRefs>
    <XmlDocuments>
      <XmlDocument NamespaceURI="http://schemas.microsoft.com/sharepoint/v3/contenttype/forms/url">
        <FormUrls xmlns="http://schemas.microsoft.com/sharepoint/v3/contenttype/forms/url">
          <New>_layouts/STUDENT/APPLICATIONPAGES/NewStudent.aspx</New>
          <Edit>_layouts/STUDENT/APPLICATIONPAGES/EditStudent.aspx</Edit>
          <Display>_layouts/STUDENT/APPLICATIONPAGES/DisplayStudent.aspx</Display>
        </FormUrls>
      </XmlDocument>
    </XmlDocuments>
  </ContentType>
</Elements>

November 17, 2008

CAML query on lookup columns

Let's imagine two SharePoint lists:

- Products
- Categories

In this scenario, the Products list contains a lookup column called Category pointing on the Categories list.

Now, I want to write a CAML query to get all the products list items related to the Hardware category.

The first thing coming into my mind is the following piece of code:

private SPListItemCollection GetProductsByCategory(SPFieldLookupValue Category)
{
    SPList listProducts = this._web.Lists["Products"];
    SPQuery camlQuery = new SPQuery();
    camlQuery.Query = string.Format("<Where><Eq><FieldRef Name=\"Category\" /><Value Type=\"Lookup\">{0}</Value></Eq></Where>", Category.LookupValue);
    return listProducts.GetItems(camlQuery);
}

The problem with this query appears if some categories have the same name (Hardware). It's due to the fact that the query doesn't use the ID of the category but the Name. So, you will get all the products related to all the categories having Hardware as name.

To solve that and get only the products related to the wanted category, you have to rewrite the query in setting the LookupId property of the FieldRef node to true and in using the LookupId property as value and not the LookupValue property:

private SPListItemCollection GetProductsByCategory(SPFieldLookupValue Category)
{
    SPList listProducts = this._web.Lists["Products"];
    SPQuery camlQuery = new SPQuery();
    camlQuery.Query = string.Format("<Where><Eq><FieldRef Name=\"Category\" LookupId=\"TRUE\" /><Value Type=\"Lookup\">{0}</Value></Eq></Where>", Category.LookupId);
    return listProducts.GetItems(camlQuery);
}