public ExtractBadRequestResponseExamples(
     IHttpContextAccessor httpContextAccessor,
     ProblemDetailsHelper problemDetailsHelper)
 {
     _httpContextAccessor  = httpContextAccessor;
     _problemDetailsHelper = problemDetailsHelper;
 }
示例#2
0
        public async Task <IActionResult> ProposeAddress(
            [FromBody] AddressProposeRequest addressProposeRequest,
            [FromServices] IActionContextAccessor actionContextAccessor,
            [FromServices] ProblemDetailsHelper problemDetailsHelper,
            [FromServices] ProposeAddressToggle proposeAddressToggle,
            CancellationToken cancellationToken = default)
        {
            if (!proposeAddressToggle.FeatureEnabled)
            {
                return(NotFound());
            }

            var contentFormat = DetermineFormat(actionContextAccessor.ActionContext);

            IRestRequest BackendRequest() => CreateBackendRequestWithJsonBody(
                ProposeAddressRoute,
                addressProposeRequest,
                Method.POST);

            var value = await GetFromBackendWithBadRequestAsync(
                contentFormat.ContentType,
                BackendRequest,
                CreateDefaultHandleBadRequest(),
                problemDetailsHelper,
                cancellationToken : cancellationToken);

            return(new BackendResponseResult(value, BackendResponseResultOptions.ForBackOffice()));
        }
        public async Task <IActionResult> ApproveStreetName(
            [FromRoute] int objectId,
            [FromServices] IActionContextAccessor actionContextAccessor,
            [FromServices] ProblemDetailsHelper problemDetailsHelper,
            [FromServices] ApproveStreetNameToggle approveStreetNameToggle,
            [FromHeader(Name = HeaderNames.IfMatch)] string?ifMatch,
            CancellationToken cancellationToken = default)
        {
            if (!approveStreetNameToggle.FeatureEnabled)
            {
                return(NotFound());
            }

            var contentFormat = DetermineFormat(actionContextAccessor.ActionContext);

            IRestRequest BackendRequest() => CreateBackendPutRequest(objectId, ifMatch);

            var value = await GetFromBackendWithBadRequestAsync(
                contentFormat.ContentType,
                BackendRequest,
                CreateDefaultHandleBadRequest(),
                problemDetailsHelper,
                cancellationToken : cancellationToken);

            return(new BackendResponseResult(value, BackendResponseResultOptions.ForBackOffice()));
        }
示例#4
0
        public async Task <IActionResult> PlanBuildingUnit(
            [FromBody] PlanBuildingUnitRequest planBuildingUnitRequest,
            [FromServices] IActionContextAccessor actionContextAccessor,
            [FromServices] ProblemDetailsHelper problemDetailsHelper,
            [FromServices] PlanBuildingUnitToggle planBuildingUnitToggle,
            CancellationToken cancellationToken = default)
        {
            if (!planBuildingUnitToggle.FeatureEnabled)
            {
                return(NotFound());
            }

            var contentFormat = DetermineFormat(actionContextAccessor.ActionContext);

            IRestRequest BackendRequest() => CreateBackendRequestWithJsonBody(
                "gebouweenheden/acties/plannen",
                planBuildingUnitRequest,
                Method.POST);

            var value = await GetFromBackendWithBadRequestAsync(
                contentFormat.ContentType,
                BackendRequest,
                CreateDefaultHandleBadRequest(),
                problemDetailsHelper,
                cancellationToken : cancellationToken);

            return(new BackendResponseResult(value, BackendResponseResultOptions.ForBackOffice()));
        }
