mardi 7 juillet 2009

[Sharepoint/Asp.net] Affichage de contenu Sharepoint dans un site Asp.net via WebServices

 

Le but de cet exemple, est d’afficher sur un site web Asp.net du contenu provenant d’un site de publication sous Moss 2007.
Mon était de récupérer des informations de base des pages de publication ou de documents dans MOSS.

NB : Apeine le temps de finir d’écrire ce post et voilà ce qui tombe dans mes Flux :
http://blogs.msdn.com/davrous/archive/2009/07/03/utilisez-linq-pour-faciliter-l-acc-s-aux-listes-sharepoint-via-ses-webservices.aspx
Un bon plus sur l’utilisation des webservices Sharepoint

Voici comment j’ai procédé :

Tout d’abord, dans mon application web, j’ai ajouté 3 web references provenant de mon site Sharepoint :

  • http://monMoss/_vti_bin/Lists.asmx
  • http://monMoss/_vti_bin/sitedata.asmx
  • http://monMoss/_vti_bin/Authentication.asmx

Que j’ai nommé comme suit :

Mots clés Technorati : ,,

image

Ensuite j’ai créé 3 classes :

  • Une SharepointBO.PublishedPage représentant les informations d’une page de publication
  • Une SharepointBO.Document représentant les informations d’un document
  • Une SharepointWS pour gérer la récupération des informations.

Les Objets métiers (Je ne me suis intéressé qu’au titre et contenu d’une page ou document) :

   1: public class PublishedPage



   2:     {



   3:         public String BaseName {get;set;}



   4:         public String Title {get;set;}



   5:         public String PublishingPageContent { get; set; }



   6:  



   7:     }



   8:  



   9:     public class Document



  10:     {



  11:         public String EncodedAbsUrl { get; set; }



  12:         public String Title { get; set; }



  13:         public String LinkFilename { get; set; }



  14:  



  15:     }




