Quantcast
Channel: ASP.NET MVC / Web API / Web Pages
Viewing all 7925 articles
Browse latest View live

Created Issue: Please add support for entity key that are composed [898]

$
0
0
Currently in order to support composite entity key we have to add new routing conventions to ODATA web api server.

Since entity key may be composite according to ODATA spec it shall be a feature ODATA web api supports out-of-the box.

Commented Issue: Please add support for entity key that are composite [897]

$
0
0
Currently in order to support composite entity key we have to add new routing conventions to ODATA web api server.

Since entity key may be composite according to ODATA spec it shall be a feature ODATA web api supports out-of-the box.
Comments: Superseeded by #898. This entry is obsolete.

Created Issue: Razor parser returns incorrect data tree for @section a {something} [899]

$
0
0
output returned by Razor parser for “@section a {something}” is as below. tree returned in incorrect.

- block {Markup Block at (0:0,0)::33 (Gen:None)} System.Web.Razor.Parser.SyntaxTree.Block
+ base {Markup Block at (0:0,0)::33 (Gen:None)} System.Web.Razor.Parser.SyntaxTree.SyntaxTreeNode {System.Web.Razor.Parser.SyntaxTree.Block}
- Children Count = 3 System.Collections.Generic.IEnumerable<System.Web.Razor.Parser.SyntaxTree.SyntaxTreeNode> {System.Collections.Generic.List<System.Web.Razor.Parser.SyntaxTree.SyntaxTreeNode>}
+ [0] {Markup Span at (0:0,0)::0 - [] Edit: <SpanEditHandler;Accepts:Any> Gen: <Markup> {HtmlSymbol:1}} System.Web.Razor.Parser.SyntaxTree.SyntaxTreeNode {System.Web.Razor.Parser.SyntaxTree.Span}
+ [1] {Section Block at (0:0,0)::21 (Gen:Section:a)} System.Web.Razor.Parser.SyntaxTree.SyntaxTreeNode {System.Web.Razor.Parser.SyntaxTree.Block}
+ [2] {Markup Span at (12:0,12)::12 - [something}
] Edit: <SpanEditHandler;Accepts:Any> Gen: <Markup> {HtmlSymbol:2}} System.Web.Razor.Parser.SyntaxTree.SyntaxTreeNode {System.Web.Razor.Parser.SyntaxTree.Span}


Edited Issue: Razor parser returns incorrect data tree for @section a {something} [899]

$
0
0
output returned by Razor parser for “@section a {something}” is as below. tree returned in incorrect.

- block {Markup Block at (0:0,0)::33 (Gen:None)} System.Web.Razor.Parser.SyntaxTree.Block
+ base {Markup Block at (0:0,0)::33 (Gen:None)} System.Web.Razor.Parser.SyntaxTree.SyntaxTreeNode {System.Web.Razor.Parser.SyntaxTree.Block}
- Children Count = 3 System.Collections.Generic.IEnumerable<System.Web.Razor.Parser.SyntaxTree.SyntaxTreeNode> {System.Collections.Generic.List<System.Web.Razor.Parser.SyntaxTree.SyntaxTreeNode>}
+ [0] {Markup Span at (0:0,0)::0 - [] Edit: <SpanEditHandler;Accepts:Any> Gen: <Markup> {HtmlSymbol:1}} System.Web.Razor.Parser.SyntaxTree.SyntaxTreeNode {System.Web.Razor.Parser.SyntaxTree.Span}
+ [1] {Section Block at (0:0,0)::21 (Gen:Section:a)} System.Web.Razor.Parser.SyntaxTree.SyntaxTreeNode {System.Web.Razor.Parser.SyntaxTree.Block}
+ [2] {Markup Span at (12:0,12)::12 - [something}
] Edit: <SpanEditHandler;Accepts:Any> Gen: <Markup> {HtmlSymbol:2}} System.Web.Razor.Parser.SyntaxTree.SyntaxTreeNode {System.Web.Razor.Parser.SyntaxTree.Span}


Created Issue: Make ODataMediaTypeFormatter constructors public [900]

$
0
0
Make at least these ODataMediaTypeFormatter constructors public so that the user can instantiate and extend ODataMediaTypeFormatter:

internal ODataMediaTypeFormatter(IEnumerable<ODataPayloadKind> payloadKinds)

internal ODataMediaTypeFormatter(ODataDeserializerProvider deserializerProvider,
ODataSerializerProvider serializerProvider, IEnumerable<ODataPayloadKind> payloadKinds)

private ODataMediaTypeFormatter(ODataMediaTypeFormatter formatter, ODataVersion version,
HttpRequestMessage request)

Edited Issue: Make ODataMediaTypeFormatter constructors public [900]

$
0
0
Make at least these ODataMediaTypeFormatter constructors public so that the user can instantiate and extend ODataMediaTypeFormatter:

internal ODataMediaTypeFormatter(IEnumerable<ODataPayloadKind> payloadKinds)

internal ODataMediaTypeFormatter(ODataDeserializerProvider deserializerProvider, ODataSerializerProvider serializerProvider, IEnumerable<ODataPayloadKind> payloadKinds)

private ODataMediaTypeFormatter(ODataMediaTypeFormatter formatter, ODataVersion version, HttpRequestMessage request)

Created Issue: PageSize should limit data loaded from database [901]

$
0
0
[Queryable(PageSize = 10)] will only limit the data sent to the client but not the data loaded from database.

This can cause performance issue that SQL server will try to load the whole table to the query.

The correct way is to take PageSize + 1 data from database in order to check if next page is available.




Edited Issue: PageSize should limit data loaded from database [901]

$
0
0
[Queryable(PageSize = 10)] will only limit the data sent to the client but not the data loaded from database.

This can cause performance issue that SQL server will try to load the whole table to the query.

The correct way is to take PageSize + 1 data from database in order to check if next page is available.





Reviewed: v4.0 RTM (三月 11, 2013)

$
0
0
Rated 5 Stars (out of 5) - good,hope more and more source code will be release~~! MS u r the best~~!

Commented Issue: Make the ApiControllerActionSelector more extensible [277]

$
0
0
The goal is to have the default action selector (ApiControllerActionSelector) expose some hooks or properties so that it's easier to customize.
Comments: Please also make DefaultHttpControllerSelector more extensible, for the similar reason.

Commented Feature: Support for anonymous types [695]

$
0
0
Enable support for Entities created dynamically at runtime.
Comments: IQueryable<DynamicObject> connot be queried upon

Edited Issue: Model binding of route wildcard broken in Web API [718]

$
0
0
A route like this:

routes.MapHttpRoute(
"KuduVirtualFileSystem",
"api/{segment}/{*path}",
defaults: new { controller = "demo" });

and a Web Api controller action like this:

public async Task<HttpResponseMessage> GetItem(string segment, string path = null)

fails a request like this (no path component)

http:/..../api/segment

but works for a non-empty path component like this:

http:/.../api/segment/path

The exception is as follows:

{"Message":"An error has occurred.","ExceptionMessage":"Object reference not set to an instance of an object.","ExceptionType":"System.NullReferenceException","StackTrace":" at System.Web.Http.ValueProviders.Providers.RouteDataValueProvider.<GetRoutes>d__4.MoveNext()\r\n at System.Web.Http.ValueProviders.Providers.NameValuePairsValueProvider.InitializeValues(IEnumerable`1 nameValuePairs)\r\n at System.Web.Http.ValueProviders.Providers.NameValuePairsValueProvider.<>c__DisplayClass8.<.ctor>b__4()\r\n at System.Lazy`1.CreateValue()\r\n at System.Lazy`1.LazyInitValue()\r\n at System.Lazy`1.get_Value()\r\n at System.Web.Http.ValueProviders.Providers.NameValuePairsValueProvider.GetValue(String key)\r\n at System.Web.Http.ValueProviders.Providers.CompositeValueProvider.GetValue(String key)\r\n at System.Web.Http.ModelBinding.Binders.TypeConverterModelBinder.BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)\r\n at System.Web.Http.Controllers.HttpActionContextExtensions.Bind(HttpActionContext actionContext, ModelBindingContext bindingContext, IEnumerable`1 binders)\r\n at System.Web.Http.ModelBinding.Binders.CompositeModelBinder.TryBind(HttpActionContext actionContext, ModelBindingContext bindingContext)\r\n at System.Web.Http.ModelBinding.Binders.CompositeModelBinder.BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)\r\n at System.Web.Http.ModelBinding.ModelBinderParameterBinding.ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken)\r\n at System.Web.Http.Controllers.HttpActionBinding.<>c__DisplayClass1.<ExecuteBindingAsync>b__0(HttpParameterBinding parameterBinder)\r\n at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext()\r\n at System.Threading.Tasks.TaskHelpers.IterateImpl(IEnumerator`1 enumerator, CancellationToken cancellationToken)"}

Attached is a repro showing that it works in MVC and not in Web API

Updated Wiki: CORS support for ASP.NET Web API

$
0
0

CORS support for ASP.NET Web API

Overview

Cross-origin resource sharing (CORS) is a standard that allows web pages to make AJAX requests to another domain. It relaxes the same-origin policy implemented on the web browsers that limits the calls to be within the same domain.

The CORS spec (http://www.w3.org/TR/cors/) defines the way how the server and browser interact in order to make cross origin calls. Most of the modern browsers today already support CORS. Our goal is to enable the support for our Web API services.

Scenarios

Enabling CORS

We’ve added a new extension method to the HttpConfiguration to enable CORS. With this, you can enable the support globally, per controller or per action.

Globally

You can define a global setting when calling EnableCors. For example, the following will enable CORS globally, allowing all origins, methods, and headers. There’re many settings on the EnableCorsAttribute that you can configure which we will see later.

using System.Web.Http.Cors;publicstaticclass WebApiConfig
{publicstaticvoid Register(HttpConfiguration config)
    {// other settings removed for clarity

        config.EnableCors(new EnableCorsAttribute());
    }
}

Per Controller

The support can also be scoped to the controller. First you just need to call EnableCors without providing a global setting.

using System.Web.Http.Cors;publicstaticclass WebApiConfig
{publicstaticvoid Register(HttpConfiguration config)
    {// other settings removed for clarity

        config.EnableCors();
    }
}

Then you can declare the EnableCorsAttribute on the controller to enable CORS.

[EnableCors]publicclass ValuesController : ApiController
{public IEnumerable<string> Get()
    {returnnewstring[] { "value1", "value2" };
    }publicstring Get(int id)
    {return"value "+ id;
    }
}

Per Action

In a similar fashion, you can enable CORS on a single action by first calling EnableCors.

using System.Web.Http.Cors;publicstaticclass WebApiConfig
{publicstaticvoid Register(HttpConfiguration config)
    {// other settings removed for clarity

        config.EnableCors();
    }
}

And then declare the EnableCorsAttribute on an action.

publicclass ValuesController : ApiController
{public IEnumerable<string> Get()
    {returnnewstring[] { "value1", "value2" };
    }

    [EnableCors]
    publicstring Get(int id)
    {return"value "+ id;
    }
}

Attribute precedence

When you have the EnableCorsAttribute applied on all scopes (globally, per-controller, per-action), the closest one to the resource wins. Therefore the precedence is defined as follows:

  1. Action
  2. Controller
  3. Global

Excluding a controller or an action from EnableCors

You can use [DisableCors] attribute to exclude a controller or and action from the global or per-controller settings. For example, the following will enable CORS for all the actions in the ValuesController except for Get(int id).

[EnableCors]publicclass ValuesController : ApiController
{public IEnumerable<string> Get()
    {returnnewstring[] { "value1", "value2" };
    }

    [DisableCors]
    publicstring Get(int id)
    {return"value "+ id;
    }
}

Configuring [EnableCors] attribute

There’re few settings under the EnableCorsAttribute. These settings are defined by the CORS spec (http://www.w3.org/TR/cors/#resource-processing-model).

  • Origins
  • Headers
  • Methods
  • ExposedHeaders
  • SupportsCredentials
  • PreflightMaxAge

By default, EnableCorsAttribute will allow all origins, methods and headers. Note that when you declare the attribute on an action it automatically assumes the HTTP Method of the action that you declared on.

As soon as you specify the origins, you are basically limiting the access to the specified origins. The same applies to the methods and the headers.

For example, the following will only allow “http://localhost” and “http://sample.com” to access the ValuesController from the browser though AJAX. Note that it is still allowing any methods and headers because they’re not specified.

[EnableCors(Origins = new[] { "http://localhost", "http://sample.com" })]publicclass ValuesController : ApiController
{public IEnumerable<string> Get()
    {returnnewstring[] { "value1", "value2" };
    }publicstring Get(int id)
    {return"value "+ id;
    }
}

Implementing a custom ICorsPolicyProvider

You can implement ICorsPolicyProvider to load the CORS settings/policy dynamically from other sources such as web.config or database. In fact, both the EnableCorsAttribute and DisableCorsAttribute implement this interface internally.

namespace System.Web.Http.Cors
{
    public interface ICorsPolicyProvider
    {
        Task GetCorsPolicyAsync(HttpRequestMessage request);
    }
}

Note that the ICorsPolicyProvider is async so that we don’t block the thread on I/O.

Sample

Here is a custom implementation of ICorsPolicyProvider that loads the origins from web.config.

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false)]publicclass EnableCorsAppSettingsAttribute : Attribute, ICorsPolicyProvider
{private CorsPolicy _policy;public EnableCorsAppSettingsAttribute(string appSettingOriginKey)
    {
        _policy = new CorsPolicy
        {
            AllowAnyMethod = true,
            AllowAnyHeader = true
        };// loads the origins from AppSettingsstring originsString = ConfigurationManager.AppSettings[appSettingOriginKey];if (!String.IsNullOrEmpty(originsString))
        {foreach (var origin in originsString.Split(','))
            {
                _policy.Origins.Add(origin);
            }
        }
    }public Task<CorsPolicy> GetCorsPolicyAsync(HttpRequestMessage request)
    {return Task.FromResult(_policy);
    }
}

