2

I'm struggling to get the example custom autoquery of the requestlogs working in a servicestack service.

I'm using VS2017 and have used the ServiceStack ASP.NET empty template to create a new solution. I then added some of the code from the example in http://docs.servicestack.net/autoquery-service#view-request-logs-in-autoquery-viewerhttpsgithubcomservicestackadmin , Namely the following classes QueryRequestLogs, CustomAutoQueryDataServices and TodayLogs. My apphost is -

//VS.NET Template Info: https://servicestack.net/vs-templates/EmptyAspNet
public class AppHost : AppHostBase
{
    /// <summary>
    /// Base constructor requires a Name and Assembly where web service implementation is located
    /// </summary>
    public AppHost()
        : base("Autoquery", typeof(MyServices).Assembly) { }

    /// <summary>
    /// Application specific configuration
    /// This method should initialize any IoC resources utilized by your web service classes.
    /// </summary>
    public override void Configure(Container container)
    {

        Plugins.Add(new RequestLogsFeature
        {
            RequestLogger = new CsvRequestLogger(
    files: new FileSystemVirtualPathProvider(this, Config.WebHostPhysicalPath),
    requestLogsPattern: "requestlogs/{year}-{month}/{year}-{month}-{day}.csv",
    errorLogsPattern: "requestlogs/{year}-{month}/{year}-{month}-{day}-errors.csv",
    appendEvery: TimeSpan.FromSeconds(1)
),
            EnableResponseTracking = true
        });

        Plugins.Add(new AutoQueryFeature { MaxLimit = 100 });
        Plugins.Add(new AdminFeature());
    }
}

I made a couple of calls just to be sure there was something in the request logs. Then I go to the autoquery viewer using the link from the metadata page. Whichever of the search options I try from the left hand side I get an "Object reference not set to an instance of an object." System.NullReferenceException which is coming from the line

var q = AutoQuery.CreateQuery(query, Request,
    db: new MemoryDataSource<RequestLogEntry>(logs, query, Request));

in

public class CustomAutoQueryDataServices : Service
{
    public IAutoQueryData AutoQuery { get; set; }

    public object Any(QueryRequestLogs query)
    {
        var date = query.Date.GetValueOrDefault(DateTime.UtcNow);
        var logSuffix = query.ViewErrors ? "-errors" : "";
        var csvLogsFile = VirtualFileSources.GetFile(
            "requestlogs/{0}-{1}/{0}-{1}-{2}{3}.csv".Fmt(
                date.Year.ToString("0000"),
                date.Month.ToString("00"),
                date.Day.ToString("00"),
                logSuffix));

        if (csvLogsFile == null)
            throw HttpError.NotFound("No logs found on " + date.ToShortDateString());

        var logs = csvLogsFile.ReadAllText().FromCsv<List<RequestLogEntry>>();
        try
        {
            var q = AutoQuery.CreateQuery(query, Request,
                db: new MemoryDataSource<RequestLogEntry>(logs, query, Request));
            return AutoQuery.Execute(query, q);
        }
        catch (Exception ex)
        {
            return ex;
        }

    }

The full stack trace is:

at Autoquery.ServiceInterface.CustomAutoQueryDataServices.Any(QueryRequestLogs query) in C:\Repos\test\Autoquery\Autoquery\Autoquery.ServiceInterface\CustomAutoQueryDataServices.cs:line 32
at ServiceStack.Host.ServiceRunner`1.Execute(IRequest request, Object instance, TRequest requestDto)
at ServiceStack.Host.ServiceExec`1.Execute(IRequest request, Object instance, Object requestDto, String requestName)
at ServiceStack.Host.ServiceRequestExec`2.Execute(IRequest requestContext, Object instance, Object request)
at ServiceStack.Host.ServiceController.ManagedServiceExec(ServiceExecFn serviceExec, IService service, IRequest request, Object requestDto)
at ServiceStack.Host.ServiceController.<>c__DisplayClass36_0.<RegisterServiceExecutor>b__0(IRequest req, Object dto)
at ServiceStack.Host.ServiceController.Execute(Object requestDto, IRequest req)
at ServiceStack.HostContext.ExecuteService(Object request, IRequest httpReq)
at ServiceStack.Host.RestHandler.GetResponse(IRequest request, Object requestDto)
at ServiceStack.Host.RestHandler.<>c__DisplayClass13_1.<ProcessRequestAsync>b__0(Task t)
at ServiceStack.AsyncExtensions.Continue[TOut](Task task, Func`2 next)
at ServiceStack.Host.RestHandler.ProcessRequestAsync(IRequest httpReq, IResponse httpRes, String operationName)
at ServiceStack.Host.Handlers.HttpAsyncTaskHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData)
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
at System.Web.HttpApplication.PipelineStepManager.ResumeSteps(Exception error)
at System.Web.HttpApplication.BeginProcessRequestNotification(HttpContext context, AsyncCallback cb)
at System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest wr, HttpContext context)
at System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(IntPtr rootedObjectsPointer, IntPtr nativeRequestContext, IntPtr moduleData, Int32 flags)
at System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(IntPtr rootedObjectsPointer, IntPtr nativeRequestContext, IntPtr moduleData, Int32 flags)
at System.Web.Hosting.UnsafeIISMethods.MgdIndicateCompletion(IntPtr pHandler, RequestNotificationStatus& notificationStatus)
at System.Web.Hosting.UnsafeIISMethods.MgdIndicateCompletion(IntPtr pHandler, RequestNotificationStatus& notificationStatus)
at System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(IntPtr rootedObjectsPointer, IntPtr nativeRequestContext, IntPtr moduleData, Int32 flags)
at System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(IntPtr rootedObjectsPointer, IntPtr nativeRequestContext, IntPtr moduleData, Int32 flags)