示例#5
0
        protected static async Task <BackendResponse> GetFromBackendWithBadRequestAsync(
            IRestClient restClient,
            Func <IRestRequest> createBackendRequestFunc,
            AcceptType acceptType,
            Action <HttpStatusCode> handleNotOkResponseAction,
            ProblemDetailsHelper problemDetailsHelper,
            ICollection <KeyValuePair <string, string> >?headersToForward = null,
            CancellationToken cancellationToken = default)
        {
            var contentType = acceptType.ToMimeTypeString();

            var backendRequest = createBackendRequestFunc();

            backendRequest.AddHeader(HeaderNames.Accept, contentType);
            if (headersToForward != null && headersToForward.Any())
            {
                backendRequest.AddHeaders(headersToForward);
            }

            var response = await ExecuteRequestAsync(restClient, backendRequest, cancellationToken);

            var downstreamVersion = response
                                    .Headers
                                    .FirstOrDefault(x => x.Name.Equals(AddVersionHeaderMiddleware.HeaderName, StringComparison.InvariantCultureIgnoreCase));

            if (response.StatusCode is HttpStatusCode.BadRequest)
            {
                return(new BackendResponse(
                           GetPublicContentValue(response, problemDetailsHelper),
                           downstreamVersion?.Value.ToString(),
                           DateTimeOffset.UtcNow,
                           response.ContentType,
                           false,
                           response.HeadersToKeyValuePairs(),
                           response.StatusCode));
            }

            if (response.IsSuccessful)
            {
                return(new BackendResponse(
                           response.Content,
                           downstreamVersion?.Value.ToString(),
                           DateTimeOffset.UtcNow,
                           contentType,
                           false,
                           response.HeadersToKeyValuePairs(),
                           response.StatusCode));
            }

            handleNotOkResponseAction(response.StatusCode);

            throw new ApiException("Fout bij de bron.", (int)response.StatusCode, response.ErrorException);
        }
示例#6
0
 protected async Task <BackendResponse> GetFromBackendWithBadRequestAsync(
     AcceptType acceptType,
     Func <IRestRequest> createBackendRequestFunc,
     Action <HttpStatusCode> handleNotOkResponseAction,
     ProblemDetailsHelper problemDetailsHelper,
     CancellationToken cancellationToken)
 => await GetFromBackendWithBadRequestAsync(
     _restClient,
     createBackendRequestFunc,
     acceptType,
     handleNotOkResponseAction,
     problemDetailsHelper,
     cancellationToken);
示例#7
0
        public async Task <IActionResult> GetForEditor(
            [FromServices] ProblemDetailsHelper problemDetailsHelper,
            CancellationToken cancellationToken = default)
        {
            var response = await GetFromBackendWithBadRequestAsync(
                _httpClient,
                CreateBackendDownloadForEditorRequest,
                CreateDefaultHandleBadRequest(),
                problemDetailsHelper,
                cancellationToken
                );

            return(response.ToActionResult());
        }
示例#8
0
        public override ProblemDetails MapException(ApiProblemDetailsException exception,
                                                    ProblemDetailsHelper problemDetailsHelper)
        {
            var registryName = ((NotFoundException)exception).RegistryName;

            return(new ProblemDetails
            {
                ProblemTypeUri = $"urn:be.vlaanderen.basisregisters.api:{registryName}:not-found",
                HttpStatus = StatusCodes.Status404NotFound,
                Title = ProblemDetails.DefaultTitle,
                Detail = exception?.Message,
                ProblemInstanceUri = $"{problemDetailsHelper.GetInstanceBaseUri()}/{ProblemDetails.GetProblemNumber()}"
            });
        }
示例#9
0
        public override ProblemDetails MapException(
            ApiProblemDetailsException exception,
            ProblemDetailsHelper problemDetailsHelper)
        {
            var registryName = ((PreconditionFailedException)exception).RegistryName;

            return(new ProblemDetails
            {
                HttpStatus = StatusCodes.Status412PreconditionFailed,
                Title = ProblemDetails.DefaultTitle,
                Detail = "De If-Match header komt niet overeen met de laatst gekende ETag.",
                ProblemTypeUri = $"urn:be.vlaanderen.basisregisters.api:{registryName}:precondition-failed",
                ProblemInstanceUri = $"{problemDetailsHelper.GetInstanceBaseUri()}/{ProblemDetails.GetProblemNumber()}"
            });
        }