You can apply it on the controller/action just like EnableCorsAttribute.

[EnableCorsAppSettings("internal:origins")]publicclass ValuesController : ApiController
{public IEnumerable<string> Get()
    {returnnewstring[] { "value1", "value2" };
    }publicstring Get(int id)
    {return"value "+ id;
    }
}

And it will read the “internal:origins” appSetting from the web.config.

<appSettings><addkey="webpages:Version"value="2.0.0.0"/><addkey="webpages:Enabled"value="false"/><addkey="PreserveLoginUrl"value="true"/><addkey="ClientValidationEnabled"value="true"/><addkey="UnobtrusiveJavaScriptEnabled"value="true"/><addkey="internal:origins"value="http://example.com,http://webapisample.azurewebsites.net"/></appSettings>

Implementing a custom ICorsPolicyProviderFactory

ICorsPolicyProviderFactory is an abstraction that allows you to specify how the ICorsPolicyProvider are retrieved. By default we provide the AttributeBasedPolicyProviderFactory which allows you to specify the ICorsPolicyProvider as attributes ([EnableCors], [DisableCors]). However you can extend the ICorsPolicyProviderFactory to create a centralized configuration model.

namespace System.Web.Http.Cors
{publicinterface ICorsPolicyProviderFactory
    {
        ICorsPolicyProvider GetCorsPolicyProvider(HttpRequestMessage request);
    }
}

You can register the custom ICorsPolicyProviderFactory through SetCorsPolicyProviderFactory extension method.

publicstaticclass HttpConfigurationExtensions
{// other extensions removed for claritypublicstaticvoid SetCorsPolicyProviderFactory(this HttpConfiguration httpConfiguration, ICorsPolicyProviderFactory corsPolicyProviderFactory);
}
Sample

Here is a custom implementation of ICorsPolicyProviderFactory that allows you to configure the CORS settings through your own CorsConfiguration class instead of attributes.

publicclass ConfigBasedPolicyProviderFactory : ICorsPolicyProviderFactory
{private CorsConfiguration _configuration;public ConfigBasedPolicyProviderFactory(CorsConfiguration configuration)
    {
        _configuration = configuration;
    }public ICorsPolicyProvider GetCorsPolicyProvider(HttpRequestMessage request)
    {var routeData = request.GetRouteData();if (routeData == null || !routeData.Values.Keys.Contains("controller"))
        {returnnull;
        }var controller = routeData.Values["controller"] asstring;return _configuration.GetPolicyForRequest(controller);
    }
}
publicclass CorsConfiguration
{private Dictionary<string, EnableCorsAttribute> _settings = new Dictionary<string, EnableCorsAttribute>();publicvoid AddSetting(string controller, EnableCorsAttribute policyProvider)
    {
        _settings.Add(controller, policyProvider);
    }publicvirtual EnableCorsAttribute GetPolicyForRequest(string controller)
    {
        EnableCorsAttribute policyProvider;
        _settings.TryGetValue(controller, out policyProvider);return policyProvider;
    }
}

Once the ConfigBasedPolicyProviderFactory is registered, it will enable CORS on ValuesController and UsersController.

CorsConfiguration corsConfig = new CorsConfiguration();
corsConfig.AddSetting("Values", new EnableCorsAttribute());
corsConfig.AddSetting("Users", new EnableCorsAttribute { Origins = new[] { "http://localhost" } });
config.SetCorsPolicyProviderFactory(new ConfigBasedPolicyProviderFactory(corsConfig));

config.EnableCors();

Edited Issue: Summary for GetAssemblies method of WebHostAssembliesResolver is wrong [716]

$
0
0
I think the summary for GetAssemblies method of WebHostAssembliesResolver under System.Web.Http.WebHost project is wrong:

/// <summary>
/// Returns a list of controllers available for the application.
/// </summary>
/// <returns>An <see cref="ICollection{Assembly}" /> of controllers.</returns>
ICollection<Assembly> IAssembliesResolver.GetAssemblies()
{
return BuildManager.GetReferencedAssemblies().OfType<Assembly>().ToList();
}

Edited Feature: Native support for Web API Versioning [711]

$
0
0
I would like that Web API supports natively versioning api, for example:

Base URI.
Http headers.
Query string parameter.

Regards!

Updated Wiki: CORS support for ASP.NET Web API

$
0
0

CORS support for ASP.NET Web API

Overview

Cross-origin resource sharing (CORS) is a standard that allows web pages to make AJAX requests to another domain. It relaxes the same-origin policy implemented on the web browsers that limits the calls to be within the same domain.

