// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Concurrent;
using System.Collections.ObjectModel;
using System.Diagnostics.CodeAnalysis;
using System.Net.Http;
using System.Net.Http.Formatting;
using System.Web.Http.Dependencies;
using System.Web.Http.Filters;
using System.Web.Http.ModelBinding;
using System.Web.Http.Services;
namespace System.Web.Http
{
///
/// Configuration of instances.
///
public class HttpConfiguration : IDisposable
{
private readonly HttpRouteCollection _routes;
private readonly ConcurrentDictionary _properties = new ConcurrentDictionary();
private readonly MediaTypeFormatterCollection _formatters = DefaultFormatters();
private readonly Collection _messageHandlers = new Collection();
private readonly HttpFilterCollection _filters = new HttpFilterCollection();
private IDependencyResolver _dependencyResolver = EmptyResolver.Instance;
private bool _disposed;
///
/// Initializes a new instance of the class.
///
[SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope",
Justification = "The route collection is disposed as part of this class.")]
public HttpConfiguration()
: this(new HttpRouteCollection(String.Empty))
{
}
///
/// Initializes a new instance of the class.
///
/// The to associate with this instance.
public HttpConfiguration(HttpRouteCollection routes)
{
if (routes == null)
{
throw Error.ArgumentNull("routes");
}
_routes = routes;
Services = new DefaultServices(this);
}
///
/// Gets the list of filters that apply to all requests served using this HttpConfiguration instance.
///
public HttpFilterCollection Filters
{
get { return _filters; }
}
///
/// Gets an ordered list of instances to be invoked as an
/// travels up the stack and an travels down in
/// stack in return. The handlers are invoked in a bottom-up fashion in the incoming path and top-down in the outgoing
/// path. That is, the last entry is called first for an incoming request message but invoked last for an outgoing
/// response message.
///
///
/// The message handler collection.
///
public Collection MessageHandlers
{
get { return _messageHandlers; }
}
///
/// Gets the associated with this instance.
///
///
/// The .
///
public HttpRouteCollection Routes
{
get { return _routes; }
}
///
/// Gets the properties associated with this instance.
///
public ConcurrentDictionary Properties
{
get { return _properties; }
}
///
/// Gets the root virtual path. The property always returns
/// "/" as the first character of the returned value.
///
public string VirtualPathRoot
{
get { return _routes.VirtualPathRoot; }
}
///
/// Gets or sets the dependency resolver associated with this .
///
public IDependencyResolver DependencyResolver
{
get { return _dependencyResolver; }
set
{
if (value == null)
{
throw Error.PropertyNull();
}
_dependencyResolver = value;
}
}
///
/// Gets the container of default services associated with this .
/// Only supports the list of service types documented on . For general
/// purpose types, please use .
///
public DefaultServices Services { get; internal set; }
///
/// Gets or sets a value indicating whether error details should be included in error messages.
///
public IncludeErrorDetailPolicy IncludeErrorDetailPolicy { get; set; }
///
/// Gets the media type formatters.
///
public MediaTypeFormatterCollection Formatters
{
get { return _formatters; }
}
private static MediaTypeFormatterCollection DefaultFormatters()
{
var formatters = new MediaTypeFormatterCollection();
// Basic FormUrlFormatter does not support binding to a T.
// Use our JQuery formatter instead.
formatters.Add(new JQueryMvcFormUrlEncodedFormatter());
return formatters;
}
internal bool ShouldIncludeErrorDetail(HttpRequestMessage request)
{
switch (IncludeErrorDetailPolicy)
{
case IncludeErrorDetailPolicy.LocalOnly:
Uri requestUri = request.RequestUri;
return requestUri.IsAbsoluteUri && requestUri.IsLoopback;
case IncludeErrorDetailPolicy.Always:
return true;
case IncludeErrorDetailPolicy.Never:
default:
return false;
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
_disposed = true;
if (disposing)
{
_routes.Dispose();
Services.Dispose();
DependencyResolver.Dispose();
}
}
}
}
}