public virtual object HandleException(IRequest request, TRequest requestDto, Exception ex)
        {
            var errorResponse = HostContext.RaiseServiceException(request, requestDto, ex)
                                ?? DtoUtils.CreateErrorResponse(requestDto, ex);

            AfterEachRequest(request, requestDto, errorResponse ?? ex);

            return(errorResponse);
        }
Beispiel #2
0
        public virtual async Task <object> HandleExceptionAsync(IRequest request, TRequest requestDto, Exception ex, object service)
        {
            var errorResponse = (service is IServiceErrorFilter filter ? await filter.OnExceptionAsync(requestDto, ex) : null)
                                ?? await HandleExceptionAsync(request, requestDto, ex)
                                ?? await HostContext.RaiseServiceException(request, requestDto, ex)
                                ?? DtoUtils.CreateErrorResponse(requestDto, ex);

            AfterEachRequest(request, requestDto, errorResponse ?? ex, service);

            return(errorResponse);
        }
Beispiel #3
0
        private static async Task RequestFilterAsync(IRequest req, IResponse res, object requestDto,
                                                     bool treatInfoAndWarningsAsErrors)
        {
            var validator = ValidatorCache.GetValidator(req, requestDto.GetType());

            if (validator == null)
            {
                return;
            }

            try
            {
                var validationResult = await Validate(validator, req, requestDto);

                if (treatInfoAndWarningsAsErrors && validationResult.IsValid)
                {
                    return;
                }

                if (!treatInfoAndWarningsAsErrors &&
                    (validationResult.IsValid || validationResult.Errors.All(v => v.Severity != Severity.Error)))
                {
                    return;
                }

                var errorResponse =
                    await HostContext.RaiseServiceException(req, requestDto, validationResult.ToException())
                    ?? DtoUtils.CreateErrorResponse(requestDto, validationResult.ToErrorResult());

                var validationFeature = HostContext.GetPlugin <ValidationFeature>();
                if (validationFeature?.ErrorResponseFilter != null)
                {
                    errorResponse = validationFeature.ErrorResponseFilter(validationResult, errorResponse);
                }

                await res.WriteToResponse(req, errorResponse);
            }
            catch (Exception ex)
            {
                var validationEx = ex.UnwrapIfSingleException();

                var errorResponse = await HostContext.RaiseServiceException(req, requestDto, validationEx)
                                    ?? DtoUtils.CreateErrorResponse(requestDto, validationEx);

                await res.WriteToResponse(req, errorResponse);
            }
            finally
            {
                using (validator as IDisposable)
                {
                }
            }
        }
        public static Task RequestFilterAsync(IRequest req, IResponse res, object requestDto)
        {
            var validator = ValidatorCache.GetValidator(req, requestDto.GetType());
            var ruleSet   = req.Verb;

            if (validator == null || !validator.HasAsyncValidators(ruleSet))
            {
                return(TypeConstants.EmptyTask);
            }

            var validateTask = validator.ValidateAsync(
                new ValidationContext(requestDto, null, new MultiRuleSetValidatorSelector(ruleSet))
            {
                Request = req
            });

            return(HostContext.Async.ContinueWith(req, validateTask, t =>
            {
                if (t.IsFaulted)
                {
                    var validationEx = t.Exception.UnwrapIfSingleException();

                    var errorResponse = HostContext.RaiseServiceException(req, requestDto, validationEx)
                                        ?? DtoUtils.CreateErrorResponse(requestDto, validationEx);

                    return res.WriteToResponse(req, errorResponse);
                }
                else
                {
                    var validationResult = t.Result;
                    if (validationResult.IsValid)
                    {
                        return TypeConstants.TrueTask;
                    }

                    var errorResponse = HostContext.RaiseServiceException(req, requestDto, validationResult.ToException())
                                        ?? DtoUtils.CreateErrorResponse(requestDto, validationResult.ToErrorResult());

                    var validationFeature = HostContext.GetPlugin <ValidationFeature>();
                    if (validationFeature?.ErrorResponseFilter != null)
                    {
                        errorResponse = validationFeature.ErrorResponseFilter(validationResult, errorResponse);
                    }

                    return res.WriteToResponse(req, errorResponse);
                }
            })
                   .ContinueWith(t =>
            {
                using (validator as IDisposable) { }
            }));
        }
        protected async Task <object> ManagedHandleExceptionAsync(IRequest req, TRequest requestDto, Exception ex, object service)
        {
            try
            {
                return(await HandleExceptionAsync(req, requestDto, ex, service).ConfigAwait());
            }
            catch (Exception e)
            {
                Log.Error($"Invalid State: ServiceRunner HandleExceptionAsync() should handle the Exception and return an Error Response, not throw Exceptions", e);
                var errorResponse = (service is IServiceErrorFilter filter ? await filter.OnExceptionAsync(requestDto, ex).ConfigAwait() : null)
                                    ?? await HostContext.RaiseServiceException(req, requestDto, ex).ConfigAwait()
                                    ?? DtoUtils.CreateErrorResponse(requestDto, ex);

                AfterEachRequest(req, requestDto, errorResponse ?? ex, service);
                return(errorResponse);
            }
        }
        public static void RequestFilter(IRequest req, IResponse res, object requestDto)
        {
            var validator = ValidatorCache.GetValidator(req, requestDto.GetType());

            if (validator == null)
            {
                return;
            }

            try
            {
                var validatorWithHttpRequest = validator as IRequiresRequest;
                if (validatorWithHttpRequest != null)
                {
                    validatorWithHttpRequest.Request = req;
                }

                var ruleSet          = req.Verb;
                var validationResult = validator.Validate(
                    new ValidationContext(requestDto, null, new MultiRuleSetValidatorSelector(ruleSet)));

                if (validationResult.IsValid)
                {
                    return;
                }

                var errorResponse = HostContext.RaiseServiceException(req, requestDto, validationResult.ToException())
                                    ?? DtoUtils.CreateErrorResponse(requestDto, validationResult.ToErrorResult());

                var validationFeature = HostContext.GetPlugin <ValidationFeature>();
                if (validationFeature != null && validationFeature.ErrorResponseFilter != null)
                {
                    errorResponse = validationFeature.ErrorResponseFilter(validationResult, errorResponse);
                }

                res.WriteToResponse(req, errorResponse);
            }
            finally
            {
                using (validator as IDisposable) {}
            }
        }