The CORS spec (http://www.w3.org/TR/cors/) defines the way how the server and browser interact in order to make cross origin calls. Most of the modern browsers today already support CORS. Our goal is to enable the support for our Web API services.

Scenarios

Enabling CORS

We’ve added a new extension method to the HttpConfiguration to enable CORS. With this, you can enable the support globally, per controller or per action.

Globally

You can define a global setting when calling EnableCors. For example, the following will enable CORS globally, allowing all origins, methods, and headers. There’re many settings on the EnableCorsAttribute that you can configure which we will see later.

using System.Web.Http.Cors;publicstaticclass WebApiConfig
{publicstaticvoid Register(HttpConfiguration config)
    {// other settings removed for clarity

        config.EnableCors(new EnableCorsAttribute());
    }
}

Per Controller

The support can also be scoped to the controller. First you just need to call EnableCors without providing a global setting.

using System.Web.Http.Cors;publicstaticclass WebApiConfig
{publicstaticvoid Register(HttpConfiguration config)
    {// other settings removed for clarity

        config.EnableCors();
    }
}

Then you can declare the EnableCorsAttribute on the controller to enable CORS.

[EnableCors]publicclass ValuesController : ApiController
{public IEnumerable<string> Get()
    {returnnewstring[] { "value1", "value2" };
    }publicstring Get(int id)
    {return"value "+ id;
    }
}

Per Action

In a similar fashion, you can enable CORS on a single action by first calling EnableCors.

using System.Web.Http.Cors;publicstaticclass WebApiConfig
{publicstaticvoid Register(HttpConfiguration config)
    {// other settings removed for clarity

        config.EnableCors();
    }
}

And then declare the EnableCorsAttribute on an action.

publicclass ValuesController : ApiController
{public IEnumerable<string> Get()
    {returnnewstring[] { "value1", "value2" };
    }

    [EnableCors]
    publicstring Get(int id)
    {return"value "+ id;
    }
}

Attribute precedence

When you have the EnableCorsAttribute applied on all scopes (globally, per-controller, per-action), the closest one to the resource wins. Therefore the precedence is defined as follows:

  1. Action
  2. Controller
  3. Global

Excluding a controller or an action from EnableCors

You can use [DisableCors] attribute to exclude a controller or and action from the global or per-controller settings. For example, the following will enable CORS for all the actions in the ValuesController except for Get(int id).

[EnableCors]publicclass ValuesController : ApiController
{public IEnumerable<string> Get()
    {returnnewstring[] { "value1", "value2" };
    }

    [DisableCors]
    publicstring Get(int id)
    {return"value "+ id;
    }
}

Configuring [EnableCors] attribute

There’re few settings under the EnableCorsAttribute. These settings are defined by the CORS spec (http://www.w3.org/TR/cors/#resource-processing-model).

  • Origins
  • Headers
  • Methods
  • ExposedHeaders
  • SupportsCredentials
  • PreflightMaxAge

By default, EnableCorsAttribute will allow all origins, methods and headers. Note that when you declare the attribute on an action it automatically assumes the HTTP Method of the action that you declared on.

As soon as you specify the origins, you are basically limiting the access to the specified origins. The same applies to the methods and the headers.

For example, the following will only allow “http://localhost” and “http://sample.com” to access the ValuesController from the browser though AJAX. Note that it is still allowing any methods and headers because they’re not specified.

[EnableCors(Origins = new[] { "http://localhost", "http://sample.com" })]publicclass ValuesController : ApiController
{public IEnumerable<string> Get()
    {returnnewstring[] { "value1", "value2" };
    }publicstring Get(int id)
    {return"value "+ id;
    }
}

Implementing a custom ICorsPolicyProvider

You can implement ICorsPolicyProvider to load the CORS settings/policy dynamically from other sources such as web.config or database. In fact, both the EnableCorsAttribute and DisableCorsAttribute implement this interface internally.

namespace System.Web.Http.Cors
{
    public interface ICorsPolicyProvider
    {
        Task GetCorsPolicyAsync(HttpRequestMessage request);
    }
}

Note that the ICorsPolicyProvider is async so that we don’t block the thread on I/O.

Sample

Here is a custom implementation of ICorsPolicyProvider that loads the origins from web.config.

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false)]publicclass EnableCorsAppSettingsAttribute : Attribute, ICorsPolicyProvider
{private CorsPolicy _policy;public EnableCorsAppSettingsAttribute(string appSettingOriginKey)
    {
        _policy = new CorsPolicy
        {
            AllowAnyMethod = true,
            AllowAnyHeader = true
        };// loads the origins from AppSettingsstring originsString = ConfigurationManager.AppSettings[appSettingOriginKey];if (!String.IsNullOrEmpty(originsString))
        {foreach (var origin in originsString.Split(','))
            {
                _policy.Origins.Add(origin);
            }
        }
    }public Task<CorsPolicy> GetCorsPolicyAsync(HttpRequestMessage request)
    {return Task.FromResult(_policy);
    }
}

You can apply it on the controller/action just like EnableCorsAttribute.

[EnableCorsAppSettings("internal:origins")]publicclass ValuesController : ApiController
{public IEnumerable<string> Get()
    {returnnewstring[] { "value1", "value2" };
    }publicstring Get(int id)
    {return"value "+ id;
    }
}

And it will read the “internal:origins” appSetting from the web.config.

<appSettings><addkey="webpages:Version"value="2.0.0.0"/><addkey="webpages:Enabled"value="false"/><addkey="PreserveLoginUrl"value="true"/><addkey="ClientValidationEnabled"value="true"/><addkey="UnobtrusiveJavaScriptEnabled"value="true"/><addkey="internal:origins"value="http://example.com,http://webapisample.azurewebsites.net"/></appSettings>

Implementing a custom ICorsPolicyProviderFactory

ICorsPolicyProviderFactory is an abstraction that allows you to specify how the ICorsPolicyProvider are retrieved. By default we provide the AttributeBasedPolicyProviderFactory which allows you to specify the ICorsPolicyProvider as attributes ([EnableCors], [DisableCors]). However you can extend the ICorsPolicyProviderFactory to create a centralized configuration model.

namespace System.Web.Http.Cors
{publicinterface ICorsPolicyProviderFactory
    {
        ICorsPolicyProvider GetCorsPolicyProvider(HttpRequestMessage request);
    }
}

You can register the custom ICorsPolicyProviderFactory through SetCorsPolicyProviderFactory extension method.

publicstaticclass HttpConfigurationExtensions
{// other extensions removed for claritypublicstaticvoid SetCorsPolicyProviderFactory(this HttpConfiguration httpConfiguration, ICorsPolicyProviderFactory corsPolicyProviderFactory);
}
Sample

Here is a custom implementation of ICorsPolicyProviderFactory that allows you to configure the CORS settings through your own CorsConfiguration class instead of attributes.

publicclass ConfigBasedPolicyProviderFactory : ICorsPolicyProviderFactory
{private CorsConfiguration _configuration;public ConfigBasedPolicyProviderFactory(CorsConfiguration configuration)
    {
        _configuration = configuration;
    }public ICorsPolicyProvider GetCorsPolicyProvider(HttpRequestMessage request)
    {var routeData = request.GetRouteData();if (routeData == null || !routeData.Values.Keys.Contains("controller"))
        {returnnull;
        }var controller = routeData.Values["controller"] asstring;return _configuration.GetPolicyForRequest(controller);
    }
}
publicclass CorsConfiguration
{private Dictionary<string, EnableCorsAttribute> _settings = new Dictionary<string, EnableCorsAttribute>();publicvoid AddSetting(string controller, EnableCorsAttribute policyProvider)
    {
        _settings.Add(controller, policyProvider);
    }publicvirtual EnableCorsAttribute GetPolicyForRequest(string controller)
    {
        EnableCorsAttribute policyProvider;
        _settings.TryGetValue(controller, out policyProvider);return policyProvider;
    }
}

 

