This project is read-only.
MOSSDAL is a lightwork framework that consists of 2 custom attributes, 3 Service Helpers, a CAML factory class, and a business object base class.

To use MOSSDAL, a developer first decides what list they want to fetch data from in SharePoint. Once they have selected a list, the developer creates a business object that inherits from SharepointListItem. The developer must decorate the class with the SharepointListNameAttribute to map the business class to a Sharepoint list name. Then the developer creates the fields that they wish to use in their application. They can create either properties or fields or a combination of both and they can use any access level (public, private, protected, etc.). Each property or field must be decorated with the SharepointListFieldAttribute that maps the field to a field in the Sharepoint List. It is important to note that the SharepointListNameAttribute and the SharepointListFieldAttribute both use the Sharepoint Internal Name. In other words, if the list field is called "display order", then the attribute would look like [SharepointListField("display_x0020_order")]. In the next release you will be able to use the display name instead of the internal name.

After the developer has created and mapped their custom business object class, they will need to define the CAML query to send to the Lists.asmx web service. There is a class called CamlFactory that can help developers create CAML queries. If the developer were trying to get all list items where the checkbox field "show in viewer" was checked and ordered by the "display order" field. then the CAML would look like:
  <Query>
    <Where>
      <Eq>
        <FieldRef Name='show_x0020_in_x0020_viewer' />
        <Value Type='Boolean'>1</Value>
      </Eq>
    </Where>
    <OrderBy>
      <FieldRef Name='display_x0020_order' Ascending='True' />
    </OrderBy>
  </Query>
Using the CamlFactory methods it is a little more readable for the xml impared among us. With CamlFactory this query is:
CamlFactory.CreateQuery(
     CamlFactory.CreateWhereClause(
          CamlFactory.CreateEqualCriteria(
               CamlFactory.CreateBooleanField("1", "show_x0020_in_x0020_viewer")
           )
      ),
      CamlFactory.CreateOrderByClause(
           CamlFactory.CreateOrderByFieldRef("display_x0020_order", CamlFactory.OrderByType.Ascending)
       )
);
This is not quite the entire query because both the first and sencond examples need to have the viewfields and queryoptions set. Because these queries are somewhat complex, I recommend creating a static class with a method for each query. In the samples there is a class called ApplicationQueries which uses
CamlFactory to create the query:
        public static string GetSiteGalleryItems()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append(
                CamlFactory.CreateQuery(
                    CamlFactory.CreateWhereClause(
                        CamlFactory.CreateEqualCriteria(
                            CamlFactory.CreateBooleanField("1", "show_x0020_in_x0020_viewer")
                            )
                        ),
                    CamlFactory.CreateOrderByClause(
                        CamlFactory.CreateOrderByFieldRef("display_x0020_order", CamlFactory.OrderByType.Ascending)
                     )
                 )
            );
            sb.Append(new SiteGalleryListItem().ViewFields());
            sb.Append(CamlFactory.CreateEmptyQueryOptions());
            return sb.ToString();
        }
Here you notice that I call new SiteGalleryListItem().ViewFields(). This is a method from the SharepointListItem base class that uses reflection to create the viewfields part of a CAML query for you. If you look closely at the SharepointListItem class you will also notice there is a ViewFields method that takes a string for a parameter. This is an advanced feature of MOSSDAL that allows you to specify custom views in your business object that will return only some of the fields in the object. This is made possible by an optional parameter to the SharepointListFieldAttribute called viewName. If you need to be able to pull only a few fields in one view of your application but more fields later then this will reduce the amount of data that you are fetching across the wire. This is useful if you have a master grid that shows basic details and a details form that shows additional information. You could mark the fields you need in the master with [SharepointListField("ImageWidth","MasterView")] and call new SiteGalleryListItem().ViewFields("MasterView") to get the small set of fields and then leave out the view name when you need to get the details.

Once the business object is defined, the developer needs to use the framework to run their query and return the results. This is where the differences in the .NET and Silverlight versions of the MOSSDAL framework come into play. In .NET, the framework can do synchronous service calls so the code looks like:
            DotNetServiceHelper<SiteGalleryListItem> svcHelper = new DotNetServiceHelper<SiteGalleryListItem>();
            svcHelper.Credentials = new System.Net.NetworkCredential("administrator", "thefuture", "sharepoint");
            svcHelper.PageSize = 50;
            svcHelper.SharepointHostname = "sharepoint";

            IList<SiteGalleryListItem> items = svcHelper.FetchListItems(ApplicationQueries.GetSiteGalleryItems());

            foreach (SiteGalleryListItem item in items)
            {
                Console.WriteLine(item.ID);
                Console.WriteLine(item.client);
                Console.WriteLine(item.Description);
                Console.WriteLine(item.DisplayOrder);
                Console.WriteLine(item.ImageHeight);
                Console.WriteLine(item.ImageWidth);
                Console.WriteLine(item.project);
                Console.WriteLine(item.ShowInViewer);
                Console.WriteLine(item.Title);
                Console.WriteLine(item.url);
                Console.WriteLine();
            }
Here the code first creates a DotNetServiceHelper of type SiteGalleryListItem. This is type is the type of the business object and is used so that the framework can return a strongly typed set back. Next the credentials are set. If the default network credentials are to be used then this can be omitted. Then the pagesise is specified. This is a parameter sent to the service to indicate how many results are to be returned. The next release will allow you to use this information to fetch a specific page of the data. Next, the hostname of the sharepoint server is passed in. This can also include a port number if necessary and it serves as part of the service address endpoint. The next line performs the fetch.

In Silverlight, all service calls must be done asynchronously. Therefore we attach a delegate to the completion of the service helper fetch list items. Since silverlight is stateful we also can update data when the service call completes using the observable pattern. For this reason the silverlight version of the MOSSDAL framework returns an ObserableCollection of business objects. It is also worth mentioning that the framework uses the browser network stack so the browser is responsible for passing the credentials to Sharepoint. This should be ok since the silverlight that is using this framework is probably hosted by the sharepoint server. The code looks like this:
public class SitesGalleryCollection
    {
        public ObservableCollection<SiteGalleryListItem> items { get; set; }

        public SitesGalleryCollection()
        {
            items = new ObservableCollection<SiteGalleryListItem>();
        }

        void helper_FetchListItemsCompleted(object sender, EventArgs e)
        {
            foreach(SiteGalleryListItem item in ((SilverlightServiceHelper<SiteGalleryListItem>)sender).FetchListItems())
                items.Add(item);
        }

        public void LoadData()
        {
            SilverlightServiceHelper<SiteGalleryListItem> helper = new SilverlightServiceHelper<SiteGalleryListItem>();
            helper.SharepointHostname = "sharepoint";
            helper.PageSize = 50;
            helper.FetchListItemsCompleted += new EventHandler(helper_FetchListItemsCompleted);
            helper.FetchListItemsAsync(ApplicationQueries.GetSiteGalleryItems());
        }
    }

Last edited May 1, 2010 at 5:52 AM by jcart, version 8

Comments

No comments yet.