示例#10
0
        public async Task <IActionResult> GetUpload(
            [FromRoute] string identifier,
            [FromServices] ProblemDetailsHelper problemDetailsHelper,
            CancellationToken cancellationToken)
        {
            var response = await GetFromBackendWithBadRequestAsync(
                _httpClient,
                () => CreateBackendGetUploadRequest(identifier),
                CreateDefaultHandleBadRequest(),
                problemDetailsHelper,
                cancellationToken
                );

            return(response.ToActionResult());
        }
 protected async Task <BackendResponse> GetFromBackendWithBadRequestAsync(
     AcceptType acceptType,
     Func <IRestRequest> createBackendRequestFunc,
     Action <HttpStatusCode> handleNotOkResponseAction,
     ProblemDetailsHelper problemDetailsHelper,
     ICollection <KeyValuePair <string, string> >?headersToForward = null,
     CancellationToken cancellationToken = default)
 => await GetFromBackendWithBadRequestAsync(
     _restClient,
     createBackendRequestFunc,
     acceptType,
     handleNotOkResponseAction,
     problemDetailsHelper,
     headersToForward,
     cancellationToken);
示例#12
0
        public async Task <IActionResult> Post(
            IFormFile archive,
            [FromServices] ProblemDetailsHelper problemDetailsHelper,
            CancellationToken cancellationToken)
        {
            var response = await GetFromBackendWithBadRequestAsync(
                _httpClient,
                () => CreateBackendUploadRequest(archive),
                CreateDefaultHandleBadRequest(),
                problemDetailsHelper,
                cancellationToken
                );

            return(response.ToActionResult());
        }
示例#13
0
        public async Task <ActionResult> PostDownloadRequest(
            [FromRoute] string downloadId,
            [FromServices] ProblemDetailsHelper problemDetailsHelper,
            CancellationToken cancellationToken = default)
        {
            var response = await GetFromBackendWithBadRequestAsync(
                _httpClient,
                () => CreateBackendDownloadRequest(downloadId),
                CreateDefaultHandleBadRequest(),
                problemDetailsHelper,
                cancellationToken
                );

            return(response.ToActionResult());
        }
示例#14
0
        public async Task <ActionResult> PostDownloadRequest(
            [FromBody] DownloadExtractRequestBody body,
            [FromServices] ProblemDetailsHelper problemDetailsHelper,
            CancellationToken cancellationToken = default)
        {
            IRestRequest BackendRequest() => CreateBackendDownloadRequestRequest(body);

            var response = await GetFromBackendWithBadRequestAsync(
                AcceptType.Json,
                BackendRequest,
                CreateDefaultHandleBadRequest(),
                problemDetailsHelper,
                cancellationToken);

            return(new BackendResponseResult(response));
        }
        public async Task <IActionResult> GetContent(
            [FromRoute] long?id,
            [FromServices] ProblemDetailsHelper problemDetailsHelper,
            CancellationToken cancellationToken = default)
        {
            IRestRequest BackendRequest() => CreateBackendContentRequest(id);

            var response = await GetFromBackendWithBadRequestAsync(
                AcceptType.Json,
                BackendRequest,
                CreateDefaultHandleBadRequest(),
                problemDetailsHelper,
                cancellationToken : cancellationToken);

            return(new BackendResponseResult(response));
        }
示例#16
0
        public async Task <IActionResult> GetHead(
            [FromQuery] int?maxEntryCount,
            [FromServices] ProblemDetailsHelper problemDetailsHelper,
            CancellationToken cancellationToken = default)
        {
            IRestRequest BackendRequest() => CreateBackendHeadRequest(maxEntryCount);

            var response = await GetFromBackendWithBadRequestAsync(
                AcceptType.Json,
                BackendRequest,
                CreateDefaultHandleBadRequest(),
                problemDetailsHelper,
                cancellationToken : cancellationToken);

            return(new BackendResponseResult(response));
        }
        public async Task <IActionResult> CorrectPositionAddress(
            [FromRoute] int objectId,
            [FromBody] AddressCorrectPositionRequest addressCorrectPositionRequest,
            [FromServices] IActionContextAccessor actionContextAccessor,
            [FromServices] ProblemDetailsHelper problemDetailsHelper,
            [FromServices] CorrectPositionAddressToggle correctPositionAddressToggleToggle,
            [FromHeader(Name = HeaderNames.IfMatch)] string?ifMatch,
            CancellationToken cancellationToken = default)
        {
            if (!correctPositionAddressToggleToggle.FeatureEnabled)
            {
                return(NotFound());
            }

            var contentFormat = DetermineFormat(actionContextAccessor.ActionContext);

            IRestRequest BackendRequest()
            {
                var request = new RestRequest(CorrectPositionRoute, Method.POST)
                              .AddParameter(
                    "application/json; charset=utf-8",
                    JsonConvert.SerializeObject(addressCorrectPositionRequest),
                    ParameterType.RequestBody)
                              .AddParameter(
                    "objectId",
                    objectId,
                    ParameterType.UrlSegment);

                if (ifMatch is not null)
                {
                    request.AddHeader(HeaderNames.IfMatch, ifMatch);
                }

                return(request);
            }

            var value = await GetFromBackendWithBadRequestAsync(
                contentFormat.ContentType,
                BackendRequest,
                CreateDefaultHandleBadRequest(),
                problemDetailsHelper,
                cancellationToken : cancellationToken);

            return(new BackendResponseResult(value, BackendResponseResultOptions.ForBackOffice()));
        }