Once the ConfigBasedPolicyProviderFactory is registered, it will enable CORS on ValuesController and UsersController.

 

CorsConfiguration corsConfig = new CorsConfiguration();
corsConfig.AddSetting("Values", new EnableCorsAttribute());
corsConfig.AddSetting("Users", new EnableCorsAttribute { Origins = new[] { "http://localhost" } });
config.SetCorsPolicyProviderFactory(new ConfigBasedPolicyProviderFactory(corsConfig));

config.EnableCors();

Updated Wiki: CORS support for ASP.NET Web API

$
0
0

CORS support for ASP.NET Web API

Overview

Cross-origin resource sharing (CORS) is a standard that allows web pages to make AJAX requests to another domain. It relaxes the same-origin policy implemented on the web browsers that limits the calls to be within the same domain.

The CORS spec (http://www.w3.org/TR/cors/) defines the way how the server and browser interact in order to make cross origin calls. Most of the modern browsers today already support CORS. Our goal is to enable the support for our Web API services.

Scenarios

Enabling CORS

We’ve added a new extension method to the HttpConfiguration to enable CORS. With this, you can enable the support globally, per controller or per action.

Globally

You can define a global setting when calling EnableCors. For example, the following will enable CORS globally, allowing all origins, methods, and headers. There’re many settings on the EnableCorsAttribute that you can configure which we will see later.

using System.Web.Http.Cors;publicstaticclass WebApiConfig
{publicstaticvoid Register(HttpConfiguration config)
    {// other settings removed for clarity

        config.EnableCors(new EnableCorsAttribute());
    }
}

Per Controller

The support can also be scoped to the controller. First you just need to call EnableCors without providing a global setting.

using System.Web.Http.Cors;publicstaticclass WebApiConfig
{publicstaticvoid Register(HttpConfiguration config)
    {// other settings removed for clarity

        config.EnableCors();
    }
}

Then you can declare the EnableCorsAttribute on the controller to enable CORS.

[EnableCors]publicclass ValuesController : ApiController
{public IEnumerable<string> Get()
    {returnnewstring[] { "value1", "value2" };
    }publicstring Get(int id)
    {return"value "+ id;
    }
}

Per Action

In a similar fashion, you can enable CORS on a single action by first calling EnableCors.

using System.Web.Http.Cors;publicstaticclass WebApiConfig
{publicstaticvoid Register(HttpConfiguration config)
    {// other settings removed for clarity

        config.EnableCors();
    }
}

And then declare the EnableCorsAttribute on an action.

publicclass ValuesController : ApiController
{public IEnumerable<string> Get()
    {returnnewstring[] { "value1", "value2" };
    }

    [EnableCors]
    publicstring Get(int id)
    {return"value "+ id;
    }
}

Attribute precedence

When you have the EnableCorsAttribute applied on all scopes (globally, per-controller, per-action), the closest one to the resource wins. Therefore the precedence is defined as follows:

  1. Action
  2. Controller
  3. Global

Excluding a controller or an action from EnableCors

You can use [DisableCors] attribute to exclude a controller or and action from the global or per-controller settings. For example, the following will enable CORS for all the actions in the ValuesController except for Get(int id).

[EnableCors]publicclass ValuesController : ApiController
{public IEnumerable<string> Get()
    {returnnewstring[] { "value1", "value2" };
    }

    [DisableCors]
    publicstring Get(int id)
    {return"value "+ id;
    }
}

Configuring [EnableCors] attribute

There’re few settings under the EnableCorsAttribute. These settings are defined by the CORS spec (http://www.w3.org/TR/cors/#resource-processing-model).

  • Origins
  • Headers
  • Methods
  • ExposedHeaders
  • SupportsCredentials
  • PreflightMaxAge

By default, EnableCorsAttribute will allow all origins, methods and headers. Note that when you declare the attribute on an action it automatically assumes the HTTP Method of the action that you declared on.

As soon as you specify the origins, you are basically limiting the access to the specified origins. The same applies to the methods and the headers.

For example, the following will only allow “http://localhost” and “http://sample.com” to access the ValuesController from the browser though AJAX. Note that it is still allowing any methods and headers because they’re not specified.

[EnableCors(Origins = new[] { "http://localhost", "http://sample.com" })]publicclass ValuesController : ApiController
{public IEnumerable<string> Get()
    {returnnewstring[] { "value1", "value2" };
    }publicstring Get(int id)
    {return"value "+ id;
    }
}

Implementing a custom ICorsPolicyProvider

You can implement ICorsPolicyProvider to load the CORS settings/policy dynamically from other sources such as web.config or database. In fact, both the EnableCorsAttribute and DisableCorsAttribute implement this interface internally.

namespace System.Web.Http.Cors
{
    public interface ICorsPolicyProvider
    {
        Task GetCorsPolicyAsync(HttpRequestMessage request);
    }
}

Note that the ICorsPolicyProvider is async so that we don’t block the thread on I/O.

Sample

Here is a custom implementation of ICorsPolicyProvider that loads the origins from web.config.

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false)]publicclass EnableCorsAppSettingsAttribute : Attribute, ICorsPolicyProvider
{private CorsPolicy _policy;public EnableCorsAppSettingsAttribute(string appSettingOriginKey)
    {
        _policy = new CorsPolicy
        {
            AllowAnyMethod = true,
            AllowAnyHeader = true
        };// loads the origins from AppSettingsstring originsString = ConfigurationManager.AppSettings[appSettingOriginKey];if (!String.IsNullOrEmpty(originsString))
        {foreach (var origin in originsString.Split(','))
            {
                _policy.Origins.Add(origin);
            }
        }
    }public Task<CorsPolicy> GetCorsPolicyAsync(HttpRequestMessage request)
    {return Task.FromResult(_policy);
    }
}

You can apply it on the controller/action just like EnableCorsAttribute.

[EnableCorsAppSettings("internal:origins")]publicclass ValuesController : ApiController
{public IEnumerable<string> Get()
    {returnnewstring[] { "value1", "value2" };
    }publicstring Get(int id)
    {return"value "+ id;
    }
}

And it will read the “internal:origins” appSetting from the web.config.

<appSettings><addkey="webpages:Version"value="2.0.0.0"/><addkey="webpages:Enabled"value="false"/><addkey="PreserveLoginUrl"value="true"/><addkey="ClientValidationEnabled"value="true"/><addkey="UnobtrusiveJavaScriptEnabled"value="true"/><addkey="internal:origins"value="http://example.com,http://webapisample.azurewebsites.net"/></appSettings>

