Jul 24, 2008

Lookup Field with Picker V2.0

Hey SharePoint guys,

I've just published version 2.0 of Lookup Field with Picker.
Features:
  • Single- and Multiselection
  • Searching
  • Search Operators (equals, not equals, contains, begins with, greater...)
  • Choose the fields you want to search for
  • Delivered as SharePoint Solution Package

Download it from iLove SharePoint.

p.s. Perhaps is just the last code I've ever published, tomorrow I'll be "Game Over" - I'll marry ;-) The next two weeks I'm in honey moon...

Bye,
Christian

Released: List without Title Column 1.0

If you build SharePoint Solutions you often don't need the title field. But unfortnuately the context menu is attached to the title field. So you're forced to use it anyway. Tha's over! Just try the List without Title Column. The context menu is attached to the ID of the List Item.

Some screens:

Add the list

image

If you create an item there isn't any field! - Just save...

image

After saving the item only an ID has been created. The context menu is attached to the ID.

image

Now you can add as many columns you need.

Download from iLove SharePoint.

Bye,
Christian

Jul 16, 2008

SharePoint Lookup Field with Picker

I'm proud to present you the "Lookup Field with Picker". I've just released it on I Love SharePoint. Just forget the fuc**** dropdowns!

Features:

  • Single- and multi-lookup
  • Searching
  • SharePoint Solution Package (wsp)
  • Click & Enjoy installation (batch file;-)

Screens:

  • Add the field to List or Content Type

image

  • Create a new item and there will be a picker instead of a dropdown!

image

  • Click on the picker, search for an item and choose

image

  • And there it is

image

More coming soon...

Bye,

Christian

Jul 15, 2008

SharePoint Products and Technologies Protocols

Microsoft has released a detailed description about SharePoint, named SharePoint Products and Technologies Protocols. The naming is a bit confusing - just have a look - it's worth.

But sometimes differs from the reality. Just for example we'll have a look at the SharePoint's User Group Web Service Specification MS-UGS.

In the specification the response message of the "GetGroupCollectionFromUser" method is defined as:

<s:element name="GetGroupCollectionFromUserResponse">
<s:complexType>
<s:sequence>
<s:element name="GetGroupCollectionFromUserResult">
<s:complexType>
<s:sequence>
<s:element name="GetGroupCollectionFromUser">
<s:complexType>
<s:sequence>
<s:element name="Groups" type="tns:Groups" />
</s:sequence>
</s:complexType>
</s:element>
</s:sequence>
</s:complexType>
</s:element>
</s:sequence>
</s:complexType>
</s:element>

In reality the response of the method's wsdl on the server looks like that:

<s:element name="GetGroupCollectionFromUserResponse">

<s:complexType>

<s:sequence>

<s:element minOccurs="0" maxOccurs="1" name="GetGroupCollectionFromUserResult">

<s:complexType mixed="true">

<s:sequence>

<s:any />

</s:sequence>

</s:complexType>

</s:element>

</s:sequence>

</s:complexType>

</s:element>

In the specification there's a strongly typed element "Groups" and on the real server there's an xs:any element instead.

This is a big difference if you would like to generate a proxy with wsdl.exe or just using it in Infopath as you can see in my article Infopath - Switch View Depending on the Current User's Role.

It's pitty, because the specification is nicer than the reality.

Dear Microsoft, what' the cause?

Regards,

Christian

Jul 14, 2008

Kill tempuri in WCF Services

Annoyed by tempuri? Just kill it!

  • Adding a namespace to the service contract removes the tempuri from the wsdl:portType and wsdl:message nodes.
[ServiceContract(Namespace="http://cglessner.de/wcf/")]
public interface IByeByeTempuri
{
   [OperationContract]
   TimeToSayGoodbyeResponse TimeToSayGoodbye (TimeToSayGoodbyeRequest request);
}
  • Done!? Forget about it! Now add a namespace to the Data Contract classes to remove tempuri from the wsdl:types
[DataContract(Namespace="http://cglessner.de/wcf/entities/")]
public class TimeToSayGoodbyeRequest
{

[DataMember]
    public string SayGoodbyeText { get; set; }
}
  • Killed?!? No! Add a namespace to the ServiceBehavior attribute of the service implementation. This removes tempuri from the wsdl:definitions and wsdl:service nodes.

[ServiceBehavior(Namespace="http://cglessner.de/wcf")]
public class ByeByeTempuri : IByeByeTempuri

{

public TimeToSayGoodbyeResponse TimeToSayGoodbye(TimeToSayGoodbyeRequest request) {
return new TimeToSayGoodbyeResponse() { Goodbye = "Bye, bye tempuri!" };

}

}
  • But now...? NO! Last but not least changing the endpoint's binding namespace removes the final tempuri from the wsdl:binding node.

    <endpoint address="" binding="basicHttpBinding" bindingConfiguration="" bindingNamespace="http://cglessner.de/wcf/" contract="KillTempuri.IByeByeTempuri" />


  • Unbelievable, you've killed! Now you can say goodbye...

