DCSIMG
May 2010 - Posts - itaysk

May 2010 - Posts

שלום לכולם,

מפגש חמישי של קבוצת מפתחי SharePoint יתקיים בתאריך ה 23/06/2010 במשרדי מיקרוסופט ברעננה.

הפעם נארח את גיל זילברפילד מחברת TypeMock אשר יספר לנו על Unit Testing בפיתוח עבור SharePoint.

אתר המפגש:
http://www.sharepoint2010.co.il/Events/SPDG5

הרשמה:
https://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032453745&culture=he-IL

תיאור המפגש:

במפגש זה נדבר על מושגי יסוד בunit testing ,תהליך פיתוח שמקפיץ את איכות הקוד, מקצר לוחות זמנים ומשפר את האפשרות לתחזק את הקוד בשנים הבאות עלינו לטובה. בעולם ה SharePoint נהוג לחשוב שהמערכת אינה בנויה לבדיקות. הגיע הזמן להפריך את המיתוס.

סדר יום:

17:30-17:45 - התכנסות

17:45-18:45 – Unit testing from scratch

· Why is unit testing important?

· What makes good unit tests?

· What testing tools can we use?

· And why is SharePoint considered un-testable?

18:45-19:00 - הפסקה וכיבוד קל

19:00-20:00 – Unit testing in SharePoint – Solutions to real life problems

· How do we overcome the unit testing SharePoint challenge?

· The toolset for real SharePoint unit testing: Typemock Isolator and Microsoft Moles

· Examples of unit testing a WebPart and an administration component.

· What’s next?

20:00 - סיום משוער

אודות המרצה:

Gil Zilberfeld has been in software since childhood, starting with Logo turtles. After 15 years in commercial software companies, he has vast experience in development and development practices. Currently Gil is the Technology Evangelist at Typemock, promoting unit testing and some incredibly cool tools. He's presented in Israel and abroad. Gil brings his real-life experience, along with a bit of sarcasm, since these two are a match made in heaven. Follow Gil on twitter: gil_zilberfeld and read his blog at http://www.gilzilberfeld.com

אתמול התקיים מפגש רביעי של קבוצת מפתחי SharePoint.

במפגש הרצו ליאור ארביב, וגיל גבעתי על אריזת פתרונות והפצתם, ואיתור וניטור בעיות בקוד.

תמונות מהאירוע, מצגות וחומרים נוספים ניתן למצוא באתר המפגש:
http://www.sharepoint2010.co.il/events/spdg4

כאמור, המפגש הבא יתקיים ב 23/6 – פרטים כאן:
http://www.sharepoint2010.co.il/events/spdg5

IMG_20100525_190848

נתראה במפגש הבא,

איתי.

SharePoint 2010 יצא בגרסה סופית לא מזמן. לפני כשבוע התקיימה ההשקה העולמית, ועכשיו תורנו. השנה מתכננים לנו אירוע קצת שונה - אירוע וירטואלי!
האירוע יתקיים ב 8-9 ליוני. לשמירה ביומנים לחצו כאן.

2010event

מדובר ממש על אירוע עם כל הדברים שמכירים מכנס אמיתי – ביתני שותפים, הפסקות קפה, הרצאות, אולמות, שיחות עם מומחים, רק שהכל וירטואלי.

למי שרוצה לקבל מושג על מה הולך להיות שם, אפשר להתרשם מהתכנים באתר ההשקה העולמית - http://www.the2010event.com, ומהפלטפורמה עצמה באתר של inxpo.

application_image_virtual_events_conferences 

אתר הכנס יהיה פתוח למשך תקופה של 3 חודשים, כך שתוכלו לצרוך את התכנים שמעניינים אתכם בקצב שנוח לכם,ובצורה שנוחה לכם.

בנוסף, נפתחו ערוצי תקשורת והפצה לאירוע ב twitter facebook.

Short story: SharePoint 2010 RTM (as opposed to beta 2) doesn’t support Forms Based Authentication with Classic Mode, only with Claims Based Authentication.

Long story: SharePoint 2010 introduces a new authentication type – Claims Based Authentication. The old type that we know from 2007 is still available and is now referred to as Classic Mode Authentication.

FBA2

SharePoint 2007 provided an option to work with Forms Based Authentication. SharePoint 2010 beta 2 carried on with this to support FBA both on Classic and Claims mode.

