5

I am storing some details from my tridion pages in the APP_DATA table by passing it on to the DATA_CONTENT column as a stream. While retrieving it via a service call method, the values are not getting displayed on the page although it is present in the DB.

Here's how I retrieve the details:

if ($url.getHashParam("id") != null) // We  want to pull app data only for existing pages
{
    if ($url.getHashParam("id").indexOf("-64") != -1) 
        window.onload = $modelUtils.getAppData($url.getHashParam("id"), Namespace.Methods.handleGetAppData);
}

This getAppDatamethod is defined in another JS file as below:

Type.registerNamespace("Namespace");

Namespace.Utilities = function () {
};
Namespace.Utilities.getAppData = function (pageID, handler) {
        try {
            var onError = null;
            var context = null;
           Namespace.GetAppData(pageID,
            handler,
            onError,
            context,
            false);
        }
        catch (err) {
            $messages.registerWarning('Unable to execute GetAppData WCF service Process.', '', false);
        }

    }

And again GetAppData is a service call method which goes as:

[WebGet(RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
        public string GetAppData(string pageID)
        {
            try   {   
              return GetAppDataFromPage(pageID);
            }
            catch (Exception ex)  {
                throw ex;                
            }
            finally   {
                if (channel != null && channel.State != CommunicationState.Closed)
                {
                    channel.Close();
                }
            }
        }

        public string GetAppDataFromPage(string pageID)
        {
            using (Session adminSession = new Session("NT AUTHORITY\\SYSTEM"))
            {
                Page p = new Page(new TcmUri(pageID), adminSession);
                IEnumerable<Tridion.ContentManager.ApplicationData> appData = p.LoadAllApplicationData();
                uint uIntVersion = (uint)((p.DynamicVersion.Revision > 0) ? 0 : (p.Version));
                VersionedItem majVersion = p.GetVersion(uIntVersion);
                Tridion.ContentManager.ApplicationData applicationData = majVersion.LoadApplicationData("APP_ID_NAME");    
                if (applicationData != null)                                    
                return System.Text.Encoding.Unicode.GetString(applicationData.Data);
      }
            return string.Empty;
        }
1
  • Did you test your web service method? Based on what you're saying there is either a bug in the method or your javascript. Apr 30, 2014 at 11:46

1 Answer 1

4

First you are using the TOM.NET API in your own defined web service, that is not appropriate usage of the TOM.NET API. Basically you should only use the TOM.NET API in Template Building Blocks and in the Event System. A good indicator you are doing something which you are not supposed to is when you need to call new Session().

On the Core Service client you could use:

using Tridion.ContentManager.Data;

ApplicationData appData = client.ReadApplicationData("tcm:1-2-64", "APP_ID_NAME");

Where tcm:1-2-64 is the value of your pageID variable.

If you insist on being naughty and continue to use the TOM.NET API in your service, then you will want to use the LoadApplicationData method directly on the Page. Application Data is stored on a specific version, but automatically pushed to newer versions (unless changed, since it is versioned), so by just getting application data from the current Page object, you will get the latest application data automatically.

using Tridion.ContentManager.ApplicationData;

// naughty code
using (Session adminSession = new Session("NT AUTHORITY\\SYSTEM"))
{
    Page p = new Page(new TcmUri(pageID), adminSession);
    ApplicationData applicationData = p.LoadApplicationData("APP_ID_NAME");
    ...
}

By the way creating a session with NT AUTHORITY\SYSTEM also seems a bit strange, while specifying a username on the constructor, you are impersonating from the current user (which in your case probably is the the NetworkService account NT AUTHORITY\NETWORK SERVICE) to the user specified. And you are impersonating to a system user, you should better use the name of a Tridion Administrator (something like server\Administrator).

So for your code to work the NetworkService account needs to be an administrator (which it by default already is) and then you must have created a Tridion user (probably an admin) with the name NT AUTHORITY\SYSTEM.

While when you would use the Core Service, you could create a Core Service client and impersonate the currently logged in user:

using Tridion.ContentManager.CoreService.Client;

// core service endpoint and binding
string uri = "net.tcp://localhost:2660/CoreService/2013/netTcp";
EndpointAddress endpoint = new EndpointAddress(uri);
NetTcpBinding binding = new NetTcpBinding
{
    MaxReceivedMessageSize = 2147483647,
    ReaderQuotas = new XmlDictionaryReaderQuotas
    {
        MaxStringContentLength = 2147483647,
        MaxArrayLength = 2147483647
    }
};

var client = new SessionAwareCoreServiceClient(binding, endpoint);
client.Impersonate(System.Web.HttpContext.Current.User.Identity.Name);
3
  • Thanks Bart! Your answer was a lot helpful and I am incorporating your suggestions. However, in this current code, I used alerts to debug the JS, but the control doesn't see to hit the getAppData method itself. I used an alert immediately inside the method but it doesn't appear. IS there anything wrong in calling the first getAppData method itself?
    – Keirthana
    Apr 30, 2014 at 12:55
  • @Keirthana it all looks fine to me, but I'm no expert in debugging the UI JavaScript. I usually revert to using alerts and console.log(...); myself. Mind you the good thing about using Core Service code is that you can test that logic separately from any type of application, so you can create a unit test class to make sure it works for example. Then you know what that returns and you only have to sort out your JavaScript code. Apr 30, 2014 at 13:15
  • The issue was in the namespace declaration, a trivial one actually. Your answer helped a lot in improving the code. Thanks!
    – Keirthana
    May 1, 2014 at 12:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.