Infopath - Switch View Depending on the Current User's Role

Did you ever need to switch the view depending on the current user's role in an browser enabled Infopath 2007 form? Good luck!

The process presents a very common business scenario, but unfortunately also a very tricky one. The local Infopath client has a built-in mechanism to do that, but there isn't any for browser enabled forms running on Infopath Form Services.

If you googel for a solution, you'll maybe find an article from the Infopath team. They suggest to use an XML file containing all rules and users and store it within the form template. That would work! But, the downside of this approach is that you have to change the form template every time a user's role changes. This is inapplicable for large scale enterprises!

So my idea was to switch the view on the load event of the form depending on the user's SharePoint group using SPContext. Sounds good, but doesn't work, because you aren't able to switch the view programmatically  on the load event- just great!

Next try: Because I'm a smart ass;-) I've started to try the built-in SharePoint Web Service (usergroup.asmx) to get the user's groups. The "GetGroupCollectionFromUser" method returns an "xsd:any"-node, doesn't work with Infopath - tiresome! Okay, there would be a chance to get around this in trying to modify the automatically generated schemas from the wsdl in the XSN- I don't like that.

Now, I've had enough! I've just written my own SharePoint Web Service. It's a very simple service with only one method, returning the SharePoint groups from the current user. Quiet simple, but effective! The Web Service works exactly as any built-in SharePoint Web Service, expects that it works with Infopath :-) 

You can download the web service (sources and solution package) on my CodePlex project "I Love SharePoint".

  • Execute the deploy script (deploy.bat). Don't get frightened, the script first tries to uninstall the solution. This will fail the first time you're running.
  • Paste the following url in your browser to check that the service is running: http://localhost/_vti_bin/ILoveSharePoint/UserService.asmx
  • You're done, now try it in Infopath:
    • Open an existing form template or create a new one
    • Extras->Data Sources->Add
    • Choose new connection to receive data
    • Enter the url of the service: http://localhost/_vti_bin/ILoveSharePoint/UserService.asmx -> next
    • Select "GetGroupsFromCurrentUser" -> next -> next -> finish
    • After that select Data Sources in the task pane and choose the one you've just created
    • Expand the child nodes of dataFields until you find the UserGroups node
    • Drag the node on your form and choose section with controls
    • Now you're done. Click the preview icon...

The url pattern for the web service is as follows:

http://[host]:[port]/[site]/[subsites]/_vti_bin/ILoveSharePoint/UserService.asmx

The [site] and [subsites] placeholders define the site you want to get the current user groups from.

You can use the service with the Infopath's rules, perhaps to:

  • Switch the view depending on the user's SharePoint group on the load event of the form
  • Show or hide controls depending on the user's group using conditional formatting

Any questions or ideas? Leave a comment...

Have fun,

Christian

Jul 13, 2008

Recycle IIS Application Pool with PowerShell

You can also recycle the Application Pool with PowerShell and WMI:

PS>$appPoolName = "SharePoint - 80"
PS>$appPool = get-wmiobject -namespace "root\MicrosoftIISv2" -class "IIsApplicationPool" Where-Object {$_.Name -eq "W3SVC/APPPOOLS/$appPoolName"}
PS>$appPool.Recycle()

Regards,
Christian

Favorite PowerShell Tools

My favorite PowerShell Tools:
Bye,
Christian

Jul 12, 2008

Recycle IIS Application Pool

Much faster than an iisreset. I use that snippet often in debug or deployment scripts for SharePoint.

"%windir%\system32\iisapp.vbs" /a "SharePoint - 80" /r

"SharePoint - 80" is the application to recycle.

The snippet is just a reminder for myself, but perhaps you can use it....

Cheers,
Christian

Die "1000:100:10:1" Regel

Die "1000:100:10:1" Regel besagt: geht mir im Moment eine Idee im Kopf herum, haben im gleiche Moment 1000 andere die selbe Idee, 100 sind schon dabei sie umzusetzen, 10 haben sie schon umgesetzt und 1er ist schon an der nächsten dran.

Leider eine Weisheit die sich im Blogger Leben nur allzuoft bewahrheitet. Kaum hat man einen Beitrag geschrieben, checkt sein Google-Ranking, schon findet man haufenweise fast gleiche Beiträge, schon frustrierend...

Ciao,

Christian

Jul 7, 2008

Codename SPAC just launched...

