12

I love LINQPad! I'm trying to connect to Tridion Core Services using a WCF connector in LINQPad to help with my rapid development & learning of Core.

Currently, LINQPad is reporting a 404 (not found) error for the URI, but this same URI works in my browser.

Anyone else successfully connect?

LINQPad's connection window

LINQPad's connection window

MADCookie
  • 2,596
  • 3
  • 26
  • 46

3 Answers3

13

LINQPad is by now my tool of choice for interacting with Tridion through its Core Service API.

If you just download a plain LINQPad, it can connect to WCF data services (typically known as OData sources), SQL Server databases and to the Azure Data Services market. Since Tridion's Core Service is none of those types, you can not create a persistent connection to it.

But you can still use LINQPad as a lightweight alternative to Visual Studio by following these steps:

  1. Switch LINQPad's Language to "C# Program"
  2. Paste in the code snippet below
  3. Add the necessary DLL references from the code snippet
  4. Add the necessary Namespace references from the code snippet
  5. Specify your own values for hostname, username and password
  6. Write your code

LINQPad can handle multiple languages. It defaults to "C# Expression", which means you can just specify a single "statement" in the code panel. That works great when working with e.g. SQL databases for which a driver is available, but is not good enough for interacting with Tridion's Core Service. So first you need to switch it from "C# Expression" language to "C# Program" language in the toolbar at the top of your query.

After switching Language, I typically start with the following boilerplate

void Main()
{
    // System.Runtime.Serialization.dll
    // System.ServiceModel.dll
    // System.Net.dll
    // Namespaces:
    // System.Net
    // System.ServiceModel
    // Tridion.ContentManager.CoreService.Client
    var binding = new NetTcpBinding { MaxReceivedMessageSize = 2147483647, ReaderQuotas = new XmlDictionaryReaderQuotas { MaxStringContentLength = 2147483647, MaxArrayLength = 2147483647 } };
    var endpoint = new EndpointAddress("net.tcp://<hostname>:2660/CoreService/2011/netTcp");
    var DEFAULT_READ_OPTIONS = new ReadOptions();

    CoreServiceClient client = new CoreServiceClient(binding, endpoint);
    client.ChannelFactory.Credentials.Windows.ClientCredential = new NetworkCredential("<username>", "<password>");
    try {
        // TODO: fill in the blanks
    } finally {
        if (client.State == CommunicationState.Faulted) client.Abort(); else client.Close();
    }    
}

After pasting this code, open the Query Properties window (F4) and add System.Runtime.Serialization.dll, System.ServiceModel.dll and System.Net.dll to the Additional References tab. Make sure you have a copy of Tridion.ContentManager.CoreService.Client.dll on your machine and add a reference to that too. (You can find this in Tridion/bin/client on your server)

Add System.Net, System.ServiceModel and Tridion.ContentManager.CoreService.Client to the Additional Namespace Imports tab.

Change the <hostname>, <username> and <password> values in the code and test if the connection succeeds.

After this, fill in the blanks and start having fun with the Core Service API.

I recommend keeping the Core Service API documentation (in CHM format) open at all times. With that open I found that I could get pretty far even without auto-complete. And if you save the query you just created, you can easily clone it with ctrl-shift-C and have a fresh query with the Language, DLL references and Namespaces already filled in.

Update

A easier way to connect to Tridion from LINQPad is now documented here: https://sdltridionworld.com/articles/sdltridion2011/using_linqpad_with_tridion.aspx

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • Great stuff Frank. I just kicked the tyres by replacing the TODO with Console.WriteLine(client.GetApiVersion()); It works a treat. Now for some more interesting queries! – Dominic Cronin Oct 26 '12 at 07:26
  • 1
    Try this: `client.GetListXml("tcm:0-8-1", new RepositoryItemsFilterData { Recursive=true, ItemTypes = new[] { ItemType.Schema }, SchemaPurposes= new [] { SchemaPurpose.Component } }) .Elements() .Select(elm => new { ID=elm.Attribute("ID").Value, Title=elm.Attribute("Title").Value, Fields=String.Join(", ", client.ReadSchemaFields(elm.Attribute("ID").Value).Fields.Select(field => field.Name)) })` Quickest way I found to figure out the content model of a TCM I connect to. – Frank van Puffelen Oct 26 '12 at 18:05
  • Good one Frank. I needed to add some arguments to ReadSchemaFields to make it work. Sure you posted the right version? ReadSchemaFields(elm.Attribute("ID").Value, true, null) worked for me. – Dominic Cronin Nov 30 '12 at 18:45
  • I am getting "A call to SSPI failed, see inner exception." at System.Net.Security.NegoState.StartSendAuthResetSignal(LazyAsyncResult lazyResult, Byte[] message, Exception exception) at System.Net.Security.NegoState.StartSendBlob(Byte[] message, LazyAsyncResult lazyResult) Any Suggestions – Manoj Singh Jan 06 '13 at 04:50
  • My first suggestion would be that you open a new question. In there please include enough information for someone to try and reproduce this problem. You might also want to do a few searches on the error message, since it sounds fairly unrelated to Tridion's Core Service and more .NET/WCF and related to your infrastructure/security setup. – Frank van Puffelen Jan 06 '13 at 14:47
12

Reading through this: http://markistaylor.com/2010/09/09/linqpad-beyond-linq/ it seems like you might be able to do this by adding a reference to System.ServiceModel.dll and [Tridion_Home]\bin\client\Tridion.ContentManager.CoreService.Client.dll (under Query -> Query Properties) to LINQPad.

Nuno Linhares
  • 10,214
  • 1
  • 22
  • 42
  • And the 404 is likely because LINQPad is searching for /$metadata which doesn't exist in the CoreService – Nuno Linhares Mar 13 '12 at 00:38
  • I agree. Remember that the Core Service is implemented using WCF 3.5, which uses SOAP as the default. "Combining Web-centric communication with SOAP and WS-* standards into one service stack and object model is one of the features that makes WCF in the .NET Framework 3.5 so compelling", http://msdn.microsoft.com/en-us/magazine/cc135976.aspx – robrtc Mar 13 '12 at 14:00
  • 1
    Note: Tridion.ContentManager.CoreService.Client.dll is available for SDL Tridion 2011 SP1. We have to generate the client dll ourselves if on 2011 GA or Hotfix Rollup. – Alvin Reyes Mar 13 '12 at 18:16
  • 3
    From the article, I followed "Using LINQPad to call a WCF Service". It was exactly what I needed. I would make one small change to the article. I would add the switch "out" so the compiled DLL is saved in a more convenient location. SVCUTIL /config: /mergeConfig /out: csc /t:library /out: I did not use the article's code in any way. I used code from Albert Romkes (SDL forums) and created a simple function to encapsulate that code. – MADCookie Mar 14 '12 at 18:20
  • 2
    I created over 2,700 components using 5 different schemas – MADCookie Mar 14 '12 at 18:20
  • http://markistaylor.com/2010/09/09/linqpad-beyond-linq/ - URL is broken now, if possible please correct it. – Manoj Singh Jan 06 '13 at 04:01
  • Sorry, not my URL to fix. If you want to use LINQPad with Tridion, check Frank's answer instead. – Nuno Linhares Jan 06 '13 at 22:41
2

You can check the IIS log for the Content Manager - do you see the 404 from the LINQPaD connection attempt? Does the page actually exist?

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
JRW
  • 1,311
  • 9
  • 9