I have tried to configure FBA on my SharePoint 2010 RTM server, and faced this screen:

FBA1

As you can see, all options but Windows Authentication are grayed out. There is no explanation, and clicking the links for more details doesn’t give much details, or tell you way it’s grayed out.

At first I was shocked. Then I stated to think what I did wrong… It took a while before I realized that this behavior is by design.

Just for comparison, Here is the same screen on my Beta 2 machine:

fba4 

After seeing this with my own eyes, I have searched and found verification on TechNet:

fba3

http://technet.microsoft.com/en-us/library/cc262350(office.14).aspx#section2

This option was dropped in the RTM, meaning that SharePoint 2010 RTM doesn’t support Forms Based Authentication with Classic Mode, only with Claims Based Authentication.

This means that every application that used FBA, must migrate to claims based authentication with SharePoint 2010.

Here are tow good tutorial I found for doing that:

http://donalconlon.wordpress.com/2010/02/23/configuring-forms-base-authentication-for-sharepoint-2010-using-iis7/

http://blogs.technet.com/mahesm/archive/2010/04/07/configure-forms-based-authentication-fba-with-sharepoint-2010.aspx

with 2 comment(s)
תגים:,

נגמרו התירוצים :) – שוחררו היום להורדה חבילות השפה לעברית.

SharePoint Foundation:
http://www.microsoft.com/downloads/details.aspx?displaylang=he&FamilyID=646e311a-aaf3-4d30-b03c-2f3c70d19a22

SharePoint Server:
http://www.microsoft.com/downloads/details.aspx?displaylang=he&FamilyID=046f16a9-4bce-4149-8679-223755560d54

כמובן שזה אומר ש SharePoint2010.co.il ישודרג בקרוב, יש למה לצפות.

heb2010

תודה לליאור ארביב על המבזק.

קבוצות הדיון של מיקרוסופט ישראל לא זמינות כבר מספר ימים.
לפני שהם ירדו, הספקתי לראות הודעה אוטומאטית שהוצבה בפורומים שציינה שמיקרוסופט מפחיתה בהדרגה את השימוש בפלטפורמה הזו של News Groups ועוברת לפלטפורמה חדישה יותר של פורומים כמו ב MSDN ו Technet.
 
כרגע, אם תנסו להגיע לקבוצות הדיון, תקבלו את ההודעה הבאה:
newsgroups_offline
 
בינתיים, וכמו תמיד, אתם יכולים להפנות את השאלות שלכם לפורום שבאתר: www.SharePoint2010.co.il (כן, גם שאלות על 2007 ייענו).
 
with 1 comment(s)
תגים:, ,