Implementing a custom ICorsPolicyProviderFactory

ICorsPolicyProviderFactory is an abstraction that allows you to specify how the ICorsPolicyProvider are retrieved. By default we provide the AttributeBasedPolicyProviderFactory which allows you to specify the ICorsPolicyProvider as attributes ([EnableCors], [DisableCors]). However you can extend the ICorsPolicyProviderFactory to create a centralized configuration model.

namespace System.Web.Http.Cors
{publicinterface ICorsPolicyProviderFactory
    {
        ICorsPolicyProvider GetCorsPolicyProvider(HttpRequestMessage request);
    }
}

You can register the custom ICorsPolicyProviderFactory through SetCorsPolicyProviderFactory extension method.

publicstaticclass HttpConfigurationExtensions
{// other extensions removed for claritypublicstaticvoid SetCorsPolicyProviderFactory(this HttpConfiguration httpConfiguration, ICorsPolicyProviderFactory corsPolicyProviderFactory);
}
Sample

Here is a custom implementation of ICorsPolicyProviderFactory that allows you to configure the CORS settings through your own CorsConfiguration class instead of attributes.

publicclass ConfigBasedPolicyProviderFactory : ICorsPolicyProviderFactory
{private CorsConfiguration _configuration;public ConfigBasedPolicyProviderFactory(CorsConfiguration configuration)
    {
        _configuration = configuration;
    }public ICorsPolicyProvider GetCorsPolicyProvider(HttpRequestMessage request)
    {var routeData = request.GetRouteData();if (routeData == null || !routeData.Values.Keys.Contains("controller"))
        {returnnull;
        }var controller = routeData.Values["controller"] asstring;return _configuration.GetPolicyForRequest(controller);
    }
}
publicclass CorsConfiguration
{private Dictionary<string, EnableCorsAttribute> _settings = new Dictionary<string, EnableCorsAttribute>();publicvoid AddSetting(string controller, EnableCorsAttribute policyProvider)
    {
        _settings.Add(controller, policyProvider);
    }publicvirtual EnableCorsAttribute GetPolicyForRequest(string controller)
    {
        EnableCorsAttribute policyProvider;
        _settings.TryGetValue(controller, out policyProvider);return policyProvider;
    }
}

Updated Wiki: CORS support for ASP.NET Web API

$
0
0

CORS support for ASP.NET Web API

Overview

Cross-origin resource sharing (CORS) is a standard that allows web pages to make AJAX requests to another domain. It relaxes the same-origin policy implemented on the web browsers that limits the calls to be within the same domain.

The CORS spec (http://www.w3.org/TR/cors/) defines the way how the server and browser interact in order to make cross origin calls. Most of the modern browsers today already support CORS. Our goal is to enable the support for our Web API services.

Scenarios

Enabling CORS

We’ve added a new extension method to the HttpConfiguration to enable CORS. With this, you can enable the support globally, per controller or per action.

Globally

You can define a global setting when calling EnableCors. For example, the following will enable CORS globally, allowing all origins, methods, and headers. There’re many settings on the EnableCorsAttribute that you can configure which we will see later.

using System.Web.Http.Cors;
publicstaticclass WebApiConfig
{
    publicstaticvoid Register(HttpConfiguration config)
    {
        // other settings removed for clarity

        config.EnableCors(new EnableCorsAttribute());
    }
}

Per Controller

The support can also be scoped to the controller. First you just need to call EnableCors without providing a global setting.

using System.Web.Http.Cors;
publicstaticclass WebApiConfig
{
    publicstaticvoid Register(HttpConfiguration config)
    {
        // other settings removed for clarity

        config.EnableCors();
    }
}

Then you can declare the EnableCorsAttribute on the controller to enable CORS.

[EnableCors]
publicclass ValuesController : ApiController
{
    public IEnumerable<string> Get()
    {
        returnnewstring[] { "value1", "value2" };
    }

    publicstring Get(int id)
    {
        return"value "+ id;
    }
}

Per Action

In a similar fashion, you can enable CORS on a single action by first calling EnableCors.

using System.Web.Http.Cors;
publicstaticclass WebApiConfig
{
    publicstaticvoid Register(HttpConfiguration config)
    {
        // other settings removed for clarity

        config.EnableCors();
    }
}

And then declare the EnableCorsAttribute on an action.

publicclass ValuesController : ApiController
{
    public IEnumerable<string> Get()
    {
        returnnewstring[] { "value1", "value2" };
    }

    [EnableCors]
    publicstring Get(int id)
    {
        return"value "+ id;
    }
}

Attribute precedence

When you have the EnableCorsAttribute applied on all scopes (globally, per-controller, per-action), the closest one to the resource wins. Therefore the precedence is defined as follows:

  1. Action
  2. Controller
  3. Global

Excluding a controller or an action from EnableCors

You can use [DisableCors] attribute to exclude a controller or and action from the global or per-controller settings. For example, the following will enable CORS for all the actions in the ValuesController except for Get(int id).

[EnableCors]
publicclass ValuesController : ApiController
{
    public IEnumerable<string> Get()
    {
        returnnewstring[] { "value1", "value2" };
    }

    [DisableCors]
    publicstring Get(int id)
    {
        return"value "+ id;
    }
}

Configuring [EnableCors] attribute

There’re few settings under the EnableCorsAttribute. These settings are defined by the CORS spec (http://www.w3.org/TR/cors/#resource-processing-model).

  • Origins
  • Headers
  • Methods
  • ExposedHeaders
  • SupportsCredentials
  • PreflightMaxAge

By default, EnableCorsAttribute will allow all origins, methods and headers. Note that when you declare the attribute on an action it automatically assumes the HTTP Method of the action that you declared on.

As soon as you specify the origins, you are basically limiting the access to the specified origins. The same applies to the methods and the headers.

For example, the following will only allow “http://localhost” and “http://sample.com” to access the ValuesController from the browser though AJAX. Note that it is still allowing any methods and headers because they’re not specified.

[EnableCors(Origins = new[] { "http://localhost", "http://sample.com" })]
publicclass ValuesController : ApiController
{
    public IEnumerable<string> Get()
    {
        returnnewstring[] { "value1", "value2" };
    }

    publicstring Get(int id)
    {
        return"value "+ id;
    }
}

Implementing a custom ICorsPolicyProvider

You can implement ICorsPolicyProvider to load the CORS settings/policy dynamically from other sources such as web.config or database. In fact, both the EnableCorsAttribute and DisableCorsAttribute implement this interface internally.

namespace System.Web.Http.Cors
{
    public interface ICorsPolicyProvider
    {
        Task GetCorsPolicyAsync(HttpRequestMessage request);
    }
}

Note that the ICorsPolicyProvider is async so that we don’t block the thread on I/O.

Sample

Here is a custom implementation of ICorsPolicyProvider that loads the origins from web.config.

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false)]
publicclass EnableCorsAppSettingsAttribute : Attribute, ICorsPolicyProvider
{
    private CorsPolicy _policy;

    public EnableCorsAppSettingsAttribute(string appSettingOriginKey)
    {
        _policy = new CorsPolicy
        {
            AllowAnyMethod = true,
            AllowAnyHeader = true
        };

        // loads the origins from AppSettingsstring originsString = ConfigurationManager.AppSettings[appSettingOriginKey];
        if (!String.IsNullOrEmpty(originsString))
        {
            foreach (var origin in originsString.Split(','))
            {
                _policy.Origins.Add(origin);
            }
        }
    }

    public Task<CorsPolicy> GetCorsPolicyAsync(HttpRequestMessage request)
    {
        return Task.FromResult(_policy);
    }
}