La classe me permettant de gérer la connexion et la récupération des données (j’ai tout mis dans la même classe pour l’exemple):





   1: public class SharepointWS



   2:     {



   3:  



   4:         #region properties



   5:         private Guid _webID;



   6:         /// 



   7:         /// GUID du site Web



   8:         /// 



   9:         public Guid WebID



  10:         {



  11:             get



  12:             {



  13:                 return _webID;



  14:             }



  15:         }



  16:  



  17:         private Cookie _authCookie;



  18:         /// 



  19:         /// Cookie d'authentification



  20:         /// 



  21:         public Cookie AuthCookie



  22:         {



  23:             get



  24:             {



  25:                 return _authCookie;



  26:             }



  27:         }



  28:  



  29:         public ICredentials Creds { get; set; }



  30:  



  31:         private Uri _webPath;



  32:         private string _authType;



  33:         #endregion



  34:  



  35:         #region constructeur



  36:         public SharepointWS(Uri webPath, ICredentials creds, string authType)



  37:         {



  38:             _webPath = webPath;



  39:             _authType = authType;



  40:             Creds = creds;



  41:             _authCookie = GetAuthentification();



  42:             _webID = GetWebID();



  43:         }



  44:         #endregion



  45:  



  46:         #region méthode privée d'initialisation



  47:         /// 



  48:         /// Récupère l'ID du site web Sharepoint



  49:         /// 



  50:         /// url du site web Sharepoint



  51:         /// 



  52:         private Guid GetWebID()



  53:         {



  54:             Guid g = new Guid();



  55:  



  56:             try



  57:             {



  58:                 using(SiteDataWS.SiteData site = CreateWebService())



  59:                 {



  60:                     if (_authCookie != null)



  61:                     {



  62:                         site.CookieContainer = new CookieContainer();



  63:                         site.CookieContainer.Add(_authCookie);



  64:                     }



  65:  



  66:                     SiteDataWS._sWebMetadata webMetaData = null;



  67:                     SiteDataWS._sWebWithTime[] arrWebWithTime = null;



  68:                     SiteDataWS._sListWithTime[] arrListWithTime = null;



  69:                     SiteDataWS._sFPUrl[] arrUrls = null;



  70:                     string roles;



  71:                     string[] roleUsers;



  72:                     string[] roleGroups;



  73:  



  74:                     uint i = site.GetWeb(out webMetaData, out arrWebWithTime, out arrListWithTime, out arrUrls, out roles, out roleUsers, out roleGroups);



  75:                     g = new Guid(webMetaData.WebID);



  76:                 }



  77:             }



  78:             catch (System.Net.WebException)



  79:             {



  80:  



  81:                 throw;



  82:             }



  83:             return g;



  84:         }



  85:  



  86:         /// 



  87:         /// Obtient un cookie après authentification sur le site Sharepoint



  88:         /// 



  89:         /// url du site Sharepoint



  90:         /// Credidentials



  91:         /// type d'authentification



  92:         /// 



  93:         private Cookie GetAuthentification()



  94:         {



  95:             Cookie authCookie = null;



  96:             using (AuthentificationWS.Authentication auth = CreateWebService())



  97:             {



  98:  



  99:                 auth.CookieContainer = new CookieContainer();



 100:                 string login = Creds.GetCredential(_webPath, _authType).UserName;



 101:                 string password = Creds.GetCredential(_webPath, _authType).Password;



 102:                 LoginResult result = auth.Login(login, password);



 103:                 if (result.ErrorCode == LoginErrorCode.NoError)



 104:                 {



 105:                     CookieCollection cookies = auth.CookieContainer.GetCookies(new Uri(auth.Url));



 106:                     authCookie = cookies[result.CookieName];



 107:  



 108:                 }



 109:             }



 110:             return authCookie;



 111:         }



 112:  



 113:  



 114:         #endregion



 115:  



 116:  



 117:         /// 



 118:         /// Methode generique de connexion au asmx



 119:         /// 



 120:         /// 



 121:         /// 



 122:         



 123:         private WSType CreateWebService()



 124:             where WSType : SoapHttpClientProtocol, new()



 125:         {



 126:             WSType webService = new WSType();



 127:             webService.Credentials = Creds;



 128:  



 129:  



 130:             string webServiceName = typeof(WSType).Name;



 131:             webService.Url = string.Format("{0}/_vti_bin/{1}.asmx", _webPath, webServiceName);



 132:  



 133:             return webService;



 134:         }



 135:  



 136:  



 137:  



 138:         /// 



 139:         /// Récupère l'Item d'une liste en fonction du nom de la liste et d'une chaine contenu dans son titre



 140:         /// 



 141:         /// url du site web Sharepoint



 142:         /// nom de la liste



 143:         /// chaine ou mot contenu dans le titre



 144:         /// Documents en pièces jointes à ajouter



 145:         /// 



 146:         private  System.Xml.XmlNode GetListItems(string listName, string titre)



 147:         {



 148:             return GetListItems(listName, titre, false);



 149:         }



 150:         private  System.Xml.XmlNode GetListItems(string listName, string titre, bool includeAttachmentUrls)



 151:         {



 152:             string query = @"



 153:                                



 154:                                   



 155:                                      



 156:                                      {0}



 157:                                   



 158:                                



 159:                             



 160:                             



 161:                             



 162:                             



 163:                             ";



 164:  



 165:             System.Xml.XmlDocument doc = new System.Xml.XmlDocument();



 166:             doc.LoadXml(""+string.Format(query,titre)+"");



 167:             XmlNode listQuery = doc.SelectSingleNode("//Query");



 168:             XmlNode listViewFields = doc.SelectSingleNode("//ViewFields");



 169:             XmlNode listQueryOptions = doc.SelectSingleNode("//QueryOptions");



 170:             



 171:             if(includeAttachmentUrls)



 172:                 listQueryOptions.InnerXml = "TRUE";



 173:  



 174:             XmlNode ret = null;



 175:             try



 176:             {



 177:                 using (SPListItemsWS.Lists l = CreateWebService())



 178:                 {



 179:                     if (AuthCookie != null)



 180:                     {



 181:                         l.CookieContainer = new CookieContainer();



 182:                         l.CookieContainer.Add(AuthCookie);



 183:                     }



 184:  



 185:                     ret = l.GetListItems(listName, string.Empty, listQuery, listViewFields, string.Empty, listQueryOptions, WebID.ToString());



 186:                 }



 187:             }



 188:             catch (Exception)



 189:             {



 190:                 



 191:                 throw;



 192:             }



 193:             return ret;



 194:         }



 195:  



 196:  



 197:         #region public



 198:  



 199:         /// 



 200:         /// Obtient une page Sharepoint en fonction de son titre



 201:         /// 



 202:         /// 



 203:         /// 



 204:         /// 



 205:         public BO.PublishedPage GetPage(string listName, string titre)



 206:         {



 207:             XDocument doc = XDocument.Load(new XmlNodeReader(GetListItems(listName, titre)));



 208:  



 209:             return (



 210:                        from el in doc.Elements() //niveau root => listitems



 211:                                     .Elements()//enfant ListItems => data



 212:                                         .Elements()  //enfant de data => row



 213:                        select new BO.PublishedPage



 214:                        {



 215:                            Title = el.Attribute("ows_Title").Value,



 216:                            BaseName = el.Attribute("ows_BaseName").Value,



 217:                            PublishingPageContent = el.Attribute("ows_PublishingPageContent").Value



 218:                        }



 219:                        ).FirstOrDefault();



 220:         }



 221:  



 222:  



 223:         /// 



 224:         /// Obtient la liste des documents de la lib choisie



 225:         /// 



 226:         /// 



 227:         /// 



 228:         /// 



 229:         /// 



 230:         /// 



 231:         public  BO.Document[] GetDocumentsList(string listName, string titre)



 232:         {



 233:  



 234:             XDocument doc = XDocument.Load(new XmlNodeReader(GetListItems(listName, titre, true)));



 235:  



 236:             return (



 237:                        from el in doc.Elements() //niveau root => listitems



 238:                                     .Elements()//enfant ListItems => data



 239:                                         .Elements()  //enfant de data => row



 240:                        select new BO.Document



 241:                        {



 242:                            Title = el.Attribute("ows_Title").Value,



 243:                            EncodedAbsUrl = el.Attribute("ows_EncodedAbsUrl").Value,



 244:                            LinkFilename = el.Attribute("ows_LinkFilename").Value



 245:                        }



 246:                        ).ToArray();



 247:  



 248:         }



 249:  



 250:         #endregion



 251:  



 252:  



 253:     }




