3

我正在尝试记录/保留我的所有请求/响应,并认为我尝试使用全局属性,但是当我实际使用 repo 时,它是空的吗?这可能吗?

还有其他方法可以实现我想要做的事情吗?

谢谢你,斯蒂芬

属性

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
public class LogRequestAttribute : RequestFilterAttribute 
{
    public IRepository Repo { get; set; }

    public LogRequestAttribute(ApplyTo applyTo)
        : base(applyTo)
    {
        this.Priority = -200;
    }

    public LogRequestAttribute()
        : this(ApplyTo.All) {}

    public override void Execute(IHttpRequest req, IHttpResponse res, object requestDto)
    {
        try
        {
            // Convert the req obj into something that can be persisted...

            Repo.LogRequest("Logging the rquest");
        }
        catch (Exception ex)
        {
            System.Diagnostics.Trace.TraceError(ex.ToString());
        }
    }
}

应用主机配置

public override void Configure(Container container)
{
    //Set JSON web services to return idiomatic JSON camelCase properties
    ServiceStack.Text.JsConfig.EmitCamelCaseNames = true;

    //Show StackTrace in Web Service Exceptions
    SetConfig(new EndpointHostConfig { DebugMode = true });


    //Register any dependencies you want injected into your services
    container.Register<ICacheClient>(new MemoryCacheClient());

/*            // Redis
    container.Register<IRedisClientsManager>(c => new PooledRedisClientManager());
    container.Register<IRepository>(c => new Repository(c.Resolve<IRedisClientsManager>()));*/


    container.Register<IRepository>(new Repository());
    container.Register<IBusinessService>(new BusinessService());

    //Configure Custom User Defined REST Paths for your services
    /*ConfigureServiceRoutes();*/

    //Add a request filter to check if the user has a session initialized
    /*this.RequestFilters.Add((httpReq, httpResp, requestDto) =>
    {
        var sessionId = httpReq.GetCookieValue("user-session");
        if (sessionId == null)
        {
            httpResp.ReturnAuthRequired();
        }
    });*/


    RequestFilters.Add((httpReq, httpResp, requestDto) => new LogRequestAttribute().Execute(httpReq, httpResp, requestDto));
}

存储库

public interface IRepository
{
    void LogRequest(string request);
    void LogResponse(string request);
}

public class Repository : IRepository
{
    private static readonly ILog Log = LogManager.GetLogger("API.Repository");

    public Repository()
    {

    }

    public void LogRequest(string request)
    {
        Log.Debug(request);
    }

    public void LogResponse(string request)
    {
        Log.Debug(request);
    }
}

更新

//Add a 'global' request filter
this.RequestFilters.Add((httpReq, httpResp, requestDto) =>
{
    /* Code here */
});


//Add a 'global' response filter
this.ResponseFilters.Add((httpReq, httpResp, responseDto) =>
{
    /* Code here */
});
4

1 回答 1

4

如果您尝试在ServiceStack中记录请求,您应该查看Request Logger插件是否有用。RequestLogsFeature插件允许您使用自己的自定义IRequestLogger,而不是默认使用的InMemoryRollingRequestLogger

过滤器属性

尽管您已经正确定义了请求过滤器属性,但您并没有正确应用它,应该像使用任何其他 C# 属性(即装饰)一样使用它。过滤器属性只能在服务类型、其请求 DTO或服务操作上进行修饰,其中它仅运行到它们所应用的范围

全局请求过滤器

没有Global Request Filter AttributeGlobal Request 过滤器只允许您指定要执行的委托,这就是这里发生的一切:

RequestFilters.Add((httpReq, httpResp, requestDto) => 
  new LogRequestAttribute().Execute(httpReq, httpResp, requestDto));

LogRequestAttribute类型的新实例是内联构造的(如上所示,不是从 IOC 解析的),因此它不是自动连接的。您正在调用的方法是 FilterAttribute 的实例这一事实无关紧要,因为所有 C# 委托正在调用的都是空 LogRequestAttribute 实例上的方法。

如果在内部注册全局过滤器,Configure()您可以container直接访问,例如:

RequestFilters.Add((httpReq, httpResp, requestDto) => 
  container.Resolve<IRepository>().LogRequest("Logging the request"));

在其他任何地方,您都可以使用单例访问 ServiceStack 的 IOC AppHostBase.Resolve<T>():.

于 2013-04-07T01:04:43.263 回答