示例#18
0
        public async Task <ActionResult> GetStatus(
            [FromRoute] string uploadId,
            [FromServices] ProblemDetailsHelper problemDetailsHelper,
            CancellationToken cancellationToken = default)
        {
            var response = await GetFromBackendWithBadRequestAsync(
                AcceptType.Json,
                () => CreateBackendUploadStatusRequest(uploadId),
                CreateDefaultHandleBadRequest(),
                problemDetailsHelper,
                cancellationToken : cancellationToken);

            var options = new BackendResponseResultOptions
            {
                ForwardHeaders = new[] { "Retry-After" }
            };

            return(response.ToActionResult(options));
        }
示例#19
0
        protected static async Task <IBackendResponse> GetFromBackendWithBadRequestAsync(
            HttpClient httpClient,
            Func <HttpRequestMessage> createBackendRequestFunc,
            Action <HttpStatusCode> handleNotOkResponseAction,
            ProblemDetailsHelper problemDetailsHelper,
            CancellationToken cancellationToken)
        {
            var backendRequest = createBackendRequestFunc();
            var response       = await httpClient.SendAsync(backendRequest, HttpCompletionOption.ResponseHeadersRead, cancellationToken);

            if (response.IsSuccessStatusCode && response.StatusCode == HttpStatusCode.OK)
            {
                var contentType        = response.Content.Headers.ContentType?.ToString();
                var contentDisposition = response.Content.Headers.ContentDisposition?.ToString();
                var responseStream     = await response.Content.ReadAsStreamAsync(cancellationToken);

                return(new StreamingBackendResponse(
                           contentType,
                           contentDisposition,
                           responseStream,
                           response.HeadersToKeyValuePairs()));
            }

            if (response.StatusCode == HttpStatusCode.BadRequest)
            {
                var responseContentType = response.Content.Headers.ContentType?.ToString();
                var responseContent     = await response.Content.ReadAsStringAsync(cancellationToken);

                return(new BackendResponse(
                           GetPublicContentValue(response, responseContent, problemDetailsHelper),
                           null,
                           DateTimeOffset.UtcNow,
                           responseContentType,
                           false,
                           response.HeadersToKeyValuePairs(),
                           response.StatusCode));
            }

            handleNotOkResponseAction(response.StatusCode);
            throw new ApiException("Fout bij de bron.", (int)response.StatusCode);
        }
示例#20
0
        private static string GetPublicContentValue(IRestResponse response, ProblemDetailsHelper helper)
        {
            var problemDetails = response.GetProblemDetails();

            if (string.IsNullOrWhiteSpace(problemDetails.ProblemTypeUri))
            {
                return(response.Content);
            }

            string Encode(string value)
            => (response.ContentType.Contains("xml", StringComparison.InvariantCultureIgnoreCase)
                       ? new XElement(XName.Get("dummy"), value).LastNode?.ToString()
                       : value)
            ?? string.Empty;

            return(response
                   .Content
                   .Replace(
                       Encode(problemDetails.ProblemTypeUri),
                       Encode(helper.RewriteExceptionTypeFrom(problemDetails))));
        }
