Categorie Archieven: SharePoint ontwikkeling

HTTP 406 Fout bij het gebruik van hoekige $http.get tegen SharePoint REST eindpunten

Update: Marc AD ndersson om erop te wijzen dit grote stuk van info: http://blogs.Office.com/2014/08/13/JSON-Light-Support-rest-SharePoint-API-Released/. Dat verklaart veel :).

Dat is misschien wel de ergste titel van een blogpost ooit! Hoe dan ook.

Ik meestal doe alle van mijn prototyping tegen een O365 exemplaar. Ik heb mijn persoonlijke exemplaar, zodat ik niet hoef te worden bezorgd op het gebied van iemand anders. Als een terzijde-Onthoud wanneer wij uitgevoerd rond virtuele machines op onze laptops met mos-SQL Server, IIS, beslissende Hyper-V vs. VMWare? Hoe dan ook...

Ik had ontwikkeld een app gebruikt Angular in deze omgeving die doet, onder andere, Dit:

$http.Get(serverUrl)
.succes(functie(gegevens, status, headers, config) {

var getLinksResponse = data;

getLinksResponse.value.forEach(functie(theResult) {

// en zo verder en zo schuim

Dit werkte prima in twee verschillende SharePoint online omgevingen. Echter, Toen mijn collega het ported aan de aanleg van een Cloudshare, Hij kreeg een HTTP 406 fout (die was de eerste keer dat ik ooit kreeg die ene, dus... yay, Denk ik). We heb een beetje van het onderzoek en merkte dat de "Accept" header uitgeschakeld was. SharePoint online was perfect gelukkig met:

Accepteren: application/json

Behalve het cloudshare exemplaar (Wat is SP op prem, gehost op een virtuele server) wilde de klassieke "odata = verbose" toegevoegd ook:

Accepteren: application/json;odata = verbose

Om dat te bevestigen, Wij toegevoegd de kop als zodanig:

var config = {headers: {
'Accepteren': ' application/json;odata = verbose'
}
};

$http.Get(serverUrl,config)
.succes(functie(gegevens, status, headers, config) {

var getLinksResponse = data;

getLinksResponse.value.forEach(functie(theResult) {

// en zo verder en zo schuim

Die verlost van de 406, maar het ook de indeling van de reactie gewijzigd. Het was meer... uitgebreide. (haha!) Meer veranderingen nodig waren en hier is het eindresultaat:

var config = {headers: {
'Accepteren': ' application/json;odata = verbose'
}
};

$http.Get(serverUrl,config)
.succes(functie(gegevens, status, headers, config) {

var getLinksResponse = data;

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

// en zo verder en zo schuim

Dit alleen omgezet in een 30 minuut probleem voor ons, Dus wij lucked uit. Hopelijk vindt iemand dit nuttig.

</einde>

Groeiend bewustzijn / Aanneming van JavaScript-Frameworks

Mijn collega, Javed Ansari (http://www.bigapplesharepoint.com/team?showExpertName=Javed%20Ansari&rsource=pgblog), schreef een korte samenvatting blogpost op kaders hij houdt of op zijn minst met heeft geweest using met SharePoint: http://www.bigapplesharepoint.com/pages/View-An-Insight.aspx?BlogID=53&rsource=PGBlog).

jQuery lijkt te zijn de overwinnaar op het veld, bij wijze van spreken, jarenlang nu, maar de anderen zijn meer nieuwe en foto's sorteren van het vechten, zoals Angular. (SPServices, Natuurlijk, is een life saver jarenlang geweest en zal blijven worden dus ik denk dat).

Wat zijn mensen gebruiken? Ze zijn meer gericht op Microsofts tooling (CSOM / JSOM) of meer richting Angular verplaatsen, Knock-out, Sintel, etc?

Ik heb een groeiende vooroordeel richting van deze niet-Microsoft-kaders. Ik denk dat de MSFT spul is moeilijker en moeilijker om te werken met, die bijna net zo veel van het leren kromme als oude-stijl serverkant dev.

Post een commentaar hier of over ten Big Apple SharePoint Als u wilt bespreken (Big Apple zal hebben meer kans op een goede discussie).

</einde>

SharePoint-timeropdrachten van collectie Siteconfiguratie spinnen

Mijn collega, Ashish Patel, schreef een blogpost met een beschrijving van een flexibele timer baan architectuur dat biedt sommige aardige flexibiliteit ter ondersteuning van langlopende taken en/of rapporten.  In zijn woorden:

1. Ingeschakeld uit bestanden analyseren en herinneringen te sturen naar de individuen als het aantal dagen (Sinds het bestand werd uitgecheckt) bepaalde drempel overschrijden

2. Verwijderen van links van andere inhoud wanneer een bepaalde inhoud wordt verwijderd of gearchiveerd uit het systeem

3. Gebruiker wil zien alle meldingen waarop hij in alle webs in de siteverzameling ingeschreven

4. Een herinneringen verzenden aan auteurs de inhoud te beoordelen wanneer een beoordeling tijd werd opgegeven in de inhoud en die datum nadert

Goed, de lijst gaat verder...

– Meer info op: http://www.bigapplesharepoint.com/ pagina's / weergave-An-Insight.aspx?BlogID=40#sthash.7cKuiwly.dpuf

Er zijn momenten in mijn verleden wanneer met iets als dit zou zeer nuttig geweest.

</einde>

Procedures: Unit Test en Test dekking met QUnit.js en Blanket.js voor een Office configureren 365 SharePoint App

Intro

Ik heb het verkennen van eenheid die test en test dekking voor JavaScript als ik werk op een nieuwe SharePoint-app voor SharePoint online in het kantoor 365 Suite.  De paden voor de hand liggende onderzoek leidde me om te Qunit.js en direct na dat, Aan Blanket.js.

QUnit laat me eenheid tests instellen en groeperen in modules.  Een module is gewoon een eenvoudige manier om te organiseren gerelateerde tests. (Ik ben niet zeker dat ik gebruik het als bedoeld, maar het werkt voor mij tot nu toe met de kleine set van tests die ik tot nu toe hebt gedefinieerd).

Blanket.js integreert met Qunit en het zal mij de feitelijke lijnen van JavaScript die waren- en nog belangrijker-werden niet daadwerkelijk uitgevoerd tijdens het uitvoeren van de tests.  Dit is "dekking"-lijnen die uitgevoerd worden gedekt door de test, terwijl anderen niet zijn.

Tussen goede testcases instellen en weergeven van de dekking, We kunnen het risico dat onze code heeft verborgen gebreken.  Goede tijden.

Qunit

Veronderstellend hebt u uw Visual Studio project instellen, Begin door te downloaden van het pakket JavaScript uit http://qunitjs.com.  De JavaScript en bijbehorende CSS toevoegen aan uw oplossing.  Mine ziet er als volgt:

image

Figuur 1

Zoals u kunt zien, Ik was met behulp van 1.13.0 op het moment schreef ik deze blogpost. Vergeet niet om te downloaden en het CSS-bestand toevoegen.

Dat uit de weg, volgende stap is het maken van een soort van testuitrusting en verwijst naar de Qunit bits.  Ik ben het testen van een heleboel functies in een scriptbestand genaamd "QuizUtil.js" dus ik heb een HTML-pagina met de naam "QuizUtil_test.html gemaakt" zoals:

image Figuur 2

Hier is de code:

<!DOCTYPE HTML>
<HTML xmlns= 'http://www.w3.org/ 1999/xhtml">
<hoofd>
    <titel>QuizUtil test met Qunit</titel>
    <koppeling rel= "stylesheet" href="../CSS/qunit-1.13.0.CSS" />
    <script type= text/javascript"" src="QuizUtil.js" gegevens-cover></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", functie () {
            var goodValue = "1;#Paul Galvin";

            gelijke(getIDFromLookupField(goodValue) + 1, 2), "ID van [" + goodValue + "] + 1 2 moeten worden";
            gelijke(getIDFromLookupField(undefined), undefined, "Niet-gedefinieerde invoer argument moet ongedefinieerde resultaat te retourneren.");
            gelijke(getIDFromLookupField(""), undefined, "Lege invoer argument moet een niet-gedefinieerde waarde retourneren.");
            gelijke(getIDFromLookupField("gobbledigood3-thq;dkvn ada;skfja sdjfbvubvqrubqer0873407t534piutheqw;VN"), undefined,"Moeten altijd terug een resultaat Cabrio naar een geheel getal");
            gelijke(getIDFromLookupField("2;#enige andere persoon"), "2", "Checking [2;#enige andere persoon].");
            gelijke(getIDFromLookupField("9834524;#Long-waarde"), "9834524", "Grote waarde test.");
            notEqual(getIDFromLookupField("5;#iedereen", 6), 6, "Het testen van een notEqual (5 is niet gelijk aan 6 voor dit voorbeeld: [5;#iedereen]");

        });

        module("htmlEscape");
        test("QuizUtil htmlEscape()", functie () {
            gelijke(htmlEscape("<"), "&lt;", "Ontsnappen een minder dan, operator ('<')");
            gelijke(htmlEscape("<div class =  "someclass">Sommige tekst</div>"), "&lt;div class =&quot;someclass&quot;&gt;Sommige tekst&lt;/div&gt;", "Meer complexe test string.");
        });

        module("getDateAsCaml");
        test("QuizUtil getDateAsCaml()", functie () {
            gelijke(getDateAsCaml(Nieuw Datum("12/31/2013")), "2013-12-31T:00:00:00", "Testing hard gecodeerde datum: [12/31/2013]");
            gelijke(getDateAsCaml(Nieuw Datum("01/05/2014")), "2014-01-05T:00:00:00", "Testing hard gecodeerde datum: [01/05/2014]");
            gelijke(getDateAsCaml(Nieuw Datum("01/31/2014")), "2014-01-31T:00:00:00", "Testing hard gecodeerde datum: [01/31/2014]");
            gelijke(getTodayAsCaml(), getDateAsCaml(Nieuw Datum()), "getTodayAsCaml() moet gelijk zijn aan getDateAsCaml(nieuwe datum())");
            gelijke(getDateAsCaml("onzin waarde"), undefined, "Proberen om de datum van de waarde van een onzin.");
            gelijke(getDateAsCaml(undefined), undefined, "Probeer om de datum van de [undefined] datum.");
        });

        module("getParameterByName");
        test("QuizUtil getParameterByName (uit de querytekenreeks)", functie () {
            gelijke(getParameterByName(undefined), undefined, "Proberen om te krijgen niet-gedefinieerde parameter ongedefinieerde moet retourneren.");
            gelijke(getParameterByName("does not exist"), undefined, "Proberen om de waarde van de parameter wanneer we weten dat de parameter niet bestaat.");

        });

        module("Cookies");
        test("QuizUtil verschillende cookie functies.", functie () {
            gelijke(setCookie("test", "1", -1), getCookieValue("test"), "Get een cookie ik ingesteld zou moeten werken.");
            gelijke(setCookie("anycookie", "1", -1), True, "Instellen van een geldig koken moet retourneren 'true'.");
            gelijke(setCookie("gekke cookienaam !@#$%"%\^&*(()?/><.,", "1", -1), True, "Instellen van een slechte cookienaam moet retourneren 'valse'.");
            gelijke(setCookie(undefined, "1", -1), undefined, "Passing ongedefinieerde als de cookienaam.");
            gelijke(getCookieValue("does not exist"), "", "Cookie does not exist test.");
        });

    </script>
</hoofd>
<lichaam>
    <div id"qunit ="></div>
    <div id= "qunit-armatuur"></div>

</lichaam>
</HTML>

Er zijn verschillende dingen gebeuren hier:

  1. Verwijzen naar mijn code (QuizUtil.js)
  2. Verwijzen naar Qunity.js
  3. Sommige modules definiëren (getIDFromLookup, Cookies, en anderen)
  4. Plaatsen van een <div> waarvan de ID is "qunit".

Vervolgens, Ik trek alleen deze pagina en krijg je zoiets als dit:

image

Figuur 3

Als je aan de bovenkant kijkt, u hebt een paar opties, waarvan er twee zijn interessant:

  • Verbergen voorbij tests: Vrij duidelijk.  Kan helpen uw oog gewoon zien de probleemgebieden en niet een heleboel rommel.
  • Module: (drop-down): Dit zal de tests tot alleen die groepen van tests die u wilt filteren.

Wat betreft de tests zelf-een paar opmerkingen:

  • Het spreekt vanzelf dat you need to Schrijf uw code zodanig zijn dat het in de eerste plaats testbare is.  Met behulp van het hulpprogramma kunt afdwingen die discipline. Bijvoorbeeld, Ik had een functie genaamd "getTodayAsCaml()”.  Dit is niet zeer testbare aangezien het geen invoer argument neemt en testen voor gelijkheid, We zouden moeten voortdurend actualiseren van de test-code om te reflecteren op de huidige datum.  Ik refactored het door een invoerparameter gegevens toevoegen dan langs de huidige datum wanneer ik wil de datum van vandaag in CAML formaat.
  • Het Qunit kader documenten zijn eigen proeven en het lijkt vrij robuust.  Het kan doen eenvoudige dingen zoals testen voor gelijkheid en heeft ook ondersteuning voor ajax stijl oproepen (zowel de "echte" of de mocked met behulp van uw favoriete mocker).
  • Gaan door het proces ook dwingt je om na te denken door middel van randgevallen – wat er gebeurt met "undefined" of null wordt doorgegeven aan een functie.  Het maakt het doodsimpel om te testen deze scenario's uit.  Goed spul.

Dekking met Blanket.js

Blanket.js is een aanvulling op Qunit door het bijhouden van de werkelijke lijnen van code die in de loop van het runnen van uw tests worden uitgevoerd.  Het integreert dus zelfs al is het een hele aparte app recht in Qunit, het speelt mooi-het echt lijkt alsof het is een naadloze app.

Dit is blanket.js in actie:

image Figuur 4

image

Figuur 5

(Je eigenlijk hebben om te klikken op het selectievakje "Enable dekking" aan de bovenkant [Zie figuur 3] om dit mogelijk te maken.)

De gemarkeerde regels in figuur 5 niet zijn uitgevoerd door een van mijn tests, dus ik moet ontwikkelen een test die leidt hen om uit te voeren tot als ik wil volledige dekking.

Krijgen blanket.js werken door deze stappen te volgen:

  1. Het downloaden van http://blanketjs.org/.
  2. Toe te voegen aan uw project
  3. Bijwerken van uw testpagina harnas (QuizUtil_test.html in mijn geval) als volgt:
    1. Verwijst naar de code
    2. Versier uw <script> verwijst naar uitzien:
    <script type= text/javascript"" src="QuizUtil.js" gegevens-cover></script>

Blanket.js pikt het kenmerk "gegevens-cover" en doet zijn magie.  Het haken in Qunit, bijgewerkt de UI als u wilt toevoegen de optie "Enable dekking" en voila!

Samenvatting (TL; DR)

Gebruik Qunit om te schrijven uw testcases.

  • Downloaden
  • Toe te voegen aan uw project
  • Schrijf een testpagina harnas
  • Maak uw tests
    • Sommige van uw code testbare refactoring
    • Wees creatief!  Denk aan gek, onmogelijk scenario's en test hen toch.

Gebruik blanket.js om dekking

  • Zorg ervoor dat Qunit werkt
  • Blanket.js downloaden en toevoegen aan uw project
  • Toe te voegen aan uw harnas testpagina:
    • Voeg een verwijzing toe naar blanket.js
    • Voeg een "gegevens-cover" kenmerk toe aan uw <script> Label
  • Uw Qunit tests uitvoeren.

Ik nooit heb een van deze vóór en had sommige rudimentaire dingen werken in een handvol uur. 

Gelukkig testen!

</einde>

undefinedAbonneren op mijn blog.

Volg mij op Twitter op http://www.twitter.com/pagalvin

Lists.asmx, GetList en "waarde kan niet null”

Ik ontdekte vandaag dat de GetList() methode in lists.asmx web-service moet zeer zorgvuldig worden genoemd of het is gevoelig voor het gooien van een mysterieuze "Waarde null kan niet" uitzondering (en dat de veronderstelling dat kunt u voorbij het nog erger algemene foutbericht, "Uitzondering van het type ' Microsoft.SharePoint.SoapServer.SoapServerException’ werd gegooid.")  Specifiek, Ik vond dat u niet elke vorm van voorvoegsel te op de GetList-methode verstrekken.  De volgende jQuery fragment illustreert het punt:

image

Als u dat doen, de webservice reageert met "Waarde kan niet null" als per dit Fiddler-geboden HTTP transcript:

<?XML version = "1.0" encoding = "utf-8"?>
  <zeep:Envelop
     xmlns:zeep ="
http://schemas.xmlsoap.org/soap/envelope/"    
     xmlns:XSi = "
http://www.w3.org/2001/XMLSchema-instance
     xmlns:XSD ="
http://www.w3.org/2001/XMLSchema">

  <zeep:Lichaam>
    <zeep:Schuld>
      <FaultCode>zeep:Server</FaultCode>
      <FaultString>
        Uitzondering van het type ' Microsoft.SharePoint.SoapServer.SoapServerException’ werd gegooid.
      </FaultString>
      <detail>
        <ErrorString xmlns ="
http://schemas.Microsoft.com/SharePoint/SOAP/">
Waarde kan niet null.
        </ErrorString>
      </detail>
    </zeep:Schuld>
  </zeep:Lichaam>
</zeep:Envelop>

Natuurlijk, u niet zou waarschijnlijk toevoegen dat "s0" voorvoegsel op uw eigen, maar sommige tools zijn geneigd om het te doen (zoals Eclipse).

Dit is des te meer verwarrend / frustrerend omdat andere methoden voorvoegsels tolereren.  Bijvoorbeeld, de GetListCollection methode erg niet als het wordt zijn voorafgegaan, zelfs met onzin voorvoegsels zoals "xyzzy":

image

Dit "waarde null kan niet" lijkt vrij algemeen met lists.asmx dus hopelijk dit iemand uit in de toekomst helpen zal.

</einde>

Abonneren op mijn blog.

Volg mij op Twitter op http://www.twitter.com/pagalvin

Eindeloos nesten <div> Tags en jQuery

Dit lijkt een excentrieke onderwerp, Ik ben niet zeker dat het is echt de moeite waard bloggen over, maar dat heeft nooit gestopt me vóór, Dus hier gaan we Glimlach

Ik ben uit te werken op een project waar ik te sommige gegevens uit een zoekopdracht trekken ben, verpakking het omhoog in een XML-bericht en vervolgens dat XML wordt uiteindelijk omgezet in HTML via XSLT.  Er is een heleboel jQuery betrokken, een beetje waarvan sommige tabben functionaliteit implementeert.  Wanneer u klikt op een tabblad (echt, een <div>), jQuery roept .hide() en .show() op diverse divs (de eerste pagina geladen gedownload alle inhoud, zodat er in dit geval geen terugsturen zijn).

Een heleboel uren geleden, het tabblad schakelen logica begon te gedragen onregelmatig en het zou niet een van mijn tabs tonen.  Ik uiteindelijk gevolgd het neer op het feit dat internet explorer (ten minste) dacht dat de <div> Tags genest ver, veel dieper dan bestemd.De werkbalk ontwikkelaar zou weergeven:

-<div id = "Tab1Content">
  -<div>
    -<div>
      -<div id = "Tab2Content">
        -<div>
           …………………………
                   </div>  <— Ten slotte tonen het helemaal naar beneden hier werd gesloten!

Dus, Als ik deed een $("# Tab1Content").verbergen(), Ik zou ook Tab2 verbergen en ik kon nooit tonen Tab2 als ik niet ook Tab1.  Ik gekopieerd en geplakt de code omhoog in visual studio en het bleek alles voor de div's voering tot keurig, net als zij waren verondersteld om te doen, op zoek als dit:

-<div id = "Tab1Content">
  +<div>
  +<div>
-<div id = "Tab2Content">
  +<div>
  +<div>

Ik sloeg mijn hoofd tegen de muur voor een tijdje en gemerkt dat in de werkelijke HTML code is het genereren veel van lege <div> Tags, zoals:

<lichaam>

  <div id = "Tab1Content">

    <div id = "row1" />
    <div id = "row2" />

  </div>

  <div id = "Tab2Content">

    <div id = "row1" />
    <div id = "row2" />

  </div>

</lichaam>

(Het bovenstaande is waaaaaaaaaaaay gesimplificeerd.  De lege div-tags zijn volkomen geldig. Sommige van mijn <div> Tags waren vol van inhoud, maar veel meer waren niet.  Ik kwam tot het besef dat mijn <XSL:for-each> richtlijnen werden de korte vorm uitstoten div tags wanneer de xsl:for-each niet ' gegevens vinden.  Ik gedwongen een HTML-commentaar in de output, zoals:

image

 

Nadat ik deed dat, alle de div's mooi opgesteld en begon te werken mijn tabblad schakelen.

Zoals altijd, Ik hoop dat dit helpt iemand in een snuifje.

</einde>

Abonneren op mijn blog.

Volg mij op Twitter op http://www.twitter.com/pagalvin

Een oorzaak voor "de maker van deze schuld niet een reden specificeerde.”

Ik heb gedaan een heleboel werk met SharePoint search laatste tijd en specifiek de KeywordQuery klasse, eigenschappen en methoden.

Als u wilt dat de resultaatset om terug te keren resultaten boven en buiten de gebruikelijke verdachten (Zie hier), u toevoegen aan de collectie SelectedProperties, Als in:

myKeywordQuery.SelectProperties.Add("xyzzy");

Hartelijk dank en een tip van de hoed aan Corey Roth en deze enorm nuttig blogpost (http://www.dotnetmafia.com/blogs/dotnettipoftheday/archive/2008/02/19/how-to-use-the-moss-enterprise-search-keywordquery-class.aspx)

In mijn geval, "xyzzy" is eigenlijk een beheerde eigenschap niet.  Wanneer ik toegevoegd aan SelectedProperties toch, SharePoint gooide een van mijn favoriete ooit runtime uitzonderingen:

"De maker van deze schuld specificeerde niet een reden."

Ik houd vooral de hoofdletter "R" in reden.  Dit klinkt voor mij als de.NETTO equivalent van"I have no mouth, and I must scream.”

</einde>

Abonneren op mijn blog.

Volg mij op Twitter op http://www.twitter.com/pagalvin

Handige referentie: Standaard resultaten van KeywordQuery Search

Wanneer u het aanroepen van de Execute() methode op een KeywordQuery, u kunt een ResultTable gebaseerd op ResultType.RelevantResults.  Dit codefragment illustreert wat ik bedoel:

ResultTableCollection resultsTableCollection = myKeywordQuery.Execute();

ResultTable searchResultsTable = resultsTableCollection[ResultType.RelevantResults];

De resulterende tabel zal hebben de volgende kolommen met informatie: 

WorkId
Rang
Titel
Auteur
Grootte
Pad
Beschrijving
Schrijven
SiteName
CollapsingStatus
HitHighlightedSummary
HitHighlightedProperties
ContentClass
IsDocument
PictureThumbnailURL
ServerRedirectedURL

Ik deze lijst afgeleid van een SharePoint 2010 milieu, Enterprise edition.  Hopelijk zal het worden handig om iemand in de toekomst.

</einde>

Abonneren op mijn blog.

Volg mij op Twitter op http://www.twitter.com/pagalvin

Een van de redenen voor: "Failed to extract het cab-bestand in de oplossing”

Tijdens het werken aan een webonderdeel visual studio project vandaag, Ik heb een kleine re-org van sommige bestanden in de map _layouts worden gebracht als onderdeel van het implementatieproces. Specifiek, Mij verdopen een .js bestand van "TypeAhead.js" naar "TypeAhead(oude).js"  Ik ben van plan om het te verwijderen zo snel als zijn opvolger "TypeAhead.js" juiste bewijst.  Het zag er als volgt:

image

Dit veroorzaakt onmiddellijk een probleem met visual studio, toen ik probeerde om het project te implementeren:

Er is een fout opgetreden in implementatie stap "Oplossing toevoegen": Failed to extract het cab-bestand in de oplossing.

Het blijkt dat u niet een haakje in bestandsnamen moeten zetten.  Ik verwijderde de pars en dat het probleem opgelost.

</einde>

Abonneren op mijn blog.

Volg mij op Twitter op http://www.twitter.com/pagalvin