Beispiel #7
0
        protected Message ExecuteMessage(Message message, RequestAttributes requestAttributes, IRequest httpReq, IResponse httpRes)
        {
            var soapFeature = requestAttributes.ToSoapFeature();

            appHost.AssertFeatures(soapFeature);

            if (httpReq == null)
            {
                httpReq = HostContext.GetCurrentRequest();
            }

            if (httpRes == null && httpReq != null)
            {
                httpRes = httpReq.Response;
            }

            if (httpReq == null)
            {
                throw new ArgumentNullException(nameof(httpReq));
            }

            if (httpRes == null)
            {
                throw new ArgumentNullException(nameof(httpRes));
            }

            httpReq.UseBufferedStream = true;
            var requestMsg = message ?? GetRequestMessageFromStream(httpReq.InputStream);

            var soapAction = httpReq.GetHeader(HttpHeaders.SOAPAction)
                             ?? GetAction(requestMsg);

            if (soapAction != null)
            {
                httpReq.OperationName = soapAction.Trim('"');
            }

            if (HostContext.ApplyCustomHandlerRequestFilters(httpReq, httpRes))
            {
                return(PrepareEmptyResponse(message, httpReq));
            }

            string requestXml  = GetRequestXml(requestMsg);
            var    requestType = GetRequestType(requestMsg, requestXml);

            httpReq.OperationName = requestType.GetOperationName();
            if (!HostContext.Metadata.CanAccess(requestAttributes, soapFeature.ToFormat(), requestType.GetOperationName()))
            {
                throw HostContext.UnauthorizedAccess(requestAttributes);
            }

            try
            {
                var useXmlSerializerRequest = requestType.HasAttribute <XmlSerializerFormatAttribute>();

                var request = appHost.ApplyRequestConvertersAsync(httpReq,
                                                                  useXmlSerializerRequest
                        ? XmlSerializableSerializer.Instance.DeserializeFromString(requestXml, requestType)
                        : Serialization.DataContractSerializer.Instance.DeserializeFromString(requestXml, requestType)
                                                                  ).Result;

                httpReq.Dto = request;

                if (request is IRequiresSoapMessage requiresSoapMessage)
                {
                    requiresSoapMessage.Message = requestMsg;
                }

                httpReq.SetItem(Keywords.SoapMessage, requestMsg);

                httpRes.ContentType = GetSoapContentType(httpReq.ContentType);

                var hasRequestFilters = HostContext.AppHost.GlobalRequestFiltersArray.Length > 0 ||
                                        HostContext.AppHost.GlobalRequestFiltersAsyncArray.Length > 0 ||
                                        FilterAttributeCache.GetRequestFilterAttributes(request.GetType()).Any();

                if (hasRequestFilters)
                {
                    HostContext.ApplyRequestFiltersAsync(httpReq, httpRes, request).Wait();
                    if (httpRes.IsClosed)
                    {
                        return(EmptyResponse(requestMsg, requestType));
                    }
                }

                httpReq.RequestAttributes |= requestAttributes;
                var response = ExecuteService(request, httpReq);

                if (response is Task taskResponse)
                {
                    response = taskResponse.GetResult();
                }

                response = appHost.ApplyResponseConvertersAsync(httpReq, response).Result;

                appHost.ApplyResponseFiltersAsync(httpReq, httpRes, response).Wait();
                if (httpRes.IsClosed)
                {
                    return(EmptyResponse(requestMsg, requestType));
                }

                var httpResult = response as IHttpResult;
                if (httpResult != null)
                {
                    response = httpResult.Response;
                }

                var noMsgAction = requestMsg.Headers.Action == null;
                var responseMsg = CreateResponseMessage(response, requestMsg.Version, requestType, noMsgAction);

                if (httpResult != null)
                {
                    SetErrorStatusIfAny(httpReq.Response, responseMsg, httpResult.Status);
                }

                return(responseMsg);
            }
            catch (Exception ex)
            {
                if (httpReq.Dto != null)
                {
                    HostContext.RaiseServiceException(httpReq, httpReq.Dto, ex).Wait();
                }
                else
                {
                    HostContext.RaiseUncaughtException(httpReq, httpRes, httpReq.OperationName, ex).Wait();
                }

                throw new SerializationException("3) Error trying to deserialize requestType: "
                                                 + requestType
                                                 + ", xml body: " + requestXml, ex);
            }
        }
        private static async Task RequestFilterAsync(IRequest req, IResponse res, object requestDto,
                                                     bool treatInfoAndWarningsAsErrors)
        {
            var validator = ValidatorCache.GetValidator(req, requestDto.GetType());

            if (validator == null)
            {
                return;
            }

            using (validator as IDisposable)
            {
                try
                {
                    var validationResult = await validator.ValidateAsync(req, requestDto);

                    if (treatInfoAndWarningsAsErrors && validationResult.IsValid)
                    {
                        return;
                    }

                    if (!treatInfoAndWarningsAsErrors &&
                        (validationResult.IsValid || validationResult.Errors.All(v => v.Severity != Severity.Error)))
                    {
                        return;
                    }

                    var errorResponse =
                        await HostContext.RaiseServiceException(req, requestDto, validationResult.ToException())
                        ?? DtoUtils.CreateErrorResponse(requestDto, validationResult.ToErrorResult());

                    var autoBatchIndex = req.GetItem(Keywords.AutoBatchIndex)?.ToString();
                    if (autoBatchIndex != null)
                    {
                        var responseStatus = errorResponse.GetResponseStatus();
                        if (responseStatus != null)
                        {
                            if (responseStatus.Meta == null)
                            {
                                responseStatus.Meta = new Dictionary <string, string>();
                            }
                            responseStatus.Meta[Keywords.AutoBatchIndex] = autoBatchIndex;
                        }
                    }

                    var validationFeature = HostContext.GetPlugin <ValidationFeature>();
                    if (validationFeature?.ErrorResponseFilter != null)
                    {
                        errorResponse = validationFeature.ErrorResponseFilter(req, validationResult, errorResponse);
                    }

                    await res.WriteToResponse(req, errorResponse);
                }
                catch (Exception ex)
                {
                    var validationEx = ex.UnwrapIfSingleException();

                    var errorResponse = await HostContext.RaiseServiceException(req, requestDto, validationEx)
                                        ?? DtoUtils.CreateErrorResponse(requestDto, validationEx);

                    await res.WriteToResponse(req, errorResponse);
                }
            }
        }