You can apply it on the controller/action just like EnableCorsAttribute.

[EnableCorsAppSettings("internal:origins")]
publicclass ValuesController : ApiController
{
    public IEnumerable<string> Get()
    {
        returnnewstring[] { "value1", "value2" };
    }

    publicstring Get(int id)
    {
        return"value "+ id;
    }
}

And it will read the “internal:origins” appSetting from the web.config.

<appSettings><addkey="webpages:Version"value="2.0.0.0"/><addkey="webpages:Enabled"value="false"/><addkey="PreserveLoginUrl"value="true"/><addkey="ClientValidationEnabled"value="true"/><addkey="UnobtrusiveJavaScriptEnabled"value="true"/><addkey="internal:origins"value="http://example.com,http://webapisample.azurewebsites.net"/></appSettings>

Implementing a custom ICorsPolicyProviderFactory

ICorsPolicyProviderFactory is an abstraction that allows you to specify how the ICorsPolicyProvider are retrieved. By default we provide the AttributeBasedPolicyProviderFactory which allows you to specify the ICorsPolicyProvider as attributes ([EnableCors], [DisableCors]). However you can extend the ICorsPolicyProviderFactory to create a centralized configuration model.

namespace System.Web.Http.Cors
{
    publicinterface ICorsPolicyProviderFactory
    {
        ICorsPolicyProvider GetCorsPolicyProvider(HttpRequestMessage request);
    }
}

You can register the custom ICorsPolicyProviderFactory through SetCorsPolicyProviderFactory extension method.

publicstaticclass HttpConfigurationExtensions
{
    // other extensions removed for claritypublicstaticvoid SetCorsPolicyProviderFactory(this HttpConfiguration httpConfiguration, ICorsPolicyProviderFactory corsPolicyProviderFactory);
}
Sample

Here is a custom implementation of ICorsPolicyProviderFactory that allows you to configure the CORS settings through your own CorsConfiguration class instead of attributes.

publicclass ConfigBasedPolicyProviderFactory : ICorsPolicyProviderFactory
{
    private CorsConfiguration _configuration;

    public ConfigBasedPolicyProviderFactory(CorsConfiguration configuration)
    {
        _configuration = configuration;
    }

    public ICorsPolicyProvider GetCorsPolicyProvider(HttpRequestMessage request)
    {
        var routeData = request.GetRouteData();
        if (routeData == null || !routeData.Values.Keys.Contains("controller"))
        {
            returnnull;
        }
        var controller = routeData.Values["controller"] asstring;
        return _configuration.GetPolicyForRequest(controller);
    }
}
publicclass CorsConfiguration
{
    private Dictionary<string, EnableCorsAttribute> _settings = 
   	new Dictionary<string, EnableCorsAttribute>();

    publicvoid AddSetting(string controller, EnableCorsAttribute policyProvider)
    {
        _settings.Add(controller, policyProvider);
    }

    publicvirtual EnableCorsAttribute GetPolicyForRequest(string controller)
    {
        EnableCorsAttribute policyProvider;
        _settings.TryGetValue(controller, out policyProvider);
        return policyProvider;
    }
}

Once the ConfigBasedPolicyProviderFactory is registered, it will enable CORS on ValuesController and UsersController.

Updated Wiki: CORS support for ASP.NET Web API

$
0
0

CORS support for ASP.NET Web API

Overview

Cross-origin resource sharing (CORS) is a standard that allows web pages to make AJAX requests to another domain. It relaxes the same-origin policy implemented on the web browsers that limits the calls to be within the same domain.

