Archives Catégorie: Développement SharePoint

HTTP 406 Erreur lors de l'utilisation $http.get angulaire contre les Points de terminaison pour le repos SharePoint

Mise à jour: Marc AD ndersson a souligné ce grand morceau de l'info: http://blogs.Office.com/2014/08/13/JSON-Light-support-Rest-SharePoint-API-Released/. Qui explique beaucoup de choses :).

C'est peut-être le pire titre d'un billet de blog jamais! Anyhoo.

Généralement, je fais toutes mes prototypage sur une instance d'Office 365. J'ai mon instance personnelle afin que je ne dois pas être inquiet qui touchent tout le monde. Soit dit en passant – Rappelez-vous lorsque nous appelons menées autour des machines virtuelles sur nos ordinateurs portables avec MOSS – SQL Server, IIS, décidant de Hyper-V vs. VMWare? Anyhoo...

J'avais mis au point une application à l'aide de moment angulaire dans cet environnement qui fait, entre autres choses, ce:

$http.Get(serverUrl)
.succès(fonction(données, statut, en-têtes, config) {

var getLinksResponse = données;

getLinksResponse.value.forEach(fonction(theResult) {

// et ainsi de suite et donc de mousse

Cela fonctionnait très bien dans deux environnements SharePoint en ligne. Cependant, Quand mon collègue il porté vers une instance de Cloudshare, il devenait un HTTP 406 erreur (qui était la première fois jamais, je suis celui-là, donc... yay, Je pense). Nous avons fait quelques recherches et a remarqué que l'en-tête « Accepter » était éteint. SharePoint en ligne était parfaitement heureux avec:

Accepter: application/json

Mais l'instance de cloudshare (qui est SP sur prem, hébergé sur un serveur virtuel) voulait le classique « odata = verbose "ajouté dans ainsi:

Accepter: application/json;OData = verbose

Pour résoudre ce, Nous avons ajouté l'en-tête comme tel:

var config = {en-têtes: {
« Accepter »: « application/json;OData = verbose'
}
};

$http.Get(serverUrl,config)
.succès(fonction(données, statut, en-têtes, config) {

var getLinksResponse = données;

getLinksResponse.value.forEach(fonction(theResult) {

// et ainsi de suite et donc de mousse

Qui s'est débarrassé de la 406, mais il a aussi changé le format de la réponse. C'était plus... bavard. (haha!) Plusieurs modifications ont été nécessaires et voici le résultat final:

var config = {en-têtes: {
« Accepter »: « application/json;OData = verbose'
}
};

$http.Get(serverUrl,config)
.succès(fonction(données, statut, en-têtes, config) {

var getLinksResponse = données;

getLinksResponse.d.Results.forEach(fonction(theResult) {

// et ainsi de suite et donc de mousse

C'est seulement transformée en un 30 problème minute pour nous, donc nous avons eu de la chance. J'espère que quelqu'un le trouve utile.

</fin>

Prise de conscience / Adoption des Frameworks JavaScript

Mon collègue, Javed Ansari (http://www.bigapplesharepoint.com/team?showExpertName=Javed%20Ansari&rsource=pgblog), a écrit un billet de blog résumé court sur les cadres qu'il aime ou a au moins utilisé avec SharePoint: http://www.bigapplesharepoint.com/pages/View-An-Insight.aspx?BlogID=53&rsource=PGBlog).

jQuery semble avoir été le vainqueur sur le terrain, pour ainsi dire, depuis des années, mais les autres sont plus nouvelles et alambics en quelque sorte luttant contre elle, comme le moment angulaire. (SPServices, Bien sûr, est un épargnant de vie depuis années et continuera d'être donc je pense que).

Ce que les gens utilisent? Ils sont concentrent davantage sur un outillage de Microsoft (CSOM / JSOM) ou se déplaçant vers le moment cinétique, Knockout, Ember, etc.?

J'ai un penchant croissant pour ces cadres non Microsoft. Je pense que les trucs MSFT sont plus difficile et plus difficiles à travailler avec, exiger presque comme une grande partie de la courbe d'apprentissage comme ancienne côté serveur dev.

Poster un commentaire ici ou plus à Grosse pomme SharePoint Si vous voulez discuter (Big Apple aura plus de chances d'une bonne discussion).

</fin>

Des travaux de minuteur SharePoint de Configuration du Site Collection de filature

Mon collègue, Pierret, a écrit un billet de blog décrivant une architecture de travail flexible minuterie qui offre une certaine souplesse agréable à l'appui des tâches longues et/ou des rapports.  Selon ses propres mots:

1. Analyse de vérifié les fichiers et envoyer des rappels aux individus, si le nombre de jours (étant donné que le fichier a été extrait) dépasser certaines valeurs limites

2. Suppression des liens de tout autre contenu lorsqu'un contenu particulier est supprimé ou archivé à partir du système

3. L'utilisateur veut voir toutes les alertes qu'il souscrit à toutes les toiles de la collection de sites

4. Envoi d'un rappel aux auteurs de réviser le contenu lorsqu'un délai d'examen a été spécifié dans le contenu et que la date se rapproche

Puits, la liste est longue...

– Voir plus à: http://www.bigapplesharepoint.com/ pages/vue-An-Insight.aspx?BlogID=40#sthash.7cKuiwly.dpuf

Il ya des moments dans mon passé quand quelque chose comme ça aurait été très utile.

</fin>

Comment: Configurer le Test unitaire et couverture de Test avec QUnit.js et Blanket.js pour un bureau 365 App de SharePoint

Intro

J'ai avez exploré les tests unitaires et testez couverture JavaScript comme je travaille sur une nouvelle application SharePoint pour SharePoint en ligne au bureau 365 suite.  Les chemins de recherche évidente m'a amené à QUnit.js et juste après que, À Blanket.js.

QUnit je voudrais mettre en place des tests unitaires et regroupez-les en modules.  Un module est juste une façon simple d'organiser des tests connexes. (Je ne suis pas sûr que je l'utilise comme prévu, mais ça marche pour moi jusqu'à maintenant avec le petit ensemble de tests, que j'ai défini à ce jour).

Blanket.js s'intègre avec Qunit et il va me montrer les lignes réelles de JavaScript qui étaient – et surtout – pas réellement exécutés au cours de l'exécution des tests.  Il s'agit d'une « couverture »-lignes exécutées sont couvertes par l'épreuve tandis que d'autres ne le sont pas.

Entre la mise en place de bonnes cas de test et la visualisation de couverture, Nous pouvons réduire le risque que notre code a des vices cachés.  Bons moments.

QUnit

En supposant que vous avez votre Visual Studio projet mis en place, Commencez par Télécharger le package de JavaScript de http://qunitjs.com.  Ajouter le JavaScript et CSS correspondant à votre solution.  Mine ressemble à ceci:

image

Figure 1

Comme vous pouvez le voir, J'utilisais 1.13.0 au moment où j'ai écrit ce billet de blog. N'oubliez pas de télécharger et ajouter le fichier CSS.

Que, sur le chemin, étape suivante consiste à créer une sorte d'atelier de test et les bits de Qunit de référence.  Je teste un tas de fonctions dans un fichier de script appelé « QuizUtil.js » donc j'ai créé une page HTML appelée « QuizUtil_test.html » comme indiqué:

image Figure 2

Voici le code:

<!DOCTYPE html>
<html xmlns= "http://www.w3.org/ 1999/xhtml">
<tête>
    <titre>Essai de QuizUtil avec Qunit</titre>
    <lien rel= "stylesheet" href="../CSS/QUnit-1.13.0.CSS" />
    <script type= text/javascript"" SRC="QuizUtil.js" données-couverture></script>
    <script type ="text/javascript" SRC =« qunit-1.13.0.js"></script>
    <script type ="text/javascript" SRC ="blanket.min.js"></script>

    <script>
        module("getIDFromLookup");
        test("QuizUtil getIDFromLookupField", fonction () {
            var goodValue = 1";#Paul Galvin";

            égal(getIDFromLookupField(goodValue) + 1, 2), "ID de [" + goodValue + "] + 1 devrait être 2";
            égal(getIDFromLookupField(indéfini), indéfini, "Undefined argument d'entrée doit retourner le résultat indéfini.");
            égal(getIDFromLookupField(""), indéfini, "Argument d'entrée vide doit retourner une valeur non définie.");
            égal(getIDFromLookupField(« gobbledigood3-thq;dkvn ada;skfja sdjfbvubvqrubqer0873407t534piutheqw;VN"), indéfini,« Doit toujours retourner une décapotable de résultat en un nombre entier");
            égal(getIDFromLookupField(2";#une autre personne"), 2"", « La vérification des [2;#une autre personne].");
            égal(getIDFromLookupField("9834524;#valeur de type long"), "9834524", « Test de grande valeur.");
            notEqual(getIDFromLookupField(5";#n'importe qui", 6), 6, "Tester un notEqual (5 n'est pas égal à 6 pour cet exemple: [5;#n'importe qui]");

        });

        module("htmlEscape");
        test("QuizUtil htmlEscape()", fonction () {
            égal(htmlEscape("<"), "&lt;", « Échapper un opérateur less than ('<')");
            égal(htmlEscape("<div class =  « someclass »>Certains texte</Div>"), "&lt;div class =&quot;SomeClass&quot;&gt;Certains texte&lt;/Div&gt;", "Chaîne de test plus complexe.");
        });

        module("getDateAsCaml");
        test("QuizUtil getDateAsCaml()", fonction () {
            égal(getDateAsCaml(Nouveau Date(« 31/12/2013")), « 2013-12-31 T:00:00:00", "Tests codés en dur date: [12/31/2013]");
            égal(getDateAsCaml(Nouveau Date("01/05/2014")), « 2014-01-05T:00:00:00", "Tests codés en dur date: [01/05/2014]");
            égal(getDateAsCaml(Nouveau Date("01/31/2014")), « 2014-01-31 T:00:00:00", "Tests codés en dur date: [01/31/2014]");
            égal(getTodayAsCaml(), getDateAsCaml(Nouveau Date()), "getTodayAsCaml() doit être égal à getDateAsCaml(nouvelle Date())");
            égal(getDateAsCaml(« valeur de non-sens"), indéfini, "Essayer d'obtenir la date d'une valeur de l'absurdité.");
            égal(getDateAsCaml(indéfini), indéfini, "Essayer d'obtenir la date de la [indéfini] Date.");
        });

        module("getParameterByName");
        test("QuizUtil getParameterByName (de la chaîne de requête)", fonction () {
            égal(getParameterByName(indéfini), indéfini, "Essayer d'obtenir non défini paramètre doit retourner non défini.");
            égal(getParameterByName("n'existe pas"), indéfini, "Essayer d'obtenir la valeur du paramètre quand on sait que le paramètre n'existe pas.");

        });

        module("Cookies");
        test(« QuizUtil diverses fonctions de cookie.", fonction () {
            égal(setCookie(« test", 1"", -1), getCookieValue(« test"), "Obtenir un cookie j'ai mis devrait fonctionner.");
            égal(setCookie("anycookie", 1"", -1), True, "Définissant une cuisson valide doit retourner à 'true'.");
            égal(setCookie("nom du cookie fou !@#$%"%\^&*(()?/><.,", 1"", -1), True, "Définir un nom de cookie mauvaise doit retourner"faux".");
            égal(setCookie(indéfini, 1"", -1), indéfini, "En passant pas défini comme nom de cookie.");
            égal(getCookieValue("n'existe pas"), "", « Cookie n'existe pas de test.");
        });

    </script>
</tête>
<corps>
    <Div ID= qunit""></Div>
    <Div ID= "qunit-luminaire"></Div>

</corps>
</html>

Il y a plusieurs choses qui se passe ici:

  1. Référencement de mon code (QuizUtil.js)
  2. Référencement Qunity.js
  3. Définition de certains modules (getIDFromLookup, Cookies, et d'autres)
  4. Placer un <Div> dont l'ID est « qunit ».

Puis, J'ai juste tirer vers le haut de cette page et vous obtenez quelque chose comme ça:

image

Figure 3

Si vous regardez dans la partie supérieure, vous avez quelques options, deux d'entre eux sont intéressants:

  • Masquer les tests passés: Assez évident.  Peut aider le œil il suffit de voir les zones à problèmes et pas beaucoup de fouillis.
  • Module: (déroulant): Ceci filtrera les tests vers le bas pour que les groupes de tests que vous voulez.

En ce qui concerne les tests eux-mêmes – quelques commentaires:

  • Il va sans dire que vous devez écrire votre code tel qu'il est testable en premier lieu.  À l'aide de l'outil peut aider à faire respecter cette discipline. Par exemple, J'ai eu une fonction appelée "getTodayAsCaml()”.  Ce n'est pas très testable puisque cela ne prend aucun argument d'entrée et de le tester pour l'égalité, Nous aurions besoin de constamment mettre à jour le code de test afin de tenir compte de la date du jour.  J'ai refait il par ajout d'un paramètre d'entrée de données, puis en passant la date actuelle quand je veux la date du jour en format CAML.
  • Le cadre Qunit documente ses propres tests, et il semble assez robuste.  Il peut faire des choses simples comme test d'égalité et possède aussi un support pour les appels de style ajax (les « vrais » ou moqué en utilisant votre mocker préféré).
  • Franchi les étapes également vous oblige à penser par cas – ce qui se passe avec « undefined » ou la valeur null est passée dans une fonction.  Il le rend simple tester ces scénarios sur.  Bonnes choses.

Couverture avec Blanket.js

Blanket.js complète Qunit en suivant les lignes réelles du code qui s'exécutent au cours de l'exécution de vos tests.  Il intègre droit dans Qunit donc, bien que c'est une application à part entière, Il joue bien : il semble vraiment que c'est une appli sans soudure.

Il s'agit de blanket.js en action:

image Figure 4

image

Figure 5

(Vous devez cliquer sur la case « Activer la couverture » en haut [Voir Figure 3] pour permettre cela.)

Les lignes en surbrillance sur la Figure 5 n'ont pas été exécutées par l'un de mes tests, J'ai donc besoin de concevoir un test qui provoque leur exécution si je veux une couverture complète.

Obtenir blanket.js en suivant ces étapes de travail:

  1. Télécharger à partir http://blanketjs.org/.
  2. Ajoutez-le à votre projet
  3. Mettre à jour votre page d'atelier de test (QuizUtil_test.html dans mon cas) comme suit:
    1. Le code de référence
    2. Décorez votre <script> référencer comme suit:
    <script type= text/javascript"" SRC="QuizUtil.js" données-couverture></script>

Blanket.js récupère l'attribut « données-couverture » et fait sa magie.  Il raccorde à Qunit, met à jour l'interface utilisateur pour ajouter l'option « Activer la protection » et voila!

Résumé (TL; DR)

Utilisez Qunit pour écrire vos scénarios de test.

  • Téléchargez-le
  • Ajoutez-le à votre projet
  • Écrire une page d'atelier de test
  • Créer vos tests
    • Refactoriser du code pour pouvoir être testée
    • Faire preuve de créativité!  Pensez à fou, scénarios impossibles des tester en tout cas.

Utilisez blanket.js pour assurer une couverture

  • Assurez-vous que Qunit fonctionne
  • Télécharger blanket.js et ajoutez-le à votre projet
  • Ajouter à votre page d'atelier de test:
    • Ajoutez une référence à blanket.js
    • Ajoutez un attribut « données-couverture » à votre <script> Tag
  • Exécuter vos tests de Qunit.

Jamais, j'ai fait tout cela avant et avait quelques trucs rudimentaire dans une poignée d'heures de travail. 

Essais heureux!

</fin>

undefinedS'abonner à mon blog.

Me suivre sur Twitter à http://www.twitter.com/pagalvin

Lists.asmx, GetList et « valeur ne peut pas être null”

J'ai découvert aujourd'hui que la GetList() méthode en lists.asmx service Web doit être appelée très soigneusement ou il est enclin à lancer un mystérieux « Valeur ne peut pas être null » exception (et qui est en supposant que vous aurez passé le message d'erreur générique encore pire, "Exception de type « Microsoft.SharePoint.SoapServer.SoapServerException’ a été lancée. »)  Spécifiquement, Je trouve que vous ne peut pas fournir toute sorte de préfixe sur la méthode GetList.  L'extrait suivant de jQuery illustre le point:

image

Si vous faites cela, le service web répond avec « Valeur ne peut être null » selon cette violon-fourni la transcription HTTP:

<?XML version = "1.0" Encoding = « utf-8 »?>
  <savon:Enveloppe
     xmlns:savon ="
http://schemas.xmlsoap.org/soap/envelope/"    
     xmlns:xsi = "
http://www.w3.org/2001/XMLSchema-instance
     xmlns:xsd ="
http://www.w3.org/2001/XMLSchema">

  <savon:Corps>
    <savon:Faute>
      <FaultCode>savon:Serveur</FaultCode>
      <FaultString>
        Exception de type « Microsoft.SharePoint.SoapServer.SoapServerException’ a été levée.
      </FaultString>
      <détail>
        <ErrorString xmlns ="
http://schemas.Microsoft.com/SharePoint/SOAP/">
Valeur ne peut pas être null.
        </ErrorString>
      </détail>
    </savon:Faute>
  </savon:Corps>
</savon:Enveloppe>

Bien sûr, vous ne serait pas probablement ajouter ce préfixe « s0 » sur votre propre, mais certains outils ont tendance à le faire (comme Eclipse).

C'est d'autant plus déroutant / frustrant parce que les autres méthodes de tolèrent les préfixes.  Par exemple, le GetListCollection méthode n'est pas l'esprit si elle est été préfixé, même avec les préfixes absurdes comme « xyzzy »:

image

Cette « valeur ne peut pas être null » semble assez commun avec lists.asmx donc j'espère que cela aidera quelqu'un sortir à l'avenir.

</fin>

S'abonner à mon blog.

Me suivre sur Twitter à http://www.twitter.com/pagalvin

Sans cesse de nidification <Div> Étiquettes et jQuery

Cela semble un tel sujet d'excentrique, Je ne suis pas sûr que c'est vraiment utile sur les blogs, mais qui a jamais cessé de me avant, donc ici, nous allons Sourire

Je travaille un projet où je suis tirer certaines données de recherche, emballage il dans un message XML, puis que XML est finalement transformé en HTML via XSLT.  Il y a beaucoup de jQuery, un bit qui implémente certaines fonctionnalités de tabulation.  Lorsque vous cliquez sur un onglet (vraiment, un <Div>), jQuery appelle .hide() et .show() sur divers divs (le chargement de la page initiale télécharge tout le contenu, il n'y a aucune publication dans ce cas).

Un tas de jours ago, l'onglet logique de commutation a commencé à se comporter de façon erratique et il ne serait pas montrer un de mes onglets.  J'ai finalement suivi il vers le fait qu'internet explorer (au moins) estime que la <Div> balises imbriquées loin, beaucoup plus profond que prévu.La barre d'outils développeur montrerait:

-<div id = « Tab1Content »>
  -<Div>
    -<Div>
      -<div id = « Tab2Content »>
        -<Div>
           …………………………
                   </Div>  <— montrant Enfin il fut fermé jusqu'ici!

Si, Si j'ai fait un $(« # Tab1Content »).cacher(), Tab2 serait également masquer et je ne pourrais jamais montrer Tab2 si je n'a pas montrer aussi Tab1.  J'ai copié et collé le code dans visual studio et il a montré de doublure de la div pied joliment, tout comme ils étaient censés faire, qui ressemble à ceci:

-<div id = « Tab1Content »>
  +<Div>
  +<Div>
-<div id = « Tab2Content »>
  +<Div>
  +<Div>

Je bat ma tête contre le mur pendant un certain temps et a remarqué que dans le réel HTML code générait beaucoup de vide <Div> balises, comme:

<corps>

  <div id = « Tab1Content »>

    <div id = « row1 » />
    <div id = « row2 » />

  </Div>

  <div id = « Tab2Content »>

    <div id = « row1 » />
    <div id = « row2 » />

  </Div>

</corps>

(Ce qui précède est waaaaaaaaaaaay trop simplifié.  Les balises div vide sont totalement valides. Certains de mes <Div> balises étaient pleins de contenu, mais beaucoup d'autres ne le sont pas.  Je suis arrivé à la prise de conscience que mon <XSL:pour chaque> les directives ont été émettant la forme abrégée des balises div quand le xsl:n'a pas pour chaque « trouver toutes les données.  J'ai forcé un commentaire HTML dans la sortie, comme le montre:

image

 

Après que je le faisais, la div alignés parfaitement et mon onglet basculement a commencé à travailler.

Comme toujours, J'espère que cela aide quelqu'un dans une pincée.

</fin>

S'abonner à mon blog.

Me suivre sur Twitter à http://www.twitter.com/pagalvin

Une Cause pour « le créateur de cette faille ne précise pas une raison.”

J'ai fait beaucoup de travail avec SharePoint recherche dernièrement et plus particulièrement la classe KeywordQuery, propriétés et méthodes.

Si vous souhaitez que le jeu de résultats à retourner des résultats au-delà d'usual suspects (voir ici), vous ajouter à la collection SelectedProperties, comme dans:

myKeywordQuery.SelectProperties.Add(« xyzzy »);

Merci beaucoup et un truc du chapeau à Corey Roth et ce billet de blog extrêmement utile (http://www.dotnetmafia.com/blogs/dotnettipoftheday/archive/2008/02/19/how-to-use-the-moss-enterprise-search-keywordquery-class.aspx)

Dans mon cas, « xyzzy » n'est pas réellement une propriété gérée.  Lorsque j'ai ajouté à SelectedProperties de toute façon, SharePoint a jeté un de mes favoris toujours des exceptions runtime:

« Le créateur de cette faille ne précise pas une raison. »

J'aime particulièrement la capitale « R » dans la raison.  Cela sonne pour moi comme la.NET équivalent de »Je n'ai aucune bouche, et je dois crier.”

</fin>

S'abonner à mon blog.

Me suivre sur Twitter à http://www.twitter.com/pagalvin

Référence pratique: Par défaut résultats de la recherche KeywordQuery

Lorsque vous invoquez l'Execute() méthode sur un KeywordQuery, vous pouvez créer un ResultTable basé sur ResultType.RelevantResults.  Cet extrait de code illustre ce que je veux dire:

ResultTableCollection resultsTableCollection = myKeywordQuery.Execute();

ResultTable searchResultsTable = resultsTableCollection[ResultType.RelevantResults];

La table résultante aura les colonnes suivantes de l'information: 

WorkId
Grade
Titre
Auteur
Taille
Chemin d'accès
Description
Écriture
Nom du site
CollapsingStatus
HitHighlightedSummary
HitHighlightedProperties
ContentClass
IsDocument
PictureThumbnailURL
ServerRedirectedURL

J'ai cette liste dérivé un SharePoint 2010 environnement, Enterprise edition.  J'espère que ce sera utile à quelqu'un à l'avenir.

</fin>

S'abonner à mon blog.

Me suivre sur Twitter à http://www.twitter.com/pagalvin

Une des raisons pour: « Impossible d'extraire le fichier cab de la solution”

Alors qu'il travaillait sur un composant WebPart de visual studio de projet aujourd'hui, J'ai fait une re-org mineur de certains fichiers à mettre dans le dossier _layouts dans le cadre du processus de déploiement. Spécifiquement, J'ai renommé un fichier .js de « TypeAhead.js » de TypeAhead"(vieux).js »  J'ai l'intention de l'enlever dès que son successeur, « TypeAhead.js » s'avère correcte.  Il ressemblait à ceci:

image

Cela a immédiatement provoqué un problème avec visual studio lorsque j'ai essayé de déployer le projet:

Erreur s'est produite à l'étape de déploiement « Ajouter une Solution »: Ne pas extraire le fichier cab de la solution.

Il s'avère que vous ne devez pas mettre une parenthèse dans les noms de fichier.  J'ai enlevé les parens et qui a résolu le problème.

</fin>

S'abonner à mon blog.

Me suivre sur Twitter à http://www.twitter.com/pagalvin