Beispiel #9
0
        private static async Task RequestFilterAsync(IRequest req, IResponse res, object requestDto,
                                                     bool treatInfoAndWarningsAsErrors)
        {
            var requestType = requestDto.GetType();
            await Validators.AssertTypeValidatorsAsync(req, requestDto, requestType);

            var validator = ValidatorCache.GetValidator(req, requestType);

            if (validator == null)
            {
                return;
            }

            using (validator as IDisposable)
            {
                if (validator is IHasTypeValidators hasTypeValidators && hasTypeValidators.TypeValidators.Count > 0)
                {
                    foreach (var scriptValidator in hasTypeValidators.TypeValidators)
                    {
                        await scriptValidator.ThrowIfNotValidAsync(requestDto, req);
                    }
                }

                try
                {
                    if (req.Verb == HttpMethods.Patch)
                    {
                        // Ignore property rules for AutoCrud Patch operations with default values that aren't reset (which are ignored)
                        if (validator is IServiceStackValidator ssValidator && requestDto is ICrud && requestType.IsOrHasGenericInterfaceTypeOf(typeof(IPatchDb <>)))
                        {
                            var typeProperties         = TypeProperties.Get(requestType);
                            var propsWithDefaultValues = new HashSet <string>();
                            var resetFields            = GetResetFields(req.GetParam(Keywords.reset))?.ToSet(StringComparer.OrdinalIgnoreCase)
                                                         ?? TypeConstants <string> .EmptyHashSet;

                            foreach (var entry in typeProperties.PropertyMap)
                            {
                                if (entry.Value.PublicGetter == null || resetFields.Contains(entry.Key))
                                {
                                    continue;
                                }
                                var defaultValue = entry.Value.PropertyInfo.PropertyType.GetDefaultValue();
                                var propValue    = entry.Value.PublicGetter(requestDto);
                                if (propValue == null || propValue.Equals(defaultValue))
                                {
                                    propsWithDefaultValues.Add(entry.Key);
                                }
                            }
                            if (propsWithDefaultValues.Count > 0)
                            {
                                ssValidator.RemovePropertyRules(rule => propsWithDefaultValues.Contains(rule.PropertyName));
                            }
                        }
                    }

                    var validationResult = await validator.ValidateAsync(req, requestDto);

                    if (treatInfoAndWarningsAsErrors && validationResult.IsValid)
                    {
                        return;
                    }

                    if (!treatInfoAndWarningsAsErrors &&
                        (validationResult.IsValid || validationResult.Errors.All(v => v.Severity != Severity.Error)))
                    {
                        return;
                    }

                    var errorResponse =
                        await HostContext.RaiseServiceException(req, requestDto, validationResult.ToException())
                        ?? DtoUtils.CreateErrorResponse(requestDto, validationResult.ToErrorResult());

                    var autoBatchIndex = req.GetItem(Keywords.AutoBatchIndex)?.ToString();
                    if (autoBatchIndex != null)
                    {
                        var responseStatus = errorResponse.GetResponseStatus();
                        if (responseStatus != null)
                        {
                            if (responseStatus.Meta == null)
                            {
                                responseStatus.Meta = new Dictionary <string, string>();
                            }
                            responseStatus.Meta[Keywords.AutoBatchIndex] = autoBatchIndex;
                        }
                    }

                    var validationFeature = HostContext.GetPlugin <ValidationFeature>();
                    if (validationFeature?.ErrorResponseFilter != null)
                    {
                        errorResponse = validationFeature.ErrorResponseFilter(req, validationResult, errorResponse);
                    }

                    await res.WriteToResponse(req, errorResponse);
                }
                catch (Exception ex)
                {
                    var validationEx = ex.UnwrapIfSingleException();

                    var errorResponse = await HostContext.RaiseServiceException(req, requestDto, validationEx)
                                        ?? DtoUtils.CreateErrorResponse(requestDto, validationEx);

                    await res.WriteToResponse(req, errorResponse);
                }
            }
        }
