예제 #1
0
        private static void OutputInternalException(HttpApplication application, Exception exception)
        {
            var context = Rest.Configuration.ServiceLocator.GetService<IServiceContext>();

            if (!context.Request.IsLocal)
            {
                return;
            }

            var contextNegotiator = Rest.Configuration.ServiceLocator.GetService<IContentNegotiator>();

            if (contextNegotiator.IsBrowserRequest(context.Request))
            {
                return;
            }

            var unwrappedException = ExceptionUnwrapper.Unwrap(exception);

            var faults = new FaultCollection
            {
                General = new[]
                {
                    new Fault
                    {
                        Message = unwrappedException.Message,
                        Detail = GetExceptionDetail(application, unwrappedException)
                    }
                }
            };

            OutputFaults(application, HttpStatusCode.InternalServerError, Global.InternalServerError, faults);
        }
예제 #2
0
        private static void OutputStatus(HttpApplication application, HttpStatusCode statusCode, string statusDescription)
        {
            var faults = new FaultCollection();
            var numericStatusCode = (int) statusCode;

            if (numericStatusCode >= MinErrorStatusCode && numericStatusCode != UnauthorizedStatusCode)
            {
                faults.General = new[]
                {
                    new Fault
                    {
                        Message = statusDescription
                    }
                };
            }

            OutputFaults(application, statusCode, statusDescription, faults);
        }
예제 #3
0
        private static void GenerateFaultBody(IServiceContext context, IServiceContextHandler handler, FaultCollection faults)
        {
            if (faults.General.Length == 0 && faults.Resource.Length == 0)
            {
                return;
            }

            var resultWrapper = Rest.Configuration.ServiceLocator.GetService<IResultWrapper>();

            IResult result;

            try
            {
                result = resultWrapper.Wrap(handler, faults, faults.GetType());
            }
            catch (HttpResponseException ex)
            {
                context.Response.SetStatus(ex.StatusCode, ex.StatusDescription);
                return;
            }

            if (result != null)
            {
                result.Execute(context);
            }
        }
예제 #4
0
        private static void OutputFaults(HttpApplication application, HttpStatusCode statusCode, string statusDescription, FaultCollection faults)
        {
            if (faults == null)
            {
                throw new ArgumentNullException("faults");
            }

            var context = Rest.Configuration.ServiceLocator.GetService<IServiceContext>();
            var handler = application.Context.CurrentHandler as IServiceContextHandler ?? new ServiceContextHandler(context);

            application.Server.ClearError();
            application.Response.Clear();

            if (application.Request.HttpMethod == Trace && Rest.Configuration.Options.AllowTraceMethod)
            {
                OutputTraceData(context);
                application.CompleteRequest();
                return;
            }

            HandleUnsupportedHttpMethod(application, faults, ref statusCode, ref statusDescription);
            context.Response.SetStatus(statusCode, statusDescription);

            if (statusCode == HttpStatusCode.MethodNotAllowed)
            {
                IEnumerable<HttpMethod> methods = SetAllowHeaderForUnsupportedHttpMethod(application);

                if (methods.Contains(HttpMethod.Patch))
                {
                    SetAcceptPatchHeader(context);
                }

                if (String.Equals(Options, application.Context.Request.HttpMethod, StringComparison.OrdinalIgnoreCase))
                {
                    context.Response.SetStatus(HttpStatusCode.OK, Global.OK);
                    return;
                }
            }

            var contextNegotiator = Rest.Configuration.ServiceLocator.GetService<IContentNegotiator>();

            if (!contextNegotiator.IsBrowserRequest(context.Request))
            {
                context.Response.TrySkipIisCustomErrors = true;

                // Do not try to resolve the response content-type because there is a problem with the Accept header
                if (statusCode != HttpStatusCode.NotAcceptable)
                {
                    GenerateFaultBody(context, handler, faults);
                }
            }

            application.CompleteRequest();
        }
예제 #5
0
        private static void HandleUnsupportedHttpMethod(HttpApplication application, FaultCollection faults, ref HttpStatusCode statusCode, ref string statusDescription)
        {
            if (statusCode != HttpStatusCode.NotFound)
            {
                return;
            }

            object constraintFailedFlag = application.Context.Items[ServiceCallConstants.RouteMethodConstraintFailed];

            if (constraintFailedFlag == null || !Convert.ToBoolean(constraintFailedFlag, CultureInfo.InvariantCulture))
            {
                return;
            }

            Fault statusFault = faults.General.FirstOrDefault(f => f.Message == Global.NotFound);

            if (statusFault != null)
            {
                statusFault.Message = Global.DisallowedHttpMethod;
            }

            statusCode = HttpStatusCode.MethodNotAllowed;
            statusDescription = Global.DisallowedHttpMethod;
        }