L’utilisation de cette classe est ensuite assez simple, il suffit de l’instancier avec




  • l’URI du site MOSS


  • Les credidentials ayant les bons droits sur le site MOSS


  • Le type d’authentification : Forms ou Windows



Une fois l’objet instancié, il suffit d’appeler la méthode GetPage (pour obtenir une page) en lui passant comme arguments :




  • Le nom de la bibliothèque de pages du site MOSS


  • Le titre de la page à récupérer





   1: SharepointWS sws = new SharepointWS(MonURIMoss, MesCredentials, "Forms");



   2:                 PublishedPage page = sws.GetPage("Pages", "Accueil");



   3:                 if (page != null)



   4:                 {



   5:                     ContentPannel.Controls.Add(new LiteralControl(page.PublishingPageContent));



   6:                 }




Voila c’est assez simple et ça permet d’utiliser du contenu déjà existant dans un site Asp.net grace à la publication de MOSS.

Attention tout de même aux appels aux webservices, cet exemple est utile dans certains cas précis, mais ne réinventons pas la publication.



Très pratique sur un Intranet.

mardi 19 mai 2009

[Sharepoint] FBA et les droits - "Erreur - la liste n'existe pas"

Voici un problème que je viens d'avoir.

Je suis sur mon portail de publication en authentification FBA perso. Tout fonctionne.
Suite à des demandes spécifiques sur la gestion des droits, je refait un petit plan de gouvernance et remet le tout à plat.

Je recrèé les groupes et en supprime certains, et la, suprise, lorsqu'on veut créer une page, j'ai le message d'erreur suivant :
La liste n'existe pas

La page sélectionnée contient une liste qui n'existe pas. Elle a peut-être été supprimée par un autre utilisateur.   à Microsoft.SharePoint.Library.SPRequestInternalClass.GetListsWithCallback(String bstrUrl, Guid foreignWebId, String bstrListInternalName, Int32 dwBaseType, Int32 dwBaseTypeAlt, Int32 dwServerTemplate, UInt32 dwGetListFlags, UInt32 dwListFilterFlags, Boolean bPrefetchMetaData, Boolean bSecurityTrimmed, Boolean bGetSecurityData, ISP2DSafeArrayWriter p2DWriter, Int32& plRecycleBinCount)
   à Microsoft.SharePoint.Library.SPRequest.GetListsWithCallback(String bstrUrl, Guid foreignWebId, String bstrListInternalName, Int32 dwBaseType, Int32 dwBaseTypeAlt, Int32 dwServerTemplate, UInt32 dwGetListFlags, UInt32 dwListFilterFlags, Boolean bPrefetchMetaData, Boolean bSecurityTrimmed, Boolean bGetSecurityData, ISP2DSafeArrayWriter p2DWriter, Int32& plRecycleBinCount)

Solution :

En supprimant mes groupes, je suis allé un peu vite et certains étaient important pour Sharepoint.

Pour palier à ce problème, il suffit de rajouter dans :

Mon site > Galerie de pages maîtres > Paramètres > Autorisations  

l'utilisateur : AUTORITE NT\utilisateurs authentifiés avec les droits lecteur restreinte

Ainsi, les utilisateurs récupèrent le droit d'utiliser les pages de la galerie.

mardi 3 mars 2009

Tutoriel Méthodes : Présentation des principes SOLID appliqués au langage C#, par Philippe Vialatte

Une petite piqure de rappel que nous fait Philippe Vialatte sur les bonnes pratiques en .NET.

Ce tuto est très intéressant et, de mon point de vue, est une bonne introduction sur certains principes de développement orientés objet:

http://philippe.developpez.com/articles/SOLIDdotNet/

Se documenter sur la sécurité et WCF

Jérémy a regroupé dans un post quelques liens élémentaires sur WCF et la sécurité, à lire impérativement :

http://www.jjeanson.fr/1/Post.aspx?post=4600cecc-48f9-6c3f-b5fa-bbe2eefaf607