The CORS spec (http://www.w3.org/TR/cors/) defines the way how the server and browser interact in order to make cross origin calls. Most of the modern browsers today already support CORS. Our goal is to enable the support for our Web API services.

Scenarios

Enabling CORS

We’ve added a new extension method to the HttpConfiguration to enable CORS. With this, you can enable the support globally, per controller or per action.

Globally

You can define a global setting when calling EnableCors. For example, the following will enable CORS globally, allowing all origins, methods, and headers. There’re many settings on the EnableCorsAttribute that you can configure which we will see later.

using System.Web.Http.Cors;publicstaticclass WebApiConfig
{publicstaticvoid Register(HttpConfiguration config)
    {// other settings removed for clarity

        config.EnableCors(new EnableCorsAttribute());
    }
}

Per Controller

The support can also be scoped to the controller. First you just need to call EnableCors without providing a global setting.

using System.Web.Http.Cors;publicstaticclass WebApiConfig
{publicstaticvoid Register(HttpConfiguration config)
    {// other settings removed for clarity

        config.EnableCors();
    }
}

Then you can declare the EnableCorsAttribute on the controller to enable CORS.

[EnableCors]publicclass ValuesController : ApiController
{public IEnumerable<string> Get()
    {returnnewstring[] { "value1", "value2" };
    }publicstring Get(int id)
    {return"value "+ id;
    }
}

Per Action

In a similar fashion, you can enable CORS on a single action by first calling EnableCors.

using System.Web.Http.Cors;publicstaticclass WebApiConfig
{publicstaticvoid Register(HttpConfiguration config)
    {// other settings removed for clarity

        config.EnableCors();
    }
}

And then declare the EnableCorsAttribute on an action.

publicclass ValuesController : ApiController
{public IEnumerable<string> Get()
    {returnnewstring[] { "value1", "value2" };
    }

    [EnableCors]
    publicstring Get(int id)
    {return"value "+ id;
    }
}

Attribute precedence

When you have the EnableCorsAttribute applied on all scopes (globally, per-controller, per-action), the closest one to the resource wins. Therefore the precedence is defined as follows:

  1. Action
  2. Controller
  3. Global

Excluding a controller or an action from EnableCors

You can use [DisableCors] attribute to exclude a controller or and action from the global or per-controller settings. For example, the following will enable CORS for all the actions in the ValuesController except for Get(int id).

[EnableCors]publicclass ValuesController : ApiController
{public IEnumerable<string> Get()
    {returnnewstring[] { "value1", "value2" };
    }

    [DisableCors]
    publicstring Get(int id)
    {return"value "+ id;
    }
}

Configuring [EnableCors] attribute

There’re few settings under the EnableCorsAttribute. These settings are defined by the CORS spec (http://www.w3.org/TR/cors/#resource-processing-model).

  • Origins
  • Headers
  • Methods
  • ExposedHeaders
  • SupportsCredentials
  • PreflightMaxAge

By default, EnableCorsAttribute will allow all origins, methods and headers. Note that when you declare the attribute on an action it automatically assumes the HTTP Method of the action that you declared on.

As soon as you specify the origins, you are basically limiting the access to the specified origins. The same applies to the methods and the headers.

For example, the following will only allow “http://localhost” and “http://sample.com” to access the ValuesController from the browser though AJAX. Note that it is still allowing any methods and headers because they’re not specified.

[EnableCors(Origins = new[] { "http://localhost", "http://sample.com" })]publicclass ValuesController : ApiController
{public IEnumerable<string> Get()
    {returnnewstring[] { "value1", "value2" };
    }publicstring Get(int id)
    {return"value "+ id;
    }
}

Implementing a custom ICorsPolicyProvider

You can implement ICorsPolicyProvider to load the CORS settings/policy dynamically from other sources such as web.config or database. In fact, both the EnableCorsAttribute and DisableCorsAttribute implement this interface internally.

namespace System.Web.Http.Cors
{
    public interface ICorsPolicyProvider
    {
        Task GetCorsPolicyAsync(HttpRequestMessage request);
    }
}

Note that the ICorsPolicyProvider is async so that we don’t block the thread on I/O.

Sample

Here is a custom implementation of ICorsPolicyProvider that loads the origins from web.config.

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false)]publicclass EnableCorsAppSettingsAttribute : Attribute, ICorsPolicyProvider
{private CorsPolicy _policy;public EnableCorsAppSettingsAttribute(string appSettingOriginKey)
    {
        _policy = new CorsPolicy
        {
            AllowAnyMethod = true,
            AllowAnyHeader = true
        };// loads the origins from AppSettingsstring originsString = ConfigurationManager.AppSettings[appSettingOriginKey];if (!String.IsNullOrEmpty(originsString))
        {foreach (var origin in originsString.Split(','))
            {
                _policy.Origins.Add(origin);
            }
        }
    }public Task<CorsPolicy> GetCorsPolicyAsync(HttpRequestMessage request)
    {return Task.FromResult(_policy);
    }
}

You can apply it on the controller/action just like EnableCorsAttribute.

[EnableCorsAppSettings("internal:origins")]publicclass ValuesController : ApiController
{public IEnumerable<string> Get()
    {returnnewstring[] { "value1", "value2" };
    }publicstring Get(int id)
    {return"value "+ id;
    }
}

And it will read the “internal:origins” appSetting from the web.config.

<appSettings><addkey="webpages:Version"value="2.0.0.0"/><addkey="webpages:Enabled"value="false"/><addkey="PreserveLoginUrl"value="true"/><addkey="ClientValidationEnabled"value="true"/><addkey="UnobtrusiveJavaScriptEnabled"value="true"/><addkey="internal:origins"value="http://example.com,http://webapisample.azurewebsites.net"/></appSettings>

Implementing a custom ICorsPolicyProviderFactory

ICorsPolicyProviderFactory is an abstraction that allows you to specify how the ICorsPolicyProvider are retrieved. By default we provide the AttributeBasedPolicyProviderFactory which allows you to specify the ICorsPolicyProvider as attributes ([EnableCors], [DisableCors]). However you can extend the ICorsPolicyProviderFactory to create a centralized configuration model.

namespace System.Web.Http.Cors
{publicinterface ICorsPolicyProviderFactory
    {
        ICorsPolicyProvider GetCorsPolicyProvider(HttpRequestMessage request);
    }
}

You can register the custom ICorsPolicyProviderFactory through SetCorsPolicyProviderFactory extension method.

publicstaticclass HttpConfigurationExtensions
{// other extensions removed for claritypublicstaticvoid SetCorsPolicyProviderFactory(this HttpConfiguration httpConfiguration, ICorsPolicyProviderFactory corsPolicyProviderFactory);
}
Sample

Here is a custom implementation of ICorsPolicyProviderFactory that allows you to configure the CORS settings through your own CorsConfiguration class instead of attributes.

publicclass ConfigBasedPolicyProviderFactory : ICorsPolicyProviderFactory
{private CorsConfiguration _configuration;public ConfigBasedPolicyProviderFactory(CorsConfiguration configuration)
    {
        _configuration = configuration;
    }public ICorsPolicyProvider GetCorsPolicyProvider(HttpRequestMessage request)
    {var routeData = request.GetRouteData();if (routeData == null || !routeData.Values.Keys.Contains("controller"))
        {returnnull;
        }var controller = routeData.Values["controller"] asstring;return _configuration.GetPolicyForRequest(controller);
    }
}
publicclass CorsConfiguration
{private Dictionary<string, EnableCorsAttribute> _settings = new Dictionary<string, EnableCorsAttribute>();publicvoid AddSetting(string controller, EnableCorsAttribute policyProvider)
    {
        _settings.Add(controller, policyProvider);
    }publicvirtual EnableCorsAttribute GetPolicyForRequest(string controller)
    {
        EnableCorsAttribute policyProvider;
        _settings.TryGetValue(controller, out policyProvider);return policyProvider;
    }
}

Once the ConfigBasedPolicyProviderFactory is registered, it will enable CORS on ValuesController and UsersController.

CorsConfiguration corsConfig = new CorsConfiguration();
corsConfig.AddSetting("Values", new EnableCorsAttribute());
corsConfig.AddSetting("Users", new EnableCorsAttribute { Origins = new[] { "http://localhost" } });
config.SetCorsPolicyProviderFactory(new ConfigBasedPolicyProviderFactory(corsConfig));

config.EnableCors();

New Post: How to use new CORS support?

Viewing all 7925 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>