SharePoint as an Enterprise Assemby Cache for your .NET Applications and Configurations - Codename SPAC.
Featuring WCF to access the SPAC.
Manage your Assemblies and Configurations centrally with SharePoint.
The SPAC Launcher allows you to use nearly any Application with SPAC without changing your Application.

Visit the SPAC on CodePlex.

COMING SOON...

i love to sharepointain you,

Christian

PowerShell, Webservices & SharePoint

In this posting I'm going to show how you can generate a Webservice-Proxy on the fly in PowerShell. After that we'll use it with a SharePoint WebService. To generate the Webservice-Proxy Source Code we will use the Windows SDK Tool wsdl.exe. Then we'll compile the generated code with the .NET Framework Compiler csc.exe and load it into the PowerShell.

Let's go:

  • Create a Script. Name it "Get-WebServiceProxy.ps1"
  • First define the Path to the Tools as an Environment Variable

$env:WinSDK="$env:ProgramFiles\Microsoft SDKs\Windows\v6.0A\Bin"

$env:Net35="$env:SystemRoot\Microsoft.NET\Framework\v3.5"

  • Build a Function to generate the Proxy

#Generates a Webservice-Proxy for the specified URL

function global:Get-WebServiceProxy([String]$url=$(throw
'Parameter -url is missing!'))

{

#generate a tempfile path

$tempFileName=[System.IO.Path]::GetTempFileName()

#generate the proxy code with wsdl.exe

$null=& $env:WinSdk\wsdl.exe $url /n:Proxy /out:"$tempFileName"

#comile the code

$null=& $env:Net35\csc.exe /t:library /out:"$tempFileName.dll"
"$tempFileName"

#load the assembly

$assembly=[System.Reflection.Assembly]::LoadFrom("$tempFileName.dll")

#find the proxy within the assembly

$proxyType=$assembly.GetTypes() Where-Object { $_.IsSubclassOf([System.Web.Services.Protocols.SoapHttpClientProtocol]) –eq
$true}

#instantiate the proxy

$proxy=New-Object
–TypeName
$proxyType

#return the proxy

return
$proxy;

}

Now we will use it to get all Lists of a SharePoint Site

  • Run the Script: PS> . .\Get-WebServiceProxy.ps1
  • PS>$proxy = Get-WebServiceProxy http://localhost/_vti_bin/Lists.asmx
  • PS>$proxy.UseDefaultCredentials = $true
  • PS>$proxy.Url = http://localhost/JW/_vti_bin/Lists.asmx
  • PS>$Lists = $proxy.GetListCollection()
  • PS>$lists.List format-table -property Name, Title
  • Now you should see something like this:

Name Title

-----------------------------------------------------------------------------------------------------

{3C851AD3-C988-43C5-8BC2-4141B1960AEF} Tasks

{169C2080-59B2-480E-A2F7-FD983D7CB759} Announcements

{FB4769F3-955D-42A5-A91F-D12BA5E5CAC9} Doucments

That's all! Create as many proxies as you want...

Find more SharePoint WebServices on MSDN.

There's a better script from Oisin Grehan for using WebServices with
PowerShell:http://poshcode.org/538

Jul 5, 2008

eWMS 2.0 (Reductio ad absurdum)