When I debug, each of logs, query and Request parameters are not null.

I'm assuming I've missed something simple somewhere but I have no idea what, nor can I see how to debug this further.

mythz
  • 141,670
  • 29
  • 246
  • 390
Steve
  • 127
  • 1
  • 8
  • Please post the full StackTrace. – mythz Jun 26 '17 at 13:17
  • The stack trace is - at ServiceStack.AutoQueryDataExtensions.CreateQuery[From](IAutoQueryData autoQuery, IQueryData`1 model, IRequest request, IQueryDataSource db) at Autoquery.ServiceInterface.CustomAutoQueryDataServices.Any(QueryRequestLogs query) in C:\Repos\test\Autoquery\Autoquery\Autoquery.ServiceInterface\CustomAutoQueryDataServices.cs:line 28 at ServiceStack.Host.ServiceRunner`1.Execute(IRequest request, Object instance, TRequest requestDto) – Steve Jun 26 '17 at 13:50
  • Please don't post Stack Traces or code in comments, just update your question to add any additional info. Can you please update your question with the **full StackTrace**. – mythz Jun 26 '17 at 13:56
  • @mythz, my apologies, I think I have added what you requested now – Steve Jun 26 '17 at 14:09
  • Did you get this StackTrace from `ex.ToString()`? as this doesn't look like the StackTrace of the exception. – mythz Jun 26 '17 at 14:14
  • yes, I did, I'm not sure how else to get it – Steve Jun 26 '17 at 14:20
  • `ex.ToString()` should include the source of the Exception, but for some reason this starts with `Environment.GetStackTrace()` ? – mythz Jun 26 '17 at 14:27
  • My apologies once again! I believe I have done it correctly now – Steve Jun 26 '17 at 14:37
  • If this is the real StackTrace it's saying that the source of the Exception is in your Service and not inside AutoQuery, so I'm not able to repro it here. If you could create a stand-alone project (e.g. on GitHub) I could investigate further as this doesn't provide any info on what the source of the Exception is. – mythz Jun 26 '17 at 14:42
  • @mythz I've put the code at https://github.com/ellwoods/AutoqueryTest – Steve Jun 26 '17 at 15:36

1 Answers1

2

The NullReferenceException is because the AutoQuery dependency is null:

public IAutoQueryData AutoQuery { get; set; }

It's null because you've only imported the AutoQuery RDBMS Feature:

Plugins.Add(new AutoQueryFeature { MaxLimit = 100 });

Instead of the AutoQuery Data Feature:

Plugins.Add(new AutoQueryDataFeature { MaxLimit = 100 });

Which is required when using any of the (non-RDBMS) AutoQuery Data Sources.

mythz
  • 141,670
  • 29
  • 246
  • 390