Beispiel #10
0
        public static async Task RequestFilterAsync(IRequest req, IResponse res, object requestDto)
        {
            var validator = ValidatorCache.GetValidator(req, requestDto.GetType());
            var ruleSet   = req.Verb;

            if (validator == null)
            {
                return;
            }

            try
            {
                ValidationResult validationResult;

                if (validator.HasAsyncValidators(ruleSet))
                {
                    validationResult = await validator.ValidateAsync(
                        new ValidationContext(requestDto, null, new MultiRuleSetValidatorSelector(ruleSet))
                    {
                        Request = req
                    });
                }
                else
                {
                    validationResult = validator.Validate(
                        new ValidationContext(requestDto, null, new MultiRuleSetValidatorSelector(ruleSet))
                    {
                        Request = req
                    });
                }

                if (validationResult.IsValid)
                {
                    return;
                }

                var errorResponse = await HostContext.RaiseServiceException(req, requestDto, validationResult.ToException())
                                    ?? DtoUtils.CreateErrorResponse(requestDto, validationResult.ToErrorResult());

                var validationFeature = HostContext.GetPlugin <ValidationFeature>();
                if (validationFeature?.ErrorResponseFilter != null)
                {
                    errorResponse = validationFeature.ErrorResponseFilter(validationResult, errorResponse);
                }

                await res.WriteToResponse(req, errorResponse);
            }
            catch (Exception ex)
            {
                var validationEx = ex.UnwrapIfSingleException();

                var errorResponse = await HostContext.RaiseServiceException(req, requestDto, validationEx)
                                    ?? DtoUtils.CreateErrorResponse(requestDto, validationEx);

                await res.WriteToResponse(req, errorResponse);
            }
            finally
            {
                using (validator as IDisposable) { }
            }
        }