Ein ganz normales Entwicklungsprojekt:

  • Vertrieb erzählt dem Kunden von der eierlegenden Wollmilchsau (eWMS).
  • Kunde will diese natürlich haben - zum Preis von einem Ei, versteht sich.
  • Um den Versprechungen gerecht zu werden beginnen die Entwickler nun sich den Kopf zu zerbrechen. Einige Zeit später und stolz doch eine Lösung gefunden zu haben präsentieren sie ihr Konzept und geben nach bestem Wissen und Gewissen ein paar Zahlen ab.
  • Vertrieb sagt: "Zu teuer! Warum brauchen wir so lange?! Die Anderen machen das in der halben Zeit, so haben wir keine Chance! Warum braucht die eierlegende Wollmilchsau eigentlich 4 Beine? Mit 3 kann sie doch auch stehen. Und braucht die unbedingt einen Kopf, da kommen doch keine Milch und Eier raus?"
  • Die Entwickler, von Natur aus ein sehr sensibles Völkchen, fangen an sich für ihr Konzept Zahlen zu schämen. Selbstzweifel kommen auf - "Bin ich wirklich so schlecht?". Sie suchen jetzt die Schuld bei sich und denken ich muss mich einfach noch mehr anstrengen, besser werden, sowie die Anderen die das in der halben Zeit schaffen. Sie sind jetzt verunsichert und geben nach.
  • Vertrieb gibt jetzt das Angebot für die kopflose-3-beinige-eierlegende-Wollmichsau ab, gibt 50% Rabatt, verspricht die Lieferung binnen kürzester Zeit und der Kunde bestellt. Schon völlig gebeutelt von den Strapazen muss man jetzt auch noch mit dem Kunde Essen gehen.
  • Jetzt sind die Entwickler wieder dran. Vertrieb: "Ihr müsst sofort anfangen, wenn nicht verlieren wir den Kunden, einer unserer wichtigsten!" Das wollen die Entwickler natürlich nicht und schieben das Projekt irgendwie ein.
  • Nach diesen Anstrengungen braucht der Vertrieb jetzt natürlich Unterstützung – den Projektleiter. Ab Jetzt werden die Entwickler vom Projektleiter motiviert, ähnlich wie damals auf den römischen Galeeren. Sein Kredo: In Time and in Budget. Da dies von Anfang an gar nicht mehr möglich ist macht er den Entwicklern ein schlechtes Gewissen. Die buchen jetzt aus Angst (noch mehr motiviert zu werden) auf das Projekt möglichst wenig Zeit und buchen mehr auf interne Projekte.
  • Mitten im Projekt fällt dem Kunden dann doch auf, dass man ohne Kopf überhaupt keine Eier und Milch produzieren kann. Wie isst und trinkt die eWMS, was steuert die Produktion und wie kommt die eWMS mit 3 Beinen von der Legebatterie zur Melkmaschine? Es muss doch ein Kopf her. Der wurde allerdings so nicht vorgesehen - Korrektur? Nein, keine Zeit, am Hintern da ist doch noch Platz, einfach da montieren.
  • Irgendwann ist die eWMS dann doch fertig. Der Projektleiter ist glücklich, schließlich sind seine Zahlen im Grünen, der Vertrieb hat seine Provision und die Entwickler keine Haare mehr.
  • Am Ende einer Abrechnungsperiode kommt dann wieder die Ernüchterung: Kein Gewinn, sondern Verlust! Wie kann das nur sein? Klar, zu wenig Auslastung! Wir brauchen mehr Projekte, mehr Vertrieb. Aber woher kriegen wir jetzt Geld? Ganz einfach, wir rechnen mehr ab schließlich hat die eWMS jetzt doch einen Kopf und 4 Beine. Der Kunde ist darüber natürlich überhaupt nicht glücklich, aber zahlt, schließlich ist er mit Wartung und Support jetzt auch irgendwie abhängig geworden.
  • Wie geht es jetzt weiter? Mit eWMS 2.0! Haben sie noch nicht?! Dann wird es aber Zeit!

Im Endeffekt hätte alles auch viel einfacher sein können. Hätte der Vertrieb den Entwicklern vertraut, die Zahlen akzeptiert, hätte der Kunde dem Vertrieb vertraut und die eWMS zum diesem Preis bestellt, hätten die Entwickler Selbstvertrauen gehabt und fair für beide Seiten gebucht, dann hätte es keinen Verlust gegeben, kein Nachverhandeln, kein Druck, alle wären glücklicher und zufriedener gewesen, bei gleichem, wenn nicht sogar besserem Ergebnis und vielleicht sogar mit Spaß!

Wir spielen beim diesem "Reductio ad absurdum" der paranoiden Geschäftswelt nicht mit.

Vertrauen ist der Schlüssel zum Erfolg.

Christian, Entwickler

Jul 2, 2008

SharePoint Designer PowerShell Activity

The first Code I've published on i Love SharePoint is the SharePoint Designer PowerShell Activity. Anything PowerShell can do, anything the Activity can do - that's really a lot!

Quick Start (Installation see ReadMe.txt):

  • The example creates a new Site based on the Workflow's List Item Title.
  • Add the Activity to a SharePoint Designer Workflow



  • Insert the following PowerShell Script:


    $web.Webs.Add($item.ID.ToString(),$item.Title,"Created by PowerShell",1031,"STS#0",$false,$false);

    $web.Dispose();

  • Save
  • Run the Workflow. The Workflow now creates a Site named like the List Item. The URL of the Site will be the ID of the Item.

That's just one trivial example. Any ideas how to use, please tell me...

Quick Reference:

In your PowerShell Script you can use the following Variables:

  • $site = current SPSite
  • $web = current SPWeb
  • $list = the List of the Workflow SPList
  • $item = the SPListItem of the Workflow
  • $variable1 = the Workflow Variable you defined for Variable1 in the SharePoint Designer (=$null if you have not defined)
  • $variable2 = the Workflow Variable you defined for Variable1 in the SharePoint Designer (=$null if you have not defined)

You can set the two Workflow Variables within the Script through returning a Hashtable
(keep care on correct types)= @{"variable1"="my Value1";"variable2"=4711};

Errors could be found in the Event Log.

WARNING: This Activity might cause huge security vulnerabilities!

Any comments would be appreciated.