1

I've read through the developer's guide to Sitecore.Services.Client and I've successfully implemented a solution using REST against the Sitecore Entity Service. All of it works as expected.

We're now in a situation where a client is suggesting that a request to the API doesn't return all the expected data. When I use Postman with either of the appropriate requests (https://example.com/sitecore/api/ssc/{namespace}/{controller}) or (https://example.com/sitecore/api/ssc/{namespace}/{controller}/{id}), I see the expected data in the response.

Within the repository, I now created an info logging event to track when the API is accessed and I've also created info logging events within the implemented FindById() and GetAll() methods so I can determine exactly what was requested.

I'm at a loss for capturing the response. Googling my query has yielded nothing tangible and the aforementioned Sitecore documentation doesn't discuss logging; at least not geared to what I'm trying to accomplish. My idea is that I'll use configuration settings to indicate whether or not to be verbose in the logging so we could turn off/on the ability to capture and log the response. That piece is already built out and I've tested it using the info logging events within FindById() and GetAll(). I just need to figure out capturing that JSON response.

Any ideas?

3
  • Are you using the default Sitecore logging mechanism like Log.Info? Commented Jun 29, 2020 at 7:32
  • Yes. For now, we've decided to drop the logs into the Sitecore log file. In the future, if this deems to be quite helpful or we need to track these events over time, we would look to modify this to drop it into a database.
    – TommyJ
    Commented Jun 29, 2020 at 14:55
  • Can you share an example of the api you’ve implemented/using and also do you have custom code in it? If so, can you please share the code Commented Jun 29, 2020 at 15:32

1 Answer 1

1

With some more digging, I was able to work out a solution using a custom action filter attribute and decorating the FindByID() and GetAll() methods within the Repository. I'm happy that I didn't need to touch the controller and it was only three lines in the repository: the two decorators and a using statement.

Since copious calls to GetAll() will wind up stuffing a lot of data into the Sitecore log, I included a settings configuration so we can turn on/off logging the response content. We can use SlowCheetah transforms to modify the setting per environment if we wanted. You get three settings from which to choose:

off = Nothing gets logged
succinct = Logs the request method and uri, as well as the response status code
verbose = Includes everything in succinct as well as logs the response content

Code below (abbreviated where necessary).

Controller

using Sitecore.Services.Core;
using Sitecore.Services.Infrastructure.Sitecore.Services;
using System.Web.Mvc;
using ExampleCo.NC.Web.Entity;
using ExampleCo.NC.Web.Repository;
using ExampleCo.NC.Web.Security;

namespace ExampleCo.NC.Web.Controllers
{
    [ValidateAntiForgeryToken]
    [ServicesController]
    [BasicAuthenticationAttribute]
    [ExampleCoDataAuthorize(Roles = "extranet\\ExampleCo NC Users")]
    public class NCDataController : EntityService<NCDataItem>
    {
        public NCDataController(IRepository<NCDataItem> repository): base(repository)
        {
        }

        public NCDataController(): this(new NCDataRepository())
        {
        }
    }
}

Repository

namespace ExampleCo.NC.Web.Repository {
    public class NCDataRepository : IRepository<NCDataItem> {
        public NCDataRepository() : this(new SitecoreContext()) { }

        public NCDataRepository(ISitecoreContext context) {
            ...
        }
        
        ...
        
        [LogApiEventsFilter]
        public NCDataItem FindById(string id)
        {
            return FetchNCItem(id);
        }
        
        [LogApiEventsFilter]
        public IQueryable<NCDataItem> GetAll()
        {
            return FetchNCItems().AsQueryable();
        }
        
        ...
    }
}

Action Filter Attribute

using Sitecore.Configuration;
using Sitecore.Diagnostics;
using System;
using System.Net.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;

namespace ExampleCo.NC.Web.Filters {
    public class LogApiEventsFilter : ActionFilterAttribute {
        public override void OnActionExecuting(HttpActionContext actionContext) {
            if (!String.IsNullOrEmpty(Settings.GetSetting("ExampleCo.NC.Web.LogLevel")) && 
                (Settings.GetSetting("ExampleCo.NC.Web.LogLevel").ToLower() == "succinct") || (Settings.GetSetting("ExampleCo.NC.Web.LogLevel").ToLower() == "verbose")) {
                string message = string.Format(System.Globalization.CultureInfo.CurrentCulture,
                    "ExampleCo NC API received a {0} request at {1}", actionContext.Request.Method, actionContext.Request.RequestUri);
                Log.Info(message, this);
            }
        }
        
        public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext) {
            base.OnActionExecuted(actionExecutedContext);
            string message = "";

            if (!String.IsNullOrEmpty(Settings.GetSetting("ExampleCo.NC.Web.LogLevel")) &&
                (Settings.GetSetting("ExampleCo.NC.Web.LogLevel").ToLower() == "succinct") || (Settings.GetSetting("ExampleCo.NC.Web.LogLevel").ToLower() == "verbose")) {
                message = string.Format(System.Globalization.CultureInfo.CurrentCulture,
                    "ExampleCo NC API responded with code {0}", actionExecutedContext.Response.StatusCode);
                Log.Info(message, this);
            }

            if (!String.IsNullOrEmpty(Settings.GetSetting("ExampleCo.NC.Web.LogLevel")) &&
                (Settings.GetSetting("ExampleCo.NC.Web.LogLevel").ToLower() == "verbose") && (null != actionExecutedContext.Response.Content)) {
                message = string.Format(System.Globalization.CultureInfo.CurrentCulture,
                    "ExampleCo NC API responded with content: {0}", actionExecutedContext.Response.Content.ReadAsStringAsync().Result);
                Log.Info(message, this);
            }
        }
    }
}

Config File

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    ...
    <settings>
      <!--  EXAMPLECO NC WEB LOG LEVEL
            Specifies what level of logging occurs for the API service.
            Valid Values: off, succinct, verbose
            Default: succinct      
      -->
      <setting name="ExampleCo.NC.Web.LogLevel" value="succinct" />
    </settings>
  </sitecore>
</configuration>

Your Answer

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

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