Sharepoint Sitedefinitions pt. 2 (List Views)

by Jess Lassen 8. January 2010 08:56

I et tidligere indlæg omkring Sitedefinitions kiggede vi på opbygningen af webtemp.xml og onet.xml filerne, der danner grundlag for de nye custom sitedefinitions.
I dette indlæg kigger jeg mere på <modules> elementet i onet.xml filer og helt konkret på hvordan man customizerer list views.

Et eksempel på et list view i en standard Sharepoint sitedefinition ses på ”Document Workspace” skabelonen.

Selvom det ser ud som en webpart, er det faktisk ikke indsat som webparts i skabelonen, men som et view element, der bliver renderet i en ListViewWebpart.

Kigger man i onet.xml filen i modules elementet ser man følgende:


<View List="$Resources:core,shareddocuments_Folder;" BaseViewID="6" WebPartZoneID="Left" />
<View List="$Resources:core,lists_Folder;/$Resources:core,tasks_Folder;" BaseViewID="7" WebPartZoneID="Left" WebPartOrder="2" />

Attributen “BaseViewID” er den der definerer renderingen af view’et (kolonner, sortering osv.). ID’et er en henvisninger til et View der ligger i liste definitionen (schema.xml).


<View BaseViewID="1" Type="HTML" WebPartZoneID="Main" DisplayName="$Resources:core,All_Documents;" DefaultView="TRUE" MobileView="True" MobileDefaultView="True" SetupPath="pages\viewpage.aspx" ImageUrl="/_layouts/images/dlicon.png" Url="Forms/AllItems.aspx"><!-- _locID@DisplayName="camlidDc1" _locComment=" " -->
 <GroupByHeader><HTML><![CDATA[<TBODY id="titl]]></HTML>
   <GetVar Name="GroupByLevelString" /><HTML><![CDATA[" groupString="]]></HTML>
    ...

Hvis man åbner schema.xml filen op til Dokumentbiblioteket, finder man hurtig ud af at ikke gidder at sidder og rode med views i notepad særligt længe. Der findes værktøjer til at gøre dette meget nemmere, f.eks Sharepoint Manager, men dette hjælper ikke på problemet, at views ligger i schema.xml filen og denne må ikke ændres, da den kan blive overskrevet ved opdateringer osv.

Så hvad gør man hvis man gerne vil have en ekstra kolonne, sorteret på en anden måde eller sætte en item limit på viewet? Der er 2 svar på dette spørgsmål. Enten laver du en helt ny listedefintion og laver dine egne views som du kan henvise til i sitedefinitionen eller også efterprocesserer man en standard listedefinition.

Webparten (views renderes som ListViewWebparts) hentes ud og efterprocesseres:


using (SPLimitedWebPartManager manager = web.GetLimitedWebPartManager("Sider/default.aspx", PersonalizationScope.Shared))
{
 foreach (System.Web.UI.WebControls.WebParts.WebPart wp in manager.WebParts)
 {
  if (wp.Title == "Dokumenter" && wp is ListViewWebPart)
  {
   ViewReflector vr = new ViewReflector(wp);
   vr.AddViewFields(new string[] { "DocIcon", "LinkFilenameNoMenu", "Editor", "Modified" });
   vr.AddQuery("<OrderBy><FieldRef Name='Modified' Ascending='FALSE' /></OrderBy>");
   vr.AddRowLimit("10", false);
   vr.Update();
   wp.Title = "Seneste dokumenter";
   manager.SaveChanges(wp);
  }
 }
}

Hvor ViewReflector er følgende klasse (udsnit):


class ViewReflector
{
 private System.Web.UI.WebControls.WebParts.WebPart wp;
 private XmlNode node;
 private SPView spView;

 public ViewReflector(System.Web.UI.WebControls.WebParts.WebPart Webpart)
 {
  wp = Webpart;
  Init();
 }
 
 private void Init()
 {
  System.Reflection.PropertyInfo ViewProp = wp.GetType().GetProperty("View",
  System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);

  spView = ViewProp.GetValue(wp, null) as SPView;

  spView.GetType().InvokeMember("EnsureFullBlownXmlDocument",
  System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.InvokeMethod,
  null, spView, null, System.Globalization.CultureInfo.CurrentCulture);

  System.Reflection.PropertyInfo NodeProp = spView.GetType().GetProperty("Node",
  System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);

  node = NodeProp.GetValue(spView, null) as XmlNode;
 }

 public void AddViewFields(string[] viewFields)
 {
  XmlNode viewNode = node.SelectSingleNode("ViewFields");

  if (viewNode != null)
  {
   viewNode.RemoveAll();
   foreach(string s in viewFields)
   {
    viewNode.AppendChild(GetViewField(viewNode.OwnerDocument, s));
   }
  }
 }
 
 ... (flere metoder)

 public void Update()
 {
  spView.Update();
 }
}

Som man kan se har Microsoft har ikke gjort det nemt for os at customizere views, hvis det ikke gøres gennem GUI eller schema.xml. Men hvor der er vilje, er der vej, - om det så må være den snørklede vej gennem reflection.

ViewReflector.cs (3,12 kb)

Tags: , , ,

Load usercontrol i webpart asynkron

by Jess Lassen 11. December 2009 09:36

Siden sidste blog indlæg i oktober, har vi fået et indblik i hvordan næste version af Sharepoint (2010) kommer til at se ud. Blandt mange forbedringer, er specielt integrationen til Visual Studio blevet forbedret markant. Jeg har tidligere snakket om muligheden for at bruge usercontrols i webparts og det ser ud til, at Microsoft også syntes det er en glimrende ide, i det de har introduceret Visual Web Parts i Sharepoint 2010. Der er ikke noget hokus pokus i Visual Web Parts måde at loade usercontrols på, den loader såmænd bare usercontrollen i webpartens CreateChildControls() metode og skubber dermed ansvaret videre til usercontrollen.


Load usercontrols asynkront.

Herunder vil jeg vise en metode jeg har brugt til at hente usercontrols ind i webparts asynkront. Dette kan forbedre sidens loadtid og give slutbrugeren en bedre oplevelse af løsningen.

Webpartens opgave er stadig at loade usercontrol, men bare asynkront istedet. Dette gøres ved at implementere ICallBackEventHandler.
CreateChildContols() opgave er nu at registrere scripts og rendere en placeholder div til usercontrollen. Dette kan gøres således.


protected override void CreateChildControls()
{
  string strScript = string.Format(@"
  function ServerRequest(arg,ctx) {{ {0}; }}
  function GetResult(result, context) {{ document.getElementById('divResult').innerHTML = result }}
  function GetError(result, context) {{ alert(result); }}"
,
  Page.ClientScript.GetCallbackEventReference(this, "arg", "GetResult", "ctx", "GetError", false));
  Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "CallbackFunctions", strScript, true);
  Page.ClientScript.RegisterStartupScript(this.GetType(), "ExecuteCallback", "ServerRequest('1','');", true);
}

protected override void Render(HtmlTextWriter writer)
{
  writer.Write(@"<div id=""divResult""><br /><img src=""/_layouts/images/CRPERSPC.GIF"" /></div>");
}

string callBackString = string.Empty;
public string GetCallbackResult()
{
  return callBackString;
}

public void RaiseCallbackEvent(string eventArgument)
{
  StringBuilder sb = new StringBuilder();
  UserControl.xxx ctrl = this.Page.LoadControl("/_controltemplates/xxx/xxx.ascx") as UserControl.xxx;
  if (ctrl != null)
  {
    this.Controls.Add(ctrl);
    using (StringWriter tw = new StringWriter(sb))
    {
      using (HtmlTextWriter hw = new HtmlTextWriter(tw))
      {
        ctrl.RenderControl(hw);
      }
    }
  }
  callBackString = sb.ToString();
}

Som resulterer i følgende mens usercontrollen ("Nyheder") loades:

Og resultatet viser når usercontrollen er loadet færdig.

Tags: , ,

Sharepoint Sitedefinitions

by Jess Lassen 9. October 2009 08:02

Sitedefinitions i Sharepoint er, ganske som ordet lyder, en definition af en type site i Sharepoint. Standard site typer i Sharepoint er: Team Site, Document Center, Publishing Site mv. Når man starter nye projekter, kan det ofte være en god ide at udvikle sine egne sitedefinitions som en del af projektet. Det meste af ens funktionalitet ligger alligevel i diverse features og en sitedefinition giver bla. mulighed for at aktiverer disse i forbindelse med oprettelse af sites baseret på sitedefinitionen.

En sitedefinition består af følgende:

Webtemp.xml
Findes i TEMPLATE\LCID\XML. Det er her sharepoint kigger efter hvilket templates der findes. Her findes alle standard templates (teamsite, publishing osv) og det er her at nye templates placeres. Kravet for at sharepoint finder de nye templates er at filen starter med webtemp (f.eks webtempMinTemplate.xml).
Her er et udsnit af en publishing template:


<Template Name="BLANKINTERNET" ID="53">
    <Configuration ID="0" Title="Publishing Site" Hidden="TRUE" ImageUrl="/_layouts/1033/images/IPPT.gif" Description="..." SubWebOnly="TRUE" DisplayCategory="Publishing">
    </Configuration>
    <Configuration ID="1" Title="Press Releases Site" Hidden="TRUE" ImageUrl="/_layouts/1033/images/IPPT.gif" Description="..." SubWebOnly="TRUE" DisplayCategory="Publishing" VisibilityFeatureDependency="F6924D36-2FA8-4f0b-B16D-06B7250180FA">
    </Configuration>
</Template>

Name attribute skal være med store bogstaver og svarer til mappenavnet i TEMPLATE\SiteTemplates folderen. ID attributen på nye templates skal være over 10000.
Læs mere omkring webtemp.xml på http://msdn.microsoft.com/en-us/library/ms447717.aspx

Onet.xml
Der er i denne fil det hårde arbejde sker. Her defineres bla. de konfigurationer som webtemp filen peger på. Det er anbefalet at holde denne fil så simpel som muligt og placere det meste funktionalitet i features. I denne fil kan bla. navigation, list templates, dokument templates og features defineres. De meste funktionalitet i templaten vil ligge i sitefeatures/webfeatures.
Bemærk at udover at definere features i onet.xml kan man oprettet features som aktiveres på baggrund af templates. Dette kaldes feature stapling (hæftning) i Sharepoint.
Læs mere omkring feature stapling på: http://msdn.microsoft.com/en-us/library/bb861862.aspx

Her er et udsnit af en onet.xml fil:


<Configurations>
  ...
  <Configuration ID="0" Name="Default">
    <Lists></Lists>
    <Modules>
      <Module Name="Default" />
    </Modules>
    <SiteFeatures>
      <Feature ID="00BFEA71-1C5E-4A24-B310-BA51C3EB7A57" />
      <Feature ID="FDE5D850-671E-4143-950A-87B473922DC7" />
    </SiteFeatures>
    <WebFeatures>
      <Feature ID="00BFEA71-4EA5-48D4-A4AD-7EA5C011ABE5" />
      <Feature ID="F41CC668-37E5-4743-B4A8-74D1DB3FD8A4" />
    </WebFeatures>
  </Configuration>

Configuration ID, er det nummer som webtemp filen referrere til. I Site/Web-features defineres de features som ønskes aktiveret og i modules elementet defineres filer der skal provisioneres, når der oprettes nye instanser af templaten.
Læs mere omkring onet.xml på: http://msdn.microsoft.com/en-us/library/ms474369.aspx

Med dette på plads er sitedefinitionen klar og der kan nu oprettes nye sites baseret på den nye template.
Det er ofte nemmest at basere sine sitedefinitions på andre sitedefinitions og tilrette disse efter behov. De indbyggede i sitedefintions i Sharepoint er ikke længere væk end 12 Hive og disse er god reference, når man kaster sig ud i at lave sine egne sitedefinitions.

Tags: ,

Sharepoint Saturday Copenhagen

by Jess Lassen 24. August 2009 15:23

Sharepoint Saturday er et gratis arrangement for Sharepoint entusiaster. Konceptet kommer fra USA og er så småt begyndt at brede sig til flere lande. I denne weekend var turen så kommet til lille Danmark.

Lyngby Kulturhus lagde lokaler til og der var indhentet speakers fra hele verdenen. Ud over nogle fede sessions og god mulighed for at mingle med andre Sharepoint entusiaster, var der også gratis morgenmad, frokost og ikke mindst fadøl. Alt dette kan jo ikke gøres gratis, så arrangørerne havde arbejdet hårdt med at skaffe en masse sponsorer til eventet.

De sessioner jeg valgte at se var følgende:

Building WSP packages efficiently (Carsten Keutmann).
Udemærket session, hvor Carsten Keutmann viste sit projekt WSP Builder. Udover en gennemgang af produktet blev der også vist et par hidden features.

Sharepoint tips and tricks. (Tobias Zimmergren)
Svenske Tobias Zimmergren havde fundet vej til danmark for at vise et par Sharepoint tricks. Jeg var meget imponeret over Tobias’s evner som taler. Han fremførte sin præsentation på engelsk, men meget velformuleret, letforståelig og med en god portion humor.

Top 10 Ways to improve Sharepoint Performance (Mike Watson)
Mike Watson havde taget hele vejen fra USA for at fortælle os lidt om sharepoint infrastruktur. Mike snakkede om Topology overvejelser, hardware anbefalinger og frontend og backend tweaks.

How to Securely Search Enterprise Systems with SharePoint (Christopher Even)
Christopher Even fortalte om Sharepoint Search med fokus på sikkerhed. 

Sharepoint Battle (Henrik Nordtorp)
Sjovt koncept, som kunne have været en stor success, med et lidt mere engageret publikum. Konceptet var at fortælle om mærkelige oplevelser med Sharepoint i åbent forum.

Arrangementet sluttede af med Happy Hour (fadøl) og lodtrækning om sponsorgaver. Der blev bla. uddelt poloshirts, bøger, licencer, en netbook og en xbox 360.

Alt i alt et rigtig fedt arrangement, som alle der interesserer sig for sharepoint burde deltage i, hvis de kan rive en lørdag ud af kalenderen. Jeg hørte en lille fugl synge om at der muligvis i starten af næste år kommer en gentagelse af arrangementet med fokus på sharepoint 2010.

Tags:

Scheduling udfordringer i Sharepoint

by Jacob Bentzen 20. August 2009 05:42
Hvis man bruger scheduling (tidsstyret publicering) af sider/items i Sharepoint lister skal man være opmærksom på følgende:
Hvis et item har været udgivet med scheduling og udgivelsesdatoen er overskredet kan item'et fremover kun udgives ved at angive en ny fremtidig udgivelsesdato. Det er med andre ord ikke muligt at udgive item'et øjeblikkeligt og det er heller ikke muligt at benytte den originale udgivelsesdato.

Et eksempel hvor dette giver problemer
Et nyhedssystem hvor udgivelsesdatoen bruges til sortering og dato visning.

Hvis man, efter et item er udgivet, har brug for at rette f.eks. en stavefejl, bliver man nødt til at ændre udgivelsesdatoen til en ny fremtidig dato for at kunne gemme. Item'et vil således se ud som om det lige er udgivet på trods af det kan være flere uger gammelt.
Dette kan være et stort problem i sammenhænge hvor der er vigtigt, hvornår en virksomhed har orienteret om et emne.

I dette tilfælde havde kunden desuden misforstået leverandøren og havde brugt "Scheduling End" til at fjerne items fra oversigterne, med formodning om at item'et stadig kunne ses i arkivet og fremsøges.
Da "Scheduling End" fjerner item'et fra almindelig visning og herefter kun kan ses af redaktører, er dette ikke tilfældet.
Hvis man fjerner "Scheduling End" på de eksisterende items, vil man ændre udgivelsesdatoen og alle de gamle items vil derfor fremstå som nye.

Løsningsforslag
Det ville være bedre at bruge 2 almindelige datofelter, en til angivelse af nyhedens dato (den der sorteres på og angiver om den skal vises i oversigt og arkiv) og en til angivelse af hvornår item'et ikke længere skal vises i oversigten, men kun i arkivet. Ulempen ved dennne løsning er at et item stadig kan fremsøges selvom visningsdatoen ikke er overskredet.
Det kan løses ved enten at gemme item'et som en draft og først udgive det når den må ses (manuelt), eller stadig benytte scheduling start, da der ikke længere sorteres på denne.
For at reaktivere de gamle items, slåes forskudt udgivelse fra på listen.

Tags:

Webpart – hvor blev seperation af logik og markup af ?

by Jess Lassen 30. July 2009 05:37

En af de fedeste ting ved asp.net er usercontrols. Disse byggeklodser gør det nemt at dele sine sider op i mindre logiske bidder og nemt at genbruge logik flere steder i projektet. Usercontrols er endvidere delt op i 2 filer. En præsentations fil og en kode fil. Dette gør det super nemt at arbejde med design mockups og giver mulighed for at opdele arbejdet mellem flere mennesker.

Første gang man laver en webpart (Sharepoint eller bare en standard asp.net webpart) vil man sikkert sidder og klø sig i nakken og undre sig over hvor denne separation blev af. Den anbefalede måde at lave webparts på er at tilføje de kontroller man skal bruge i CreateChildControls metoden og derefter ændre layoutet i Render metoden. Hvis det er en kompleks webpart ender man ofte med en fuldstændig uoverskuelig Render metode. Små designændringer vil tage længere tid at rette, da logik og markup er blandet sammen og webparten skal re-kompileres og deployes igen.

3 måder du kan gøre dette nemmere på.

1. Lav din egen template motor.
Eksponer en egenskab på den webpart hvor du kan taste en template ind. Fastlæg nogle mønstre som parses i Render metoden.


<h1>__[Title]__</h1><table><tr><td>Firstname:</td><td>__[FirstNameTextBox]__</td>


I renderingen laves string replace på disse mønstre (de kan være så komplekse som du selv ønsker det) og derved vil du have en delvis opdeling af logik og markup og du kan nemt lave små design ændringen ved blot at ændre webpartens template egenskab.

2. Udnyt nuværende standarder som XML og XSLT.
Bestem dig for at din logik sender xml til webparten og brug xsl til transformere xml’en til html. Denne metode bruges i en del af Sharepoints egne webparts og hvis man er skrap til xslt er dette en super god løsning der giver ægte deling mellem data og præsentation.


Xml xmlControl = new Xml();
xmlControl.DocumentContent = Database.GetXML();
xmlControl.TransformSource = "/Style Library/XSLTStyleSheet.xslt";
this.Controls.Add(xmlControl);

3. Load en usercontrol ind i webparten.
Den sidste måde at gøre det på vil være den mest naturlige for de fleste. Usercontrols kender man fra almindelig asp.net udvikling, og de gode egenskaber med separation mellem logik og markup er kærkommen. Det eneste der kan være lidt irriterende ved denne løsning er at du selv skal binde egenskaberne mellem webparten og usercontrol'en sammen.


UserControlCode.Search ctrl = this.Page.LoadControl("/_controltemplates/Webtop/Search.ascx") as UserControlCode.Search;
if(ctrl != null)
  this.Controls.Add(ctrl);

Tags: , ,

Skift ikoner i søgeresultatet

by Jess Lassen 21. July 2009 05:42

Pift dine Sharepoint søgeresultater lidt op med ikoner der passer til indholdstypen.

Sådan gør du:

Opret den metadata du vil teste på i xslt’en i Shared Service Provideren.
Husk at lave en ny crawl efter du har oprettet ny managed property.

Tilret kerneresultat webdelen til at vise ikoner på baggrund af indholdstype.
Tilføj den oprettede Managed Property i Valgte kolonner:

Lav en xslt template der skifter ikon på baggrund af indholdstypen.


<xsl:template name="GetContentType">
 <xsl:param name="ContentType"></xsl:param>
 <xsl:param name="OriginalImageUrl"></xsl:param>
    <xsl:choose>
        <xsl:when test="contains($ContentType,'Medarbejder')"><img align='absmiddle' border='0' src='/_layouts/images/user.png' /></xsl:when>
        <xsl:when test="contains($ContentType,'Nyhed')"><img align='absmiddle' border='0' src='/_layouts/images/newspaper.png' /></xsl:when>
        <xsl:otherwise>
            <img align='absmiddle' border='0' src='{$OriginalImageUrl}' />
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

Ret i resultat-templaten så den bruger den nyoprettede template.


<!-- This template is called for each result -->
<xsl:template match="Result">

Udskift det gamle billede-tag med et kald til den nyoprettede template (GetContentType):
<img align="absmiddle" src="{imageurl}" border="0" alt="{imageurl/@imageurldescription}" />


<xsl:call-template name="GetContentType">
 <xsl:with-param name="ContentType" select="mycontenttype"/>
 <xsl:with-param name="OriginalImageUrl" select="imageurl"/>
</xsl:call-template>

Resultatet bliver et overskueligt og lækkert søgeresultat.

Tags: , ,

Sharepoint Webservices

by Jess Lassen 17. July 2009 11:17

Engang imellem opstår behovet for at kommunikere med Sharepoint fra en klient applikation eller en anden webapplikation. Hvordan finder man så lige det dokument, den rettighed eller foretager den søgning man har brug for? Sharepoint gemmer indholdet i en database, så en løsning kunne være at tilgå denne direkte og trække data ud heraf. Dette er dog ikke den anbefalede måde at gøre det på, i stedet skal vi kigge på Sharepoint webservices.

En standard Sharepoint installation inkluderer følgende webservices som kan tilgås via http://<site>/_vti_bin/<webservicenavn>

Man må dog engang imellem erkende at de indbyggede webservices ikke altid opfylder ens behov, og så må man lave sin egen Sharepoint webservice. Det fede ved at lave sin egen Sharepoint webservice er at du har adgang til Sharepoints API - så det er ikke meget anderledes end normalt Sharepoint udvikling.

Der er dog følgende forskelle fra almindelige .NET webservices:

Codebehind koden til .asmx filen skal kompileres separat og placeres i GAC’en og .asmx filen skal henvise til denne.

.disco og .wsdl filer skal genereres manuelt med Service Discovery tool (Disco.exe). Derefter skal de omskrives til .aspx filer, så deres indhold kan genereres runtime. Wsdl filen skal endvidere regenereres hver gang du tilføjer nye webmethods i din service, hvilket kan være lidt irriterende.

Sådan laver du din sharepoint webservice:

Opret asmx filen og kompilér asmx code-behind filen.
Referér asmx filen til code-behind filen:

<%@ WebService Language="C#" Class="Service, MyServiceAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=8f2dca3c0f2d0131" %>

Opret de statiske .disco og .wsdl filer med Service Discovery tool.
Opret .aspx versioner af .disco og .wsdl filer og kopier indholdet ind i nyoprettede filer. ([service]disco.aspx og [service]wsdl.aspx)

Indsæt følgende i toppen af .aspx siderne:

<%@ Page Language="C#" Inherits="System.Web.UI.Page" %>
<%@ Assembly Name="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Import Namespace="Microsoft.SharePoint.Utilities" %>
<%@ Import Namespace="Microsoft.SharePoint" %>
<% Response.ContentType = "text/xml"; %>

Tilret url'erne i disco.aspx og wsdl.aspx filerne så de understøtter sharepoints virtual path provider.
disco.aspx:

<contractRef ref=<% SPHttpUtility.AddQuote(SPHttpUtility.HtmlEncode(SPWeb.OriginalBaseUrl(Request) + "?wsdl"),Response.Output); %>
docRef=<% SPHttpUtility.AddQuote(SPHttpUtility.HtmlEncode(SPWeb.OriginalBaseUrl(Request)),Response.Output); %>
xmlns="http://schemas.xmlsoap.org/disco/scl/" />
<soap address=<% SPHttpUtility.AddQuote(SPHttpUtility.HtmlEncode(SPWeb.OriginalBaseUrl(Request)),Response.Output); %>
xmlns:q1="http://tempuri.org/" binding="q1:HelloWorld" xmlns="http://schemas.xmlsoap.org/disco/soap/" />
<soap address=<% SPHttpUtility.AddQuote(SPHttpUtility.HtmlEncode(SPWeb.OriginalBaseUrl(Request)),Response.Output); %>
xmlns:q2="http://tempuri.org/" binding="q2:ServiceSoap12" xmlns="http://schemas.xmlsoap.org/disco/soap/" />

wsdl.aspx:

<soap:address location=<% SPHttpUtility.AddQuote(SPHttpUtility.HtmlEncode(SPWeb.OriginalBaseUrl(Request)),Response.Output); %> />

Deploy de 3 filer til \Program Files\Common Files\Microsoft Shared\web server extensions\12\ISAPI

Microsoft har skrevet en udmærket Walkthrough Guide til at lave sin egen Sharepoint webservice. Så hvis man har brug for at udvikle sin egen Sharepoint webservice er denne guide et godt startpunkt. http://msdn.microsoft.com/en-us/library/ms464040.aspx

Tags: ,

Powered by BlogEngine.NET 1.5.0.7
Theme by Mads Kristensen

RecentPosts