This is part of a series of posts about Working with Discussion lists programmatically: Part 1, Part 2, Part 3 (this one.

In the previous parts we talked about how SharePoint’s Discussion lists work, and how to work with the from server side.
In this post we will see how to work with them from client side, using the managed Client Object Model.

Getting all Posts

ClientContext ctx = new ClientContext("http://dev-sp2010-01/sites/itaysk/forum");

//Get the Discussion list
List lst = ctx.Web.Lists.GetByTitle("Team Discussion");
//Get the topics in the list
CamlQuery q = CamlQuery.CreateAllFoldersQuery();
ListItemCollection topics = lst.GetItems(q);
ctx.Load(topics);
ctx.ExecuteQuery();

To get all the topics (folders), we are basically asking for all the folders in the list.

Getting all Replies

//Select a topic
ListItem topic = topics[0];
//Get the replies of the selected topic
q = CamlQuery.CreateAllItemsQuery(100, "Title", "FileRef", "Body");
//FileRef contains the site relative path to the folder
q.FolderServerRelativeUrl = topic["FileRef"].ToString();
ListItemCollection replies = lst.GetItems(q);
ctx.Load(replies);
ctx.ExecuteQuery();

First we select a topic (Folder). Then we ask for all the items in that folder.

CamlQuery q = new CamlQuery();
//Find all replies for topic with ID=1
q.ViewXml = @"<View Scope='Recursive'>
<Query>
<Where>
<Eq>
<FieldRef Name="
"ParentFolderId"" />
<Value Type="
"Integer"">1</Value>
</Eq>
</Where>
</Query>
</View>"
;
ListItemCollection replies = lst.GetItems(q);
ctx.Load(replies);
ctx.ExecuteQuery();

Here we are using the “ParentFolderId” column, that every reply has.

Creating a Topic

As I explained in Part 2, topic and reply creation are a bit more complicated because we have to take care of Threading that’s why we have special functions to do that.

ClientContext ctx = new ClientContext("http://dev-sp2010-01/sites/itaysk/forum");

//Get the Discussion list
List lst = ctx.Web.Lists.GetByTitle("Team Discussion");

//Create the topic
ListItem t = Microsoft.SharePoint.Client.Utilities.Utility.CreateNewDiscussion(ctx, lst, "Creted by Client OM");
t["Body"] = "This is the body";
t.Update();
ctx.ExecuteQuery();

Creating a Reply

Again, using the proprietary function:

//Get the topic for which we eant to reply (assuming we already got the topic list into "topics")
//You can also get the topic in ther ways.
ListItem t = topics[0];
//Create the reply
ListItem r = Microsoft.SharePoint.Client.Utilities.Utility.CreateNewDiscussionReply(ctx, t);
r["Body"] = "This is the reply body";
r.Update();
ctx.ExecuteQuery();

In this example, we have replied to the root of the topic. You can also reply to a specific reply inside the topic – just pass the CreateNewDiscussionReply function the object that you want to reply to.

Conclusion

In this post we have seen how to work with discussion lists from the client, using Client OM.
This post concludes the series, hope I helped.

with 10 comment(s)
תגים:,

This is part of a series of posts about Working with Discussion lists programmatically: Part 1, Part 2 (this one), Part 3.

In Part 1, I have introduced the structure and inner workings of SharePoint Discussion Lists. Now, Lets take a look of some code samples with SharePoint’s Object Model, and LINQ 2 SharePoint.

Getting all Posts

ForumDataContext dc = new ForumDataContext("http://dev-sp2010-01/sites/itaysk/Forum");

//Get all topics in the Discussion list
IEnumerable<Discussion> topics = from t in dc.TeamDiscussion
select (Discussion)t;

We ask for all the list items that are in the root of the list. Those are essentially the items of type “Discussion” which are folders.

Alternatively, you can use SPList.GetItems(SPQuery query) to get the items. An empty query will do because the list contains only topics at it’s root. (You could filter for Folder content type if you like too, but it’s not necessary)

SPList list = web.Lists["Team Discussion"];
SPListItemCollection res = list.GetItems(new SPQuery());

Getting all Replies for a post

//select a single discussion (in this case, the first one), to view it's content
Discussion topic = (Discussion)dc.TeamDiscussion.Single(t => t.Id == 5);

//Get all the replies for the selected discussion
IEnumerable<Message> replies = from reply in dc.TeamDiscussion.ScopeToFolder("/"+topic.Reply+"/"+topic.Title, false)
select (Message)reply;

After selecting a specific post (folder), we are asking for all the list items that are in that folder.

Alternatively, if you prefer to work with CAML, you can use this CAML query that asks for all items in a folder:

SPList list = web.Lists["Team Discussion"];
//Get the topic. (you can use other ways to get the topic)
SPFolder t = list.GetItemById(1).Folder;
SPQuery q = new SPQuery();
q.Folder = t;
SPListItemCollection res = list.GetItems(q);

Or use this one, that uses the “ParentFolderId” column that every reply has.

SPList list = web.Lists["Team Discussion"];
//This Query gets all items of the topic with ID=1
string strQ = @"<Query>
<Where>
<Eq>
<FieldRef Name="
"ParentFolderId"" />
<Value Type="
"Integer"">1</Value>
</Eq>
</Where>
</Query>"
;

SPQuery q = new SPQuery();
//This line makes the query search ib all folders
q.ViewAttributes = "Scope=\"Recursive\"";
q.Query = strQ;
SPListItemCollection res = list.GetItems(q);

Creating a Topic

Don’t be tempted to manually create a regular list item in the list, because it will miss Threading and other stuff the mechanism needs. 
Luckily, we have a special function that does all this for us.

SPList list = web.Lists["Team Discussion"];
SPListItem t = Microsoft.SharePoint.Utilities.SPUtility.CreateNewDiscussion(
list, "Created by Code");
t[SPBuiltInFieldId.Body] = "Created by Code";
t.Update();

Creating a Reply

Again, using the proprietary function.

SPList list = web.Lists["Team Discussion"];
//Get the topic for which we are replying to. (you can also get it in other ways)
SPListItem t = list.GetItemById(11);
SPListItem r = Microsoft.SharePoint.Utilities.SPUtility.CreateNewDiscussionReply(
t);
r[SPBuiltInFieldId.Body] = "Created by Code";
r.Update();

In this example, we have replied to the root of the topic. You can also reply to a specific reply inside the topic – just pass the CreateNewDiscussionReply function the object that you want to reply to.

Conclusion

In this post we learned how to create discussion items, and replies, as well as query them. We have used Server Object Model.

In the next posts I will show how to do the same things from the client.

with 4 comment(s)
תגים:,

This is part of a series of posts about Working with Discussion lists programmatically: Part 1(This one), Part 2, Part 3.

I am currently involved in a project that requires a programmatic way to query a discussion list for it’s data, and create new items in it.
As it turns out, SharePoint discussion lists are not so ordinary lists. They have a very complex structure to store it’s data.

I came across several resources that helped me figure out how this whole thing works, and they are listed at the end of this post. This post is the summary of what I learned, and an more dated version that apply to SP 2010.

Before we get into code, lets try to understand how those lists are organized.

Content types

If you take a look at a discussion list’s settings page, you will see that it uses tow different content types: Discussion, and Message.

discussions_1
Discussion list’s content types

Discussions are new threads that are opened by users. I refer to them generally as Topics.
Messages are the responses posted at a topic. I refer to them generally as Replies.

If you follow the content types hierarchy, you will see that Topics are actually Folders.

discussions_2
Discussion is a Folder

So every topic you open, is in fact a folder, and the replies to that topic are list items stored in that folder.

Threading

So we know how topics are stored, and how to get to replies in them. Once we got the list of replies of a specific topic, how would we know which reply is for which?

Take this conversation for example:

discussions_3
A sample conversation

If we will try to get all the reply for the topic “I have a question”’, we will get a flat list of all the replies. But what if we wanted to build a tree representation like it was originally? We need a way to tell for each reply object, what it was a reply for.

Here comes the threading attribute. Each reply has a hidden column called “Threading” (there are other columns as well that contains the same data).

discussions_4
The threading attribute

This column stores a chained string that represent the depth of this item in the tree of replies. Each time we add a new reply down the tree, that reply get’s the parent reply’s threading string, appended with some other new string.

discussions_4b  The threading value of messages

As you can see, the threading of the reply “I know the answer” has the same length of “The answer is 42”, because they are at the same level. But threading of “LOL” is a bit longer, because it was a reply to “The answer is 42”.

So to wrap it up:

  • If you look at a certain threading string, you can tell it’s depth by it’s length.
  • You can get the correct order of replies, if you just sort by the Threading column.

Views

We now have the understanding for how to build something like the default views of a discussion list.

The default view for a discussion list shows all the topics.

 discussions_5 Discussion list’s default view

To recreate this view we need to get the folders in the list.
Actually, folders are actually list items, so it’s sufficient to get the root level list items. Some times I will prefer this method.

The Flat view just shows all the replies for a selected topics without any indentation.

discussions_6 
Discussion list’s flat view

To recreate this view, we need to get all the items in the designated folder, and print them as a list.

The Threaded view also shows replies for a selected topic, but in a hieratical way that takes care of indentation.

discussions_7 
Discussion list’s threaded view

To recreate this view, we need to get all the items in the designated folder. Once we have them we will sort the list based the threaded column. To add correct indentation, we can right-pad each item based on the length of the threaded value. Let take for example the first reply - “I know the answer”. It’s thread value is:

0x01CCB587E59C913F9BF0EB9145C79AD6606C8EA970CC000002F5D6

The length is 57. So we can add 57px of right padding(If you want smaller padding you can do some kind of calculation based on the length).

This will create the tree looking structure.

Summary

In this post we learned how SharePoint’s discussion lists work. We now have the tools to recreate the basic functionality of a discussion list. This is what I’m going to do in the following posts.

In the making of this post I have used the following posts.

with 29 comment(s)
תגים:,