- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试拦截 ServiceRunner 中的请求和响应以针对它们运行验证。
1.我不确定如何在 (!result.IsValid) 的情况下中止请求,或者这是否是一种正确的方法。
2。特别是对于响应,对象响应在动态运行时之前是未知的,这让我很难为它创建 IValidator,它需要在编译时知道类型。
请看代码中的注释:
public class CustomServiceRunner<T> : ServiceRunner<T> {
public CustomServiceRunner(IAppHost appHost, ActionContext actionContext)
: base(appHost, actionContext) { }
public override void BeforeEachRequest(IRequestContext requestContext, T request) {
var validator = AppHost.TryResolve<IValidator<T>>();
var result = validator.Validate(request);
//----------------------
//if (!result.IsValid)
// How to return result.ToResponseDto() and abort the request?
//----------------------
base.BeforeEachRequest(requestContext, request);
}
public override object AfterEachRequest(IRequestContext requestContext, T request, object response) {
//-----------------------
//Validating against response presents a more challenging issue
//I may have multiple response classes and returned response is
//a type object, response class is to be decided dynamically at
//runtime. I am not sure how to fit this to IValidator<T>
//-----------------------
return base.AfterEachRequest(requestContext, request, response);
}
}
在拦截方法中进行验证将使我的服务类代码更加简洁。我也考虑过请求/响应过滤器,但后来我需要在各处编写过滤器标签。 ServiceRunner 更好,因为它使整个验证过程(或一般的 AOP)对其余服务透明。
最佳答案
我不理解为什么使用 RequestFilter 是不够的。如 https://github.com/ServiceStack/ServiceStack/wiki/Validation 中所述,在 AppHost.Configure() 中执行此操作:
// Enable the validation feature
Plugins.Add(new ValidationFeature());
// This method scans the assembly for validators
container.RegisterValidators(Assemblies);
这将为验证设置一个 RequestFilter,并将注册在指定程序集中定义的所有验证器。如果发现任何验证错误,RequestFilter 将引发异常而不是调用您的服务。
与 ServiceStack 可以为您做的相比,您所做的所有布线在我看来都是多余的(而且很脆弱)。
现在,就是说,如果我遵循请求后验证,我就不会这样做。我猜您是在尝试保证服务不会返回无效结果,而不是保证请求在无效时无法执行。这对我来说似乎是一个极端案例,您不信任您的数据存储库并且您希望完全失败甚至无法看到错误数据(这可能会使消费者难以修复)。
我还没有使用过响应过滤器,所以我不确定它们有什么限制。但是看着 https://github.com/ServiceStack/ServiceStack/wiki/Request-and-response-filters ,它似乎表明你可以做同样的事情......所以听起来你可以写一个不同的响应做响应流然后关闭它。我认为这意味着响应过滤器在服务之后执行,但在序列化到响应流之前执行。所以你应该能够写出不同的响应,服务的响应将被忽略。我在 How to find Service from ServiceStack RequestFilter 发布的代码片段可能有帮助。
如果你有一个错误要从验证中返回,那么就像你在做的那样,你可以抛出一个异常,或者直接写一个错误响应。不过看看ServiceStack提供的代码:下载工程,借用/修改ValidationFilter.cs中的RequestFilter代码。如果有帮助,这是当前的实现:
public void RequestFilter(IHttpRequest req, IHttpResponse res, object requestDto)
{
IValidator validator = ValidatorCache.GetValidator(req, requestDto.GetType());
if (validator == null)
return;
IRequiresHttpRequest requiresHttpRequest = validator as IRequiresHttpRequest;
if (requiresHttpRequest != null)
requiresHttpRequest.HttpRequest = req;
string httpMethod = req.HttpMethod;
ValidationResult result = validator.Validate(new ValidationContext(requestDto, (PropertyChain) null, (IValidatorSelector) new MultiRuleSetValidatorSelector(new string[1]
{
httpMethod
})));
if (result.IsValid)
return;
object errorResponse = DtoUtils.CreateErrorResponse(requestDto, ValidationResultExtensions.ToErrorResult(result));
ServiceStack.WebHost.Endpoints.Extensions.HttpResponseExtensions.WriteToResponse(res, req, errorResponse);
}
响应过滤器应该类似于请求过滤器,但您必须安装自己的过滤器。为此,您需要实现自己的 IPlugin。一种简单的方法是从 https://github.com/ServiceStack/ServiceStack/blob/master/src/ServiceStack.ServiceInterface/Validation/ValidationFeature.cs 复制/粘贴/编辑现有的 ValidationFeature.cs。 . (该类有一些私有(private)元素,这使得它不适合子类化,否则我会建议这样做。)
您需要进行的关键更改是注册您自己的过滤器:
/// <summary>
/// Activate the validation mechanism, so every request DTO with an existing validator
/// will be validated.
/// </summary>
/// <param name="appHost">The app host</param>
public void Register(IAppHost appHost)
{
if (Enabled) return;
Enabled = true;
// use my class instead of ServiceStack.ServiceInterface.Validation.ValidationFilters
var filter = new MyValidationFilters();
appHost.RequestFilters.Add(filter.RequestFilter);
appHost.ResponseFilters.Add(filter.RequestFilter);
}
然后您可以创建自己的 MyValidationFilters 类。如果有意义,您可以在这里从 ServiceStack.ServiceInterface.Validation.ValidationFilters 派生,如果适合您,只需使用它们的 RequestFilter。但是您的 ResponseFilter 可能需要与 RequestFilter 略有不同,因为它是通过 Response DTO 而不是 Request DTO 传递的。请注意 RequestFilter 中的这段代码:
object errorResponse = DtoUtils.CreateErrorResponse(requestDto, ValidationResultExtensions.ToErrorResult(result));
此代码无法正常工作,因为 ServiceStack 将尝试获取 requestDto、构建适当的 Response DTO 并填充它,如您在 DtoUtils 代码中所见:
public static object CreateErrorResponse(object request, ValidationErrorResult validationError)
{
ResponseStatus responseStatus = DtoUtils.ToResponseStatus(validationError);
return DtoUtils.CreateErrorResponse(request, (Exception) new ValidationError(validationError), responseStatus);
}
public static object CreateErrorResponse(object request, Exception ex, ResponseStatus responseStatus)
{
object responseDto = DtoUtils.CreateResponseDto(request, responseStatus);
IHttpError httpError = ex as IHttpError;
if (httpError != null)
{
if (responseDto != null)
httpError.Response = responseDto;
return (object) httpError;
}
else
{
string errorCode = ex.GetType().Name;
string errorMessage = ex.Message;
if (responseStatus != null)
{
errorCode = responseStatus.ErrorCode ?? errorCode;
errorMessage = responseStatus.Message ?? errorMessage;
}
return (object) new HttpError(responseDto, HttpRequestExtensions.ToStatusCode(ex), errorCode, errorMessage);
}
}
相反,您需要绕过 CreateResponseDto 部分(因为您在 ResponseFilter 中已经有了 Response DTO),只需完成其余部分即可。
请注意,通过更改 ServiceStack 可以避免上述所有复制/粘贴操作。您可以自己重构 ServiceStack 代码以避免重复,然后向 github 提交拉取请求。
关于c# - ServiceStack 拦截请求/响应以进行验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15304082/
我创建了派生自的服务 ServiceStack.ServiceInterface.Service 实现一些请求。此服务实例的生命周期是多少 - 例如每次调用是否创建了一个新实例,或者该实例是否被缓存?
是否存在检测代码模型中的更改并自动重新创建数据库的首选方法?我不需要迁移数据,如果有更改,可以完全删除所有表,从模型中重新创建表,并使用代码中的初始数据集填充新表,这样就可以了。 与此相关:使用Ser
我正在尝试为 ServiceStack 服务创建一个自定义属性,我可以使用它来控制服务类中的每个方法。 这是我正在实现的属性类。 [AttributeUsage(AttributeTargets.Me
我在玩 ServiceStack,想知道它是否支持这种情况。我在我的请求类型中使用了泛型,这样许多从公共(public)接口(interface)继承的 DTO 将支持相同的基本方法 [比如... G
ServiceStack 服务中是否有任何机制来返回流/大型二进制数据? WCF 的 MTOM 支持虽然笨拙,但在返回大量数据而没有文本转换开销方面很有效。 最佳答案 我喜欢服务堆栈,这个小代码足以从
我很惊讶地发现没有关于这个主题的文档,有人知道 OrmLite 是否支持开放式并发吗?欢迎提供任何文档或示例引用。 最佳答案 这真的不取决于 OrmLite。这取决于隔离级别和您的数据库设置。 例子:
最近在做servicestack项目。当我尝试在项目中添加 open ServiceStack.ServiceInterface 时,它显示以下错误。 代码的 PFB 图片。 正如错误建议的那样,当我
我将如何使用 servicestack 处理静态文件? 我想添加一个像 Routes.Add(/app) 这样的路由,当客户端为此路径发出 GET 时,我需要返回一个 Silverlight xap
这类似于问题 Set Cache-Control: no-cache on GET requests ,这并没有真正得到回答。 在 API 响应中,缓存控制 header 被设置为私有(private
我刚刚进入 REST 和 ServiceStack,现在我的 GET 正在返回可能是 XML 或 Json 的字符串。 我现在需要处理更改我的域模型的 PUT 或 POST 命令。 对于单个资源,我的
一段时间以来,我们一直在将 ServiceStack 用于基于 REST 的服务,到目前为止,效果非常好。 我们所有的服务都写成: public class MyRestService : RestS
我读过@mythz 的这篇文章 https://stackoverflow.com/a/12413091/1095655 , 但我的声誉不够高,无法发表评论 我有一个问题正在工作。如果您收到带有版本
关于通用类型响应对象的文档,我遇到了 Swagger 的 ServiceStack 实现问题。强类型的响应对象被正确记录和显示,但是一旦通用类型的对象用作响应,文档就会不准确且具有误导性。 请求 DT
我目前正在研究一个解决方案,其中我们有一个自托管的 ServiceStack 层正在运行,但问题是当我从浏览器访问它并且浏览器尝试获取 favicon 时,我不断收到错误消息。据我所知,在运行自托管时
我正在查看 ServiceStack 中单元测试的源代码 TestHostBase.cs - 并让它与我自己的项目一起运行。在单元测试时如何在不实际启动监听器的情况下启用我的插件?例如,我想测试我的
ServiceStack 服务非常适合响应 Accept header 中请求的内容类型。但是如果我需要在请求过滤器中尽早关闭/结束响应,有没有办法用正确的内容类型进行响应?我在请求过滤器中所能访问的
我有一个 FileSystemBlobProvider 需要将物理路径映射到虚拟路径,反之亦然。我还需要访问主机名(我需要在给定应用程序相对路径的情况下生成公共(public) url)。理想情况下,
我阅读了新维基 Modularizing Services在 ServiceStack 页面上。我没有发现如何在插件中注册多个服务。当然我可以用appHost.Register(typeof(MySe
我想在重定向中保持状态并且想在重定向中保持一些状态。我认为 MVC 中的 TempData 会在 Rails 中执行此操作并闪烁消息。 ServiceStack 中的任何等效功能。我想在自己组装之前先
从 asp.net 网站调用 servicestack API 的最佳方法是什么。服务正在 IIS 中运行。服务堆栈中的所有方法都需要先进行身份验证。 我尝试使用 JsonServiceClient
我是一名优秀的程序员,十分优秀!