archivi categoria: Sviluppo di SharePoint

HTTP 406 Errore quando si utilizza $http.get angolare contro SharePoint resto punti finali

Aggiornamento: Marc AD ndersson ha sottolineato questo grande pezzo di informazioni: http://Blogs.Office.com/2014/08/13/JSON-Light-support-Rest-SharePoint-API-Released/. Questo spiega tante :).

Che può essere il peggior titolo di un post del blog mai! Anyhoo.

In genere faccio tutti i miei prototipi contro un'istanza di O365. Ho la mia istanza personale in modo che non devo preoccuparmi che colpisce chiunque altro. Come una digressione – ricorda quando chiamiamo trasportati intorno macchine virtuali sui nostri computer portatili con MOSS – SQL Server, IIS, decidendo vs Hyper-V. VMWare? Anyhoo...

Avevo sviluppato un app utilizzando angolare in questo ambiente che fa, tra le altre cose, Questo:

$http.Get(serverUrl)
.successo(funzione(dati, status, intestazioni, config) {

var getLinksResponse = dati;

getLinksResponse.value.forEach(funzione(theResult) {

// e così via e così schiuma

Questo stava lavorando bene in due diversi ambienti di SharePoint online. Tuttavia, Quando il mio collega portato a un'istanza di Cloudshare, Egli fu sempre un HTTP 406 errore (che era la prima volta che ho mai avuto che uno, quindi... evviva, Suppongo). Abbiamo fatto un po' di ricerche e ho notato che l'intestazione "Accept" era spento. SharePoint online era perfettamente felice con:

Accettare: applicazione/json

Ma l'istanza cloudshare (che è SP su prem, ospitato in un server virtuale) ha voluto il classico "odata = verbose" aggiunto pure:

Accettare: applicazione/json;OData = verbose

Alle difficoltà che, Abbiamo aggiunto l'intestazione come tale:

var config = {intestazioni: {
'Accettare': ' applicazione/json;OData = verbose'
}
};

$http.Get(serverUrl,config)
.successo(funzione(dati, status, intestazioni, config) {

var getLinksResponse = dati;

getLinksResponse.value.forEach(funzione(theResult) {

// e così via e così schiuma

Che si è sbarazzato della 406, ma ha anche cambiato il formato della risposta. Era più... dettagliato. (ma ha anche cambiato il formato della risposta.  Era più... prolisso.!) Ulteriori cambiamenti sono stati richiesti ed ecco il risultato finale:

var config = {intestazioni: {
'Accettare': ' applicazione/json;OData = verbose'
}
};

$http.Get(serverUrl,config)
.successo(funzione(dati, status, intestazioni, config) {

var getLinksResponse = dati;

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

// e così via e così schiuma

Questo solo trasformato in una 30 problema minuto per noi, così siamo stati fortunati. Speriamo che qualcuno trova questo utile.

</fine>

Crescente consapevolezza / Adozione di framework JavaScript

Il mio collega, Javed Ansari (http://www.bigapplesharepoint.com/team?showExpertName=Javed%20Ansari&rsource=pgblog), ha scritto un breve post riepilogativo sui quadri egli ama o almeno ha utilizzato con con SharePoint: http://www.bigapplesharepoint.com/pages/View-An-Insight.aspx?BlogID=53&rsource=PGBlog).

jQuery sembra di essere stato il vincitore sul campo, per intenderci, da anni ormai, ma gli altri sono più nuovi e alambicchi sorta di lotta, come angolare. (SPServices, Naturalmente, da anni è un risparmiatore di vita e continuerà ad essere così penso).

Che cosa sono persone che usano? Essi sono concentrati più su utensili di Microsoft (CSOM / JSOM) o si spostano più verso angolare, Knockout, Ember, ecc?

Ho una crescente propensione verso questi quadri non Microsoft. Penso che la roba MSFT è più difficile e più difficile da lavorare con, che richiedono quasi come gran parte della curva di apprendimento come vecchio stile lato server dev.

Posta un commento qui o sopra a Grande mela SharePoint Se volete discutere (Grande mela avrà più probabilità di una buona discussione).

</fine>

Filatura processi Timer di SharePoint dal sito raccolta configurazione

Il mio collega, Ashish Patel, ha scritto un post sul blog descrivere un'architettura di lavoro flessibile timer che offre qualche bel flessibilità per supportare i compiti e/o rapporti di lunga durata.  Nelle sue parole:

1. Analizzando Checked file e inviare promemoria agli individui, se il numero di giorni (Poiché il file è stato Estratto) superare certi limiti di soglia

2. Rimozione di collegamenti da altri contenuti quando un particolare contenuto viene rimosso o archiviato dal sistema

3. Utente vuole vedere tutti gli avvisi che ha sottoscritto in tutti i siti Web nella raccolta siti

4. Invio di un promemoria per gli autori di rivedere il contenuto quando è stato specificato un tempo di revisione nel contenuto e che si avvicina la data

Pozzo, la lista continua...

– Vedere di più in: http://www.bigapplesharepoint.com/ pagine/vista-An-Insight.aspx?BlogID=40#sthash.7cKuiwly.dpuf

Ci sono momenti nel mio passato quando avere qualcosa di simile sarebbe stato molto utile.

</fine>

Come si fa: Configurare Unit Test e Test Coverage con QUnit.js e Blanket.js per un ufficio 365 SharePoint App

Intro

Hai esplorato unit test e test copertura per JavaScript come io lavoro su una nuova applicazione di SharePoint per SharePoint online in ufficio 365 Suite.  I percorsi di ricerca ovvio mi ha portato a Qunit.js e subito dopo che, A Blanket.js.

QUnit mi permetta di creare unit test e raggrupparli in moduli.  Un modulo è solo un semplice modo per organizzare i test correlati. (Non sono sicuro che sto usandolo come previsto, ma si sta lavorando per me finora con il piccolo insieme di test che finora ho definito).

Blanket.js integra con Qunit e mi mostrerà le linee effettive di JavaScript che sono stati – e ancora più importante – non sono stati effettivamente eseguite nel corso di esecuzione dei test.  Questa è la "copertura" – linee che eseguiti sono coperti dal test, mentre altri non sono.

Tra impostazione buone test case e visualizzazione di copertura, possiamo ridurre il rischio che il nostro codice ha nascosto i difetti.  Bei tempi.

Qunit

Assumendo che abbiate il vostro Visual Studio progetto impostato, inizia scaricando il pacchetto JavaScript da http://qunitjs.com.  Aggiungere JavaScript e CSS corrispondente alla soluzione.  Miniera assomiglia a questo:

image

Figura 1

Come si può vedere, Stavo usando 1.13.0 al momento ho scritto questo post del blog. Non dimenticate di scaricare e aggiungere il file CSS..

Che fuori del modo, il passo successivo è creare una sorta di prova imbrago e i bit Qunit di riferimento.  Sto testando un sacco di funzioni in un file di script chiamato "QuizUtil.js", così ho creato una pagina HTML denominata "QuizUtil_test.html" come mostrato:

image Figura 2

Ecco il codice:

<!DOCTYPE html>
<html xmlns= "http://www.w3.org/ 1999/xhtml">
<testa>
    <titolo>QuizUtil prova con Qunit</titolo>
    <link rel= "stylesheet" href="../CSS/qunit-1.13.0.CSS" />
    <script di tipo= text/javascript"" src="QuizUtil.js" dati-copertina></script di>
    <tipo di script ="text/javascript" src ="qunit-1.13.0.js"></script di>
    <tipo di script ="text/javascript" src ="blanket.min.js"></script di>

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

            uguale(getIDFromLookupField(goodValue) + 1, 2), "ID del [" + goodValue + "] + 1 dovrebbero essere 2";
            uguale(getIDFromLookupField(non definito), non definito, "Undefined argomento di input deve restituire un risultato indefinito.");
            uguale(getIDFromLookupField(""), non definito, "Argomento di input vuoto deve restituire un valore indefinito.");
            uguale(getIDFromLookupField("gobbledigood3-thq;dkvn ada;skfja sdjfbvubvqrubqer0873407t534piutheqw;VN"), non definito,"Deve sempre restituire un convertibile del risultato in un valore Integer");
            uguale(getIDFromLookupField(2";#qualche altra persona"), 2"", "Checking [2;#qualche altra persona].");
            uguale(getIDFromLookupField("9834524;#valore Long"), "9834524", "Prova di grande valore.");
            notEqual(getIDFromLookupField("5;#chiunque", 6), 6, "Prova un notEqual (5 non è uguale a 6 per questo esempio: [5;#chiunque]");

        });

        modulo("htmlEscape");
        test("QuizUtil htmlEscape()", funzione () {
            uguale(htmlEscape("<"), "&lt;", "Fuga a meno che l'operatore ('<')");
            uguale(htmlEscape("<classe div =  "someclass">Qualche testo</div>"), "&lt;div class =&quot;SomeClass&quot;&gt;Qualche testo&lt;/div&gt;", "Stringa di test più complesso.");
        });

        modulo("getDateAsCaml");
        test("QuizUtil getDateAsCaml()", funzione () {
            uguale(getDateAsCaml(Nuovo Data("31/12/2013")), "31T-12-2013:00:00:00", "Test data duramente codificato: [12/31/2013]");
            uguale(getDateAsCaml(Nuovo Data("01/05/2014")), "05T-01-2014:00:00:00", "Test data duramente codificato: [01/05/2014]");
            uguale(getDateAsCaml(Nuovo Data("01/31/2014")), "31T-01-2014:00:00:00", "Test data duramente codificato: [01/31/2014]");
            uguale(getTodayAsCaml(), getDateAsCaml(Nuovo Data()), "getTodayAsCaml() dovrebbe essere uguale getDateAsCaml(nuova data())");
            uguale(getDateAsCaml("valore di sciocchezze"), non definito, "Cercare di ottenere la data di un valore di sciocchezze.");
            uguale(getDateAsCaml(non definito), non definito, "Cercare di ottenere la data della [non definito] Data.");
        });

        modulo("getParameterByName");
        test("QuizUtil getParameterByName (dalla stringa di query)", funzione () {
            uguale(getParameterByName(non definito), non definito, "Cercare di ottenere indefinito parametro deve restituire indefinito.");
            uguale(getParameterByName("non esiste"), non definito, "Cercare di ottenere il valore del parametro quando sappiamo che il parametro non esiste.");

        });

        modulo("Cookies");
        test("QuizUtil varie funzioni di biscotto.", funzione () {
            uguale(setCookie("prova", 1"", -1), getCookieValue("prova"), "Get un cookie ho impostato dovrebbe funzionare.");
            uguale(setCookie("anycookie", 1"", -1), true, "L'impostazione di una cucina valida deve restituire 'vero'.");
            uguale(setCookie("nome del cookie pazzo !@#$%"%\^&*(()?/><.,", 1"", -1), true, "L'impostazione di un nome di cookie male deve restituire 'falsa'.");
            uguale(setCookie(non definito, 1"", -1), non definito, "Passing indefinito come il nome del cookie.");
            uguale(getCookieValue("non esiste"), "", "Cookie non esiste prova.");
        });

    </script di>
</testa>
<corpo>
    <div Identificazione= qunit""></div>
    <div Identificazione= "qunit-apparecchio"></div>

</corpo>
</html>

Ci sono parecchie cose che succedono qui:

  1. Il mio codice di riferimento (QuizUtil.js)
  2. Riferimento Qunity.js
  3. Definizione di alcuni moduli (getIDFromLookup, Cookies, e gli altri)
  4. Posizionando un <div> cui ID è "qunit".

Poi, Basta tirare su questa pagina e si ottiene qualcosa di simile:

image

Figura 3

Se guardi nella parte superiore, avete alcune opzioni, di cui due sono interessanti:

  • Nascondi superato test: Abbastanza evidente.  Può aiutare il vostro occhio vedere solo le aree di problema e non un sacco di confusione.
  • Modulo: (cadere giù): Questo consente di filtrare i test fino a solo quei gruppi di test che si desidera.

Per quanto riguarda i test stessi – alcune osservazioni:

  • Va da sé che è necessario scrivere codice, tale che in primo luogo è testabile.  Utilizzando lo strumento può aiutare a far rispettare tale disciplina. Per esempio, Ho avuto una funzione chiamata "getTodayAsCaml()”.  Questo non è verificabile molto poiché non prende nessun argomento di input e per verificare l'uguaglianza, dobbiamo costantemente aggiornare il codice di test per riflettere la data corrente.  Si rifattorizzato aggiungendo un parametro di input dati e passando la data corrente quando voglio la data odierna nel formato CAML.
  • Quadro Qunit documenta le proprie prove e sembra piuttosto robusto.  Possono fare cose semplici come test per l'uguaglianza e ha anche il supporto per le chiamate in stile ajax ("reale" o utilizzando il tuo preferito mocker deriso).
  • Passando attraverso il processo anche ti costringe a pensare attraverso casi limite – cosa succede con "undefined" o in una funzione viene passato null.  Lo rende morto semplice testare questi scenari fuori.  Roba buona.

Copertura con Blanket.js

Blanket.js completa Qunit l'effettive righe di codice che vengono eseguite durante il corso dell'esecuzione di test di rilevamento.  Esso integra diritto in Qunit anche se che è una app completamente separati, gioca bene – sembra davvero che è una app senza soluzione di continuità.

Questo è blanket.js in azione:

image Figura 4

image

Figura 5

(In realtà devi cliccare sulla casella di controllo "Attiva la copertura" nella parte superiore [Vedi figura 3] per consentire questo.)

Le righe evidenziate in figura 5 non sono stati eseguiti da alcuna delle mie prove, quindi ho bisogno di elaborare un test che causano loro di eseguire se voglio piena copertura.

Ottenere blanket.js lavorando seguendo questi passi:

  1. Scaricalo da http://blanketjs.org/.
  2. Aggiungerlo al progetto
  3. Aggiornare la tua pagina di prova imbrago (QuizUtil_test.html nel mio caso) come segue:
    1. Il codice di riferimento
    2. Decorare il vostro <script di> riferimento come questo:
    <script di tipo= text/javascript"" src="QuizUtil.js" dati-copertina></script di>

Blanket.js preleva l'attributo "dati-copertina" e fa la sua magia.  Aggancia Qunit, Aggiorna l'interfaccia utente per aggiungere l'opzione "Abilita la copertura" e voilà!

Riassunto (TL; DR)

Utilizzare Qunit per scrivere i test case.

  • Scaricarlo
  • Aggiungerlo al progetto
  • Scrivere una pagina di prova imbrago
  • Creare i test
    • Rifattorizzare alcuni del codice sia testabile
    • Essere creativi!  Pensare di crazy, scenari impossibili e li prova comunque.

Utilizzare blanket.js per garantire una copertura

  • Assicurarsi che il Qunit sta lavorando
  • Scarica blanket.js e aggiungerlo al progetto
  • Aggiungere alla tua pagina di prova imbrago:
    • Aggiungere un riferimento a blanket.js
    • Aggiungere un attributo "dati-copertura" al vostro <script di> Tag
  • Eseguire i test Qunit.

Non ho mai fatto nulla di tutto questo prima e aveva alcune cose rudimentali in una manciata di ore di lavoro. 

Test felice!

</fine>

undefinedIscriviti al mio blog.

Seguimi su Twitter a http://www.twitter.com/pagalvin

Lists.asmx, GetList e "valore non può essere null”

Ho scoperto oggi che la GetList() Metodo in lists.asmx servizio Web deve essere chiamato con molta attenzione, o è incline a generare un misterioso "Valore non può essere null" eccezione (e che sta assumendo che si può andare oltre il messaggio di errore generico anche peggio, "Eccezione di tipo ' SoapServerException’ è stato gettato.")  In particolare, Ho trovato che è non può fornire qualsiasi tipo di prefisso del metodo GetList.  Il seguente frammento di jQuery illustra il punto:

image

Se lo fai, il servizio web risponde con "Valore non può essere null" come per questo violinista-fornito di trascrizione HTTP:

<?XML version = "1.0" Encoding = "utf-8"?>
  <sapone:Busta
     xmlns:sapone ="
http://schemas.xmlsoap.org/soap/envelope/"    
     xmlns:xsi = "
http://www.w3.org/2001/XMLSchema-instance
     xmlns:XSD ="
http://www.w3.org/2001/XMLSchema">

  <sapone:Corpo>
    <sapone:Colpa>
      <FaultCode>sapone:Server</FaultCode>
      <FaultString>
        Eccezione di tipo ' SoapServerException’ è stato gettato.
      </FaultString>
      <dettaglio>
        <ErrorString xmlns ="
http://schemas.Microsoft.com/SharePoint/SOAP/">
Valore non può essere null.
        </ErrorString>
      </dettaglio>
    </sapone:Colpa>
  </sapone:Corpo>
</sapone:Busta>

Naturalmente, è probabilmente non sarebbe aggiungere tale prefisso "s0" sul proprio, ma alcuni strumenti sono inclini a farlo (come eclissi).

Questo è ancora più confuso / frustrante perché altri metodi tollerano i prefissi.  Per esempio, il GetListCollection Metodo non mente se esso è stato preceduto da, anche con i prefissi di sciocchezze come "xyzzy":

image

Questo "valore non può essere null" sembra piuttosto comune con lists.asmx quindi speriamo questo aiuterà qualcuno fuori in futuro.

</fine>

Iscriviti al mio blog.

Seguimi su Twitter a http://www.twitter.com/pagalvin

Nidificazione all'infinito <div> Tag e jQuery

Questo mi sembra un soggetto così stravaganti, Non sono sicuro che vale davvero la pena bloggare su, ma che non ha mai smesso prima di me, quindi qui si va sorriso, sorridere

Sto lavorando su un progetto dove sto tirando alcuni dati da una ricerca, imballaggio in un messaggio XML e poi il codice XML viene trasformato in definitiva in HTML tramite XSLT.  C'è un sacco di jQuery coinvolte, un bit di che implementa alcune funzionalità di tabulazione.  Quando fa clic su una scheda (davvero, un <div>), jQuery richiama .hide() e .show() su vari DIV (il caricamento della pagina iniziale Download tutto il contenuto, quindi non ci sono in questo caso postback).

Un mucchio di ore fa, la scheda logica di commutazione ha iniziato a comportarsi in modo strano e non mostra una delle mie schede.  Io alla fine esso monitorati al fatto che internet explorer (almeno) pensava che la <div> tag nidificati lontano, molto più profondo da desiderata.Avrebbe mostrato la developer toolbar:

-<div id = "Tab1Content">
  -<div>
    -<div>
      -<div id = "Tab2Content">
        -<div>
           …………………………
                   </div>  <— Infine mostrandolo è stata chiusa fino in fondo!

Così, Se ho fatto un $("# Tab1Content").Nascondi(), Sarebbe anche nascondere Tab2 e mai potuto mostrare Tab2 anche se non ha mostro Tab1.  Ho copiato e incollato il codice in visual studio e ha mostrato a tutti di rivestimento del div fino piacevolmente, proprio come avrebbero dovuto fare, guardando come questo:

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

Ho battuto la testa contro il muro per un po' e ho notato che nel codice HTML effettivo codice era generando un sacco di vuoto <div> Tag, come:

<corpo>

  <div id = "Tab1Content">

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

  </div>

  <div id = "Tab2Content">

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

  </div>

</corpo>

(Quanto sopra è waaaaaaaaaaaay semplificato.  I tag div vuota sono totalmente validi. Alcuni dei miei <div> Tag erano piene di contenuti, ma molti altri non hanno.  Sono venuto alla realizzazione che mio <xsl:for each> le direttive sono state che emettono la forma abbreviata div tag quando xsl:for each non ' trovare tutti i dati.  Sono costretto a un commento HTML nell'output, come illustrato:

image

 

Dopo che ho fatto che, il div in fila piacevolmente ed il mio switching tab iniziò a lavorare.

Come sempre, Spero che questo aiuta a qualcuno in un pizzico.

</fine>

Iscriviti al mio blog.

Seguimi su Twitter a http://www.twitter.com/pagalvin

Una delle Cause per "il creatore di questo difetto non ha specificato un motivo.”

Ho fatto un sacco di lavoro con SharePoint ricerca ultimamente e in particolare la classe KeywordQuery, Proprietà e metodi.

Se si desidera che il set di risultati a restituire risultati oltre i soliti sospetti (vedi qui), aggiungerlo all'insieme SelectedProperties, come in:

myKeywordQuery.SelectProperties.Add("xyzzy");

Molte grazie e una punta di cappello a Corey Roth e Questo post del blog molto utile (http://www.dotnetmafia.com/blogs/dotnettipoftheday/archive/2008/02/19/how-to-use-the-moss-enterprise-search-keywordquery-class.aspx)

Nel mio caso, "xyzzy" non è in realtà una proprietà gestita.  Quando ho aggiunto al SelectedProperties comunque, SharePoint gettò uno dei miei preferiti mai eccezioni runtime:

"Il creatore di questo difetto non ha specificato una ragione."

Piace soprattutto la capitale "R" nel motivo.  Questo suona per me come il.Equivalente netto di"I have no bocca, e devo urlare.”

</fine>

Iscriviti al mio blog.

Seguimi su Twitter a http://www.twitter.com/pagalvin

Utile riferimento: Risultati predefiniti da KeywordQuery di ricerca

Quando si richiama il Execute() Metodo su un KeywordQuery, è possibile creare un ResultTable basato su ResultType.RelevantResults.  Questo frammento di codice viene illustrato cosa intendo:

ResultTableCollection resultsTableCollection = myKeywordQuery.Execute();

ResultTable searchResultsTable = resultsTableCollection[ResultType.RelevantResults];

La tabella risultante avrà le seguenti colonne di informazioni: 

ID lavoro
Rango
Titolo
Autore
Dimensioni
Percorso
Descrizione
Scrivere
Nomesito
CollapsingStatus
HitHighlightedSummary
HitHighlightedProperties
ContentClass
IsDocument
PictureThumbnailURL
ServerRedirectedURL

Questo elenco è derivano una SharePoint 2010 ambiente, Enterprise edition.  Spero che sarà utile a qualcuno in futuro.

</fine>

Iscriviti al mio blog.

Seguimi su Twitter a http://www.twitter.com/pagalvin

Uno dei motivi per: "Non è riuscito a estrarre il file cab nella soluzione”

Mentre si lavora su una parte del web di visual studio progetto oggi, Ho fatto un re-org minori di alcuni file da mettere nella cartella layouts come parte del processo di distribuzione. In particolare, Ho rinominato un file js da "TypeAhead.js" in "TypeAhead(vecchio).js"  Ho intenzione di rimuoverlo come suo successore "TypeAhead.js" si rivela corretto.  Si presentava così:

image

Questo ha causato immediatamente un problema con visual studio quando ho provato a distribuire il progetto:

Si è verificato un errore in fase di distribuzione 'Aggiungi soluzione': Non è riuscito a estrarre il file cab nella soluzione.

Si scopre che non si dovrebbe mettere una parentesi nei nomi di file.  Ho rimosso la parentesi e che ha risolto il problema.

</fine>

Iscriviti al mio blog.

Seguimi su Twitter a http://www.twitter.com/pagalvin