示例#21
0
        public async Task <IActionResult> AddressMatch(
            [FromQuery] string gemeentenaam,
            [FromQuery] string niscode,
            [FromQuery] string postcode,
            [FromQuery] string kadStraatcode,
            [FromQuery] string rrStraatcode,
            [FromQuery] string straatnaam,
            [FromQuery] string huisnummer,
            [FromQuery] string index,
            [FromQuery] string busnummer,
            [FromServices] IActionContextAccessor actionContextAccessor,
            [FromServices] IOptions <AddressOptions> responseOptions,
            [FromServices] ProblemDetailsHelper problemDetailsHelper,
            [FromHeader(Name = HeaderNames.IfNoneMatch)] string ifNoneMatch,
            CancellationToken cancellationToken = default)
        {
            var contentFormat = DetermineFormat(actionContextAccessor.ActionContext);

            IRestRequest BackendRequest() => CreateBackendMatchRequest(
                Taal.NL,
                busnummer,
                huisnummer,
                postcode,
                gemeentenaam,
                niscode,
                straatnaam,
                kadStraatcode,
                rrStraatcode,
                index);

            var response = await GetFromBackendWithBadRequestAsync(
                contentFormat.ContentType,
                BackendRequest,
                CreateDefaultHandleBadRequest(),
                problemDetailsHelper,
                cancellationToken);

            return(BackendListResponseResult.Create(response, Request.Query, string.Empty));
        }
示例#22
0
        public async Task <IActionResult> NotRealizeBuildingUnit(
            [FromRoute] int objectId,
            [FromServices] IActionContextAccessor actionContextAccessor,
            [FromServices] ProblemDetailsHelper problemDetailsHelper,
            [FromServices] RealizeBuildingUnitToggle notRealizeBuildingUnitToggle,
            [FromHeader(Name = HeaderNames.IfMatch)] string?ifMatch,
            CancellationToken cancellationToken = default)
        {
            if (!notRealizeBuildingUnitToggle.FeatureEnabled)
            {
                return(NotFound());
            }

            var contentFormat = DetermineFormat(actionContextAccessor.ActionContext);

            IRestRequest BackendRequest()
            {
                var request = new RestRequest("gebouweenheden/{persistentLocalId}/acties/nietrealiseren", Method.POST);

                request.AddParameter("persistentLocalId", objectId, ParameterType.UrlSegment);

                if (ifMatch is not null)
                {
                    request.AddHeader(HeaderNames.IfMatch, ifMatch);
                }

                return(request);
            }

            var value = await GetFromBackendWithBadRequestAsync(
                contentFormat.ContentType,
                BackendRequest,
                CreateDefaultHandleBadRequest(),
                problemDetailsHelper,
                cancellationToken : cancellationToken);

            return(new BackendResponseResult(value, BackendResponseResultOptions.ForBackOffice()));
        }
        public void OnResultExecuting(ResultExecutingContext context)
        {
            if (!(context.Result is BadRequestObjectResult badRequest))
            {
                return;
            }

            if (badRequest.Value is SerializableError errors)
            {
                // make controller actions that do this:
                //   `return BadRequest(ModelState);`
                // as though they did this instead:
                //   `return BadRequest(new ValidationProblemDetails(ModelState));`

                var problemDetails = ToValidationProblemDetails(errors);
                context.Result = badRequest = new BadRequestObjectResult(problemDetails);
            }

            if (badRequest.Value is ProblemDetails details)
            {
                // keep consistent with asp.net core 2.2 conventions that adds a tracing value
                ProblemDetailsHelper.SetTraceId(details, context.HttpContext);
            }
        }
示例#24
0
 public override ProblemDetails MapException(ApiProblemDetailsException exception, ProblemDetailsHelper problemDetailsHelper)
 => new ProblemDetails
 {
     HttpStatus         = exception.StatusCode,
     Title              = ProblemDetails.DefaultTitle,
     Detail             = "Probleem bij het contacteren van de GRB WFS-service.",
     ProblemTypeUri     = problemDetailsHelper.GetExceptionTypeUriFor <GrbWfsException>(),
     ProblemInstanceUri = $"{problemDetailsHelper.GetInstanceBaseUri()}/{ProblemDetails.GetProblemNumber()}"
 };