diff --git a/samples/MvcSample.Web/Filters/InspectResultPageAttribute.cs b/samples/MvcSample.Web/Filters/InspectResultPageAttribute.cs
index 6d91c843d0..9ff209fb95 100644
--- a/samples/MvcSample.Web/Filters/InspectResultPageAttribute.cs
+++ b/samples/MvcSample.Web/Filters/InspectResultPageAttribute.cs
@@ -1,28 +1,37 @@
using System;
-using System.Threading.Tasks;
using Microsoft.AspNet.Mvc;
-using Microsoft.AspNet.Mvc.Filters;
using MvcSample.Web.Models;
namespace MvcSample.Web.Filters
{
- public class InspectResultPageAttribute : ActionFilterAttribute
+ [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
+ public class InspectResultPageAttribute : Attribute, IFilterFactory
{
- public override async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next)
+ public IFilter CreateInstance(IServiceProvider serviceProvider)
{
- var viewResult = context.Result as ViewResult;
+ return new InspectResultPageFilter();
+ }
- if (viewResult != null)
+ private class InspectResultPageFilter : IResultFilter
+ {
+ public void OnResultExecuting(ResultExecutingContext context)
{
- var user = viewResult.ViewData.Model as User;
+ var viewResult = context.Result as ViewResult;
- if (user != null)
+ if (viewResult != null)
{
- user.Name += "**" + user.Name + "**";
+ var user = viewResult.ViewData.Model as User;
+
+ if (user != null)
+ {
+ user.Name += "**" + user.Name + "**";
+ }
}
}
- await next();
+ public void OnResultExecuted(ResultExecutedContext context)
+ {
+ }
}
}
}
diff --git a/samples/MvcSample.Web/Filters/UserNameProvider.cs b/samples/MvcSample.Web/Filters/UserNameProvider.cs
index 00d94fada4..9809b5d9c9 100644
--- a/samples/MvcSample.Web/Filters/UserNameProvider.cs
+++ b/samples/MvcSample.Web/Filters/UserNameProvider.cs
@@ -4,8 +4,12 @@ namespace MvcSample.Web.Filters
{
public class UserNameProvider : IActionFilter
{
- private static readonly string[] _userNames = new[] { "Jon", "David", "Goliath" };
- private static int _index;
+ private readonly UserNameService _nameService;
+
+ public UserNameProvider(UserNameService nameService)
+ {
+ _nameService = nameService;
+ }
public void OnActionExecuting(ActionExecutingContext context)
{
@@ -17,7 +21,7 @@ namespace MvcSample.Web.Filters
if (string.IsNullOrWhiteSpace(userName))
{
- context.ActionArguments["userName"] = _userNames[(_index++)%3];
+ context.ActionArguments["userName"] = _nameService.GetName();
}
}
diff --git a/samples/MvcSample.Web/Filters/UserNameService.cs b/samples/MvcSample.Web/Filters/UserNameService.cs
new file mode 100644
index 0000000000..7480bc1a91
--- /dev/null
+++ b/samples/MvcSample.Web/Filters/UserNameService.cs
@@ -0,0 +1,15 @@
+using Microsoft.AspNet.Mvc;
+
+namespace MvcSample.Web.Filters
+{
+ public class UserNameService
+ {
+ private static readonly string[] _userNames = new[] { "Jon", "David", "Goliath" };
+ private static int _index;
+
+ public string GetName()
+ {
+ return _userNames[_index++ % 3];
+ }
+ }
+}
diff --git a/samples/MvcSample.Web/MvcSample.Web.kproj b/samples/MvcSample.Web/MvcSample.Web.kproj
index 99aa4a241b..ddbfaf1c7f 100644
--- a/samples/MvcSample.Web/MvcSample.Web.kproj
+++ b/samples/MvcSample.Web/MvcSample.Web.kproj
@@ -50,6 +50,7 @@
+
diff --git a/samples/MvcSample.Web/Startup.cs b/samples/MvcSample.Web/Startup.cs
index 358c8cee2d..207b720f7d 100644
--- a/samples/MvcSample.Web/Startup.cs
+++ b/samples/MvcSample.Web/Startup.cs
@@ -2,6 +2,7 @@
using Microsoft.AspNet.Abstractions;
using Microsoft.AspNet.Mvc;
using Microsoft.AspNet.Routing;
+using MvcSample.Web.Filters;
namespace MvcSample.Web
{
@@ -13,6 +14,7 @@ namespace MvcSample.Web
{
services.AddMvc();
services.AddSingleton();
+ services.AddSingleton();
});
app.UseMvc(routes =>
diff --git a/src/Microsoft.AspNet.Mvc.Core/Filters/DefaultFilterProvider.cs b/src/Microsoft.AspNet.Mvc.Core/Filters/DefaultFilterProvider.cs
index e63eb41fab..53e123dd92 100644
--- a/src/Microsoft.AspNet.Mvc.Core/Filters/DefaultFilterProvider.cs
+++ b/src/Microsoft.AspNet.Mvc.Core/Filters/DefaultFilterProvider.cs
@@ -1,6 +1,7 @@
using System;
using System.Diagnostics.Contracts;
using Microsoft.AspNet.DependencyInjection;
+using Microsoft.AspNet.Mvc.Core;
namespace Microsoft.AspNet.Mvc.Filters
{
@@ -46,45 +47,23 @@ namespace Microsoft.AspNet.Mvc.Filters
var filter = filterItem.Descriptor.Filter;
- var serviceFilterSignature = filter as IServiceFilter;
- if (serviceFilterSignature != null)
+ var filterFactory = filter as IFilterFactory;
+ if (filterFactory == null)
{
- var serviceFilter = ServiceProvider.GetService(serviceFilterSignature.ServiceType) as IFilter;
-
- if (serviceFilter == null)
- {
- throw new InvalidOperationException("Service filter must be of type IFilter");
- }
-
- filterItem.Filter = serviceFilter;
+ filterItem.Filter = filter;
}
else
{
- var typeFilterSignature = filter as ITypeFilter;
- if (typeFilterSignature != null)
+ filterItem.Filter = filterFactory.CreateInstance(ServiceProvider);
+
+ if (filterItem.Filter == null)
{
- if (typeFilterSignature.ImplementationType == null)
- {
- throw new InvalidOperationException("Type filter must provide a type to instantiate");
- }
-
- if (!typeof (IFilter).IsAssignableFrom(typeFilterSignature.ImplementationType))
- {
- throw new InvalidOperationException("Type filter must implement IFilter");
- }
-
- var typeFilter = (IFilter)_typeActivator.CreateInstance(
- ServiceProvider,
- typeFilterSignature.ImplementationType,
- typeFilterSignature.Arguments);
-
- ApplyFilterToContainer(typeFilter, filter);
- filterItem.Filter = typeFilter;
- }
- else
- {
- filterItem.Filter = filter;
+ throw new InvalidOperationException(Resources.FormatTypeMethodMustReturnNotNullValue(
+ "CreateInstance",
+ typeof(IFilterFactory).Name));
}
+
+ ApplyFilterToContainer(filterItem.Filter, filterFactory);
}
}
diff --git a/src/Microsoft.AspNet.Mvc.Core/Filters/IFilterFactory.cs b/src/Microsoft.AspNet.Mvc.Core/Filters/IFilterFactory.cs
new file mode 100644
index 0000000000..bf7307bc5d
--- /dev/null
+++ b/src/Microsoft.AspNet.Mvc.Core/Filters/IFilterFactory.cs
@@ -0,0 +1,9 @@
+using System;
+
+namespace Microsoft.AspNet.Mvc
+{
+ public interface IFilterFactory : IFilter
+ {
+ IFilter CreateInstance([NotNull] IServiceProvider serviceProvider);
+ }
+}
diff --git a/src/Microsoft.AspNet.Mvc.Core/Filters/IServiceFilter.cs b/src/Microsoft.AspNet.Mvc.Core/Filters/IServiceFilter.cs
deleted file mode 100644
index a5763f452b..0000000000
--- a/src/Microsoft.AspNet.Mvc.Core/Filters/IServiceFilter.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-using System;
-
-namespace Microsoft.AspNet.Mvc
-{
- public interface IServiceFilter : IFilter
- {
- Type ServiceType { get; }
- }
-}
diff --git a/src/Microsoft.AspNet.Mvc.Core/Filters/ITypeFilter.cs b/src/Microsoft.AspNet.Mvc.Core/Filters/ITypeFilter.cs
deleted file mode 100644
index eccb2ed6df..0000000000
--- a/src/Microsoft.AspNet.Mvc.Core/Filters/ITypeFilter.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-using System;
-
-namespace Microsoft.AspNet.Mvc
-{
- public interface ITypeFilter : IFilter
- {
- object[] Arguments { get; }
-
- Type ImplementationType { get; }
- }
-}
diff --git a/src/Microsoft.AspNet.Mvc.Core/Filters/ServiceFilterAttribute.cs b/src/Microsoft.AspNet.Mvc.Core/Filters/ServiceFilterAttribute.cs
index e5ed6ae706..e64405c74a 100644
--- a/src/Microsoft.AspNet.Mvc.Core/Filters/ServiceFilterAttribute.cs
+++ b/src/Microsoft.AspNet.Mvc.Core/Filters/ServiceFilterAttribute.cs
@@ -1,13 +1,14 @@
using System;
using System.Diagnostics;
+using Microsoft.AspNet.Mvc.Core;
namespace Microsoft.AspNet.Mvc
{
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
[DebuggerDisplay("ServiceFilter: Type={ServiceType} Order={Order}")]
- public class ServiceFilterAttribute : Attribute, IServiceFilter
+ public class ServiceFilterAttribute : Attribute, IFilterFactory, IOrderedFilter
{
- public ServiceFilterAttribute(Type type)
+ public ServiceFilterAttribute([NotNull] Type type)
{
ServiceType = type;
}
@@ -15,5 +16,20 @@ namespace Microsoft.AspNet.Mvc
public Type ServiceType { get; private set; }
public int Order { get; set; }
+
+ public IFilter CreateInstance([NotNull] IServiceProvider serviceProvider)
+ {
+ var service = serviceProvider.GetService(ServiceType);
+
+ var filter = service as IFilter;
+ if (filter == null)
+ {
+ throw new InvalidOperationException(Resources.FormatFilterFactoryAttribute_TypeMustImplementIFilter(
+ typeof(ServiceFilterAttribute).Name,
+ typeof(IFilter).Name));
+ }
+
+ return filter;
+ }
}
}
diff --git a/src/Microsoft.AspNet.Mvc.Core/Filters/TypeFilterAttribute.cs b/src/Microsoft.AspNet.Mvc.Core/Filters/TypeFilterAttribute.cs
index a7fc9bc12d..22bc8696dc 100644
--- a/src/Microsoft.AspNet.Mvc.Core/Filters/TypeFilterAttribute.cs
+++ b/src/Microsoft.AspNet.Mvc.Core/Filters/TypeFilterAttribute.cs
@@ -1,13 +1,15 @@
using System;
using System.Diagnostics;
+using Microsoft.AspNet.DependencyInjection;
+using Microsoft.AspNet.Mvc.Core;
namespace Microsoft.AspNet.Mvc
{
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
[DebuggerDisplay("TypeFilter: Type={ImplementationType} Order={Order}")]
- public class TypeFilterAttribute : Attribute, ITypeFilter, IOrderedFilter
+ public class TypeFilterAttribute : Attribute, IFilterFactory, IOrderedFilter
{
- public TypeFilterAttribute(Type type)
+ public TypeFilterAttribute([NotNull] Type type)
{
ImplementationType = type;
}
@@ -17,5 +19,21 @@ namespace Microsoft.AspNet.Mvc
public Type ImplementationType { get; private set; }
public int Order { get; set; }
+
+ public IFilter CreateInstance([NotNull] IServiceProvider serviceProvider)
+ {
+ var activator = serviceProvider.GetService();
+ var obj = activator.CreateInstance(serviceProvider, ImplementationType, Arguments ?? new object[0]);
+
+ var filter = obj as IFilter;
+ if (filter == null)
+ {
+ throw new InvalidOperationException(Resources.FormatFilterFactoryAttribute_TypeMustImplementIFilter(
+ typeof(TypeFilterAttribute).Name,
+ typeof(IFilter).Name));
+ }
+
+ return filter;
+ }
}
}
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.Mvc.Core/Microsoft.AspNet.Mvc.Core.kproj b/src/Microsoft.AspNet.Mvc.Core/Microsoft.AspNet.Mvc.Core.kproj
index 7390e2a347..6ac42e8f14 100644
--- a/src/Microsoft.AspNet.Mvc.Core/Microsoft.AspNet.Mvc.Core.kproj
+++ b/src/Microsoft.AspNet.Mvc.Core/Microsoft.AspNet.Mvc.Core.kproj
@@ -103,8 +103,7 @@
-
-
+
diff --git a/src/Microsoft.AspNet.Mvc.Core/Properties/Resources.Designer.cs b/src/Microsoft.AspNet.Mvc.Core/Properties/Resources.Designer.cs
index c291a3c46e..685a10cae8 100644
--- a/src/Microsoft.AspNet.Mvc.Core/Properties/Resources.Designer.cs
+++ b/src/Microsoft.AspNet.Mvc.Core/Properties/Resources.Designer.cs
@@ -10,86 +10,6 @@ namespace Microsoft.AspNet.Mvc.Core
private static readonly ResourceManager _resourceManager
= new ResourceManager("Microsoft.AspNet.Mvc.Core.Resources", typeof(Resources).GetTypeInfo().Assembly);
- ///
- /// The provided identity of type '{0}' is marked IsAuthenticated = true but does not have a value for Name. By default, the anti-forgery system requires that all authenticated identities have a unique Name. If it is not possible to provide a unique Name for this identity, consider extending IAdditionalDataProvider by overriding the DefaultAdditionalDataProvider or a custom type that can provide some form of unique identifier for the current user.
- ///
- internal static string TokenValidator_AuthenticatedUserWithoutUsername
- {
- get { return GetString("TokenValidator_AuthenticatedUserWithoutUsername"); }
- }
-
- ///
- /// The provided identity of type '{0}' is marked IsAuthenticated = true but does not have a value for Name. By default, the anti-forgery system requires that all authenticated identities have a unique Name. If it is not possible to provide a unique Name for this identity, consider extending IAdditionalDataProvider by overriding the DefaultAdditionalDataProvider or a custom type that can provide some form of unique identifier for the current user.
- ///
- internal static string FormatTokenValidator_AuthenticatedUserWithoutUsername(object p0)
- {
- return string.Format(CultureInfo.CurrentCulture, GetString("TokenValidator_AuthenticatedUserWithoutUsername"), p0);
- }
-
- ///
- /// A claim of type '{0}' was not present on the provided ClaimsIdentity.
- ///
- internal static string ClaimUidExtractor_ClaimNotPresent
- {
- get { return GetString("ClaimUidExtractor_ClaimNotPresent"); }
- }
-
- ///
- /// A claim of type '{0}' was not present on the provided ClaimsIdentity.
- ///
- internal static string FormatClaimUidExtractor_ClaimNotPresent(object p0)
- {
- return string.Format(CultureInfo.CurrentCulture, GetString("ClaimUidExtractor_ClaimNotPresent"), p0);
- }
-
- ///
- /// A claim of type 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier' or 'http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider' was not present on the provided ClaimsIdentity. To enable anti-forgery token support with claims-based authentication, please verify that the configured claims provider is providing both of these claims on the ClaimsIdentity instances it generates. If the configured claims provider instead uses a different claim type as a unique identifier, it can be configured by setting the static property AntiForgeryConfig.UniqueClaimTypeIdentifier.
- ///
- internal static string ClaimUidExtractor_DefaultClaimsNotPresent
- {
- get { return GetString("ClaimUidExtractor_DefaultClaimsNotPresent"); }
- }
-
- ///
- /// A claim of type 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier' or 'http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider' was not present on the provided ClaimsIdentity. To enable anti-forgery token support with claims-based authentication, please verify that the configured claims provider is providing both of these claims on the ClaimsIdentity instances it generates. If the configured claims provider instead uses a different claim type as a unique identifier, it can be configured by setting the static property AntiForgeryConfig.UniqueClaimTypeIdentifier.
- ///
- internal static string FormatClaimUidExtractor_DefaultClaimsNotPresent()
- {
- return GetString("ClaimUidExtractor_DefaultClaimsNotPresent");
- }
-
- ///
- /// The method '{0}' on type '{1}' returned an instance of '{2}'. Make sure to call Unwrap on the returned value to avoid unobserved faulted Task.
- ///
- internal static string ActionExecutor_WrappedTaskInstance
- {
- get { return GetString("ActionExecutor_WrappedTaskInstance"); }
- }
-
- ///
- /// The method '{0}' on type '{1}' returned an instance of '{2}'. Make sure to call Unwrap on the returned value to avoid unobserved faulted Task.
- ///
- internal static string FormatActionExecutor_WrappedTaskInstance(object p0, object p1, object p2)
- {
- return string.Format(CultureInfo.CurrentCulture, GetString("ActionExecutor_WrappedTaskInstance"), p0, p1, p2);
- }
-
- ///
- /// The method '{0}' on type '{1}' returned a Task instance even though it is not an asynchronous method.
- ///
- internal static string ActionExecutor_UnexpectedTaskInstance
- {
- get { return GetString("ActionExecutor_UnexpectedTaskInstance"); }
- }
-
- ///
- /// The method '{0}' on type '{1}' returned a Task instance even though it is not an asynchronous method.
- ///
- internal static string FormatActionExecutor_UnexpectedTaskInstance(object p0, object p1)
- {
- return string.Format(CultureInfo.CurrentCulture, GetString("ActionExecutor_UnexpectedTaskInstance"), p0, p1);
- }
-
///
/// The provided anti-forgery token failed a custom data check.
///
@@ -234,6 +154,70 @@ namespace Microsoft.AspNet.Mvc.Core
return GetString("AntiForgeryWorker_RequireSSL");
}
+ ///
+ /// The method '{0}' on type '{1}' returned an instance of '{2}'. Make sure to call Unwrap on the returned value to avoid unobserved faulted Task.
+ ///
+ internal static string ActionExecutor_WrappedTaskInstance
+ {
+ get { return GetString("ActionExecutor_WrappedTaskInstance"); }
+ }
+
+ ///
+ /// The method '{0}' on type '{1}' returned an instance of '{2}'. Make sure to call Unwrap on the returned value to avoid unobserved faulted Task.
+ ///
+ internal static string FormatActionExecutor_WrappedTaskInstance(object p0, object p1, object p2)
+ {
+ return string.Format(CultureInfo.CurrentCulture, GetString("ActionExecutor_WrappedTaskInstance"), p0, p1, p2);
+ }
+
+ ///
+ /// The method '{0}' on type '{1}' returned a Task instance even though it is not an asynchronous method.
+ ///
+ internal static string ActionExecutor_UnexpectedTaskInstance
+ {
+ get { return GetString("ActionExecutor_UnexpectedTaskInstance"); }
+ }
+
+ ///
+ /// The method '{0}' on type '{1}' returned a Task instance even though it is not an asynchronous method.
+ ///
+ internal static string FormatActionExecutor_UnexpectedTaskInstance(object p0, object p1)
+ {
+ return string.Format(CultureInfo.CurrentCulture, GetString("ActionExecutor_UnexpectedTaskInstance"), p0, p1);
+ }
+
+ ///
+ /// A claim of type '{0}' was not present on the provided ClaimsIdentity.
+ ///
+ internal static string ClaimUidExtractor_ClaimNotPresent
+ {
+ get { return GetString("ClaimUidExtractor_ClaimNotPresent"); }
+ }
+
+ ///
+ /// A claim of type '{0}' was not present on the provided ClaimsIdentity.
+ ///
+ internal static string FormatClaimUidExtractor_ClaimNotPresent(object p0)
+ {
+ return string.Format(CultureInfo.CurrentCulture, GetString("ClaimUidExtractor_ClaimNotPresent"), p0);
+ }
+
+ ///
+ /// The provided identity of type '{0}' is marked IsAuthenticated = true but does not have a value for Name. By default, the anti-forgery system requires that all authenticated identities have a unique Name. If it is not possible to provide a unique Name for this identity, consider extending IAdditionalDataProvider by overriding the DefaultAdditionalDataProvider or a custom type that can provide some form of unique identifier for the current user.
+ ///
+ internal static string TokenValidator_AuthenticatedUserWithoutUsername
+ {
+ get { return GetString("TokenValidator_AuthenticatedUserWithoutUsername"); }
+ }
+
+ ///
+ /// The provided identity of type '{0}' is marked IsAuthenticated = true but does not have a value for Name. By default, the anti-forgery system requires that all authenticated identities have a unique Name. If it is not possible to provide a unique Name for this identity, consider extending IAdditionalDataProvider by overriding the DefaultAdditionalDataProvider or a custom type that can provide some form of unique identifier for the current user.
+ ///
+ internal static string FormatTokenValidator_AuthenticatedUserWithoutUsername(object p0)
+ {
+ return string.Format(CultureInfo.CurrentCulture, GetString("TokenValidator_AuthenticatedUserWithoutUsername"), p0);
+ }
+
///
/// The class ReflectedActionFilterEndPoint only supports ReflectedActionDescriptors.
///
@@ -475,19 +459,19 @@ namespace Microsoft.AspNet.Mvc.Core
}
///
- /// The '{0}' must return a non-null '{1}'.
+ /// The '{0}' method of type '{1}' cannot return a null value.
///
- internal static string MethodMustReturnNotNullValue
+ internal static string TypeMethodMustReturnNotNullValue
{
- get { return GetString("MethodMustReturnNotNullValue"); }
+ get { return GetString("TypeMethodMustReturnNotNullValue"); }
}
///
- /// The '{0}' must return a non-null '{1}'.
+ /// The '{0}' method of type '{1}' cannot return a null value.
///
- internal static string FormatMethodMustReturnNotNullValue(object p0, object p1)
+ internal static string FormatTypeMethodMustReturnNotNullValue(object p0, object p1)
{
- return string.Format(CultureInfo.CurrentCulture, GetString("MethodMustReturnNotNullValue"), p0, p1);
+ return string.Format(CultureInfo.CurrentCulture, GetString("TypeMethodMustReturnNotNullValue"), p0, p1);
}
///
@@ -922,6 +906,21 @@ namespace Microsoft.AspNet.Mvc.Core
return GetString("HtmlHelper_TextAreaParameterOutOfRange");
}
+ /// The type provided to '{0}' must implement '{1}'.
+ ///
+ internal static string FilterFactoryAttribute_TypeMustImplementIFilter
+ {
+ get { return GetString("FilterFactoryAttribute_TypeMustImplementIFilter"); }
+ }
+
+ ///
+ /// The type provided to '{0}' must implement '{1}'.
+ ///
+ internal static string FormatFilterFactoryAttribute_TypeMustImplementIFilter(object p0, object p1)
+ {
+ return string.Format(CultureInfo.CurrentCulture, GetString("FilterFactoryAttribute_TypeMustImplementIFilter"), p0, p1);
+ }
+
private static string GetString(string name, params string[] formatterNames)
{
var value = _resourceManager.GetString(name);
diff --git a/src/Microsoft.AspNet.Mvc.Core/Resources.resx b/src/Microsoft.AspNet.Mvc.Core/Resources.resx
index 92a8fe7ec4..55b2f2eeb3 100644
--- a/src/Microsoft.AspNet.Mvc.Core/Resources.resx
+++ b/src/Microsoft.AspNet.Mvc.Core/Resources.resx
@@ -150,9 +150,6 @@
The method '{0}' on type '{1}' returned a Task instance even though it is not an asynchronous method.
-
A claim of type '{0}' was not present on the provided ClaimsIdentity.
@@ -204,8 +201,8 @@
The '{0}' property of '{1}' must not be null.
-
- The '{0}' must return a non-null '{1}'.
+
+ The '{0}' method of type '{1}' cannot return a null value.
The supplied route values are ambiguous and can select multiple sets of actions.
@@ -288,4 +285,7 @@
The value must be greater than or equal to zero.
-
\ No newline at end of file
+
+ The type provided to '{0}' must implement '{1}'.
+
+
diff --git a/src/Microsoft.AspNet.Mvc.Razor.Host/Properties/Resources.Designer.cs b/src/Microsoft.AspNet.Mvc.Razor.Host/Properties/Resources.Designer.cs
index 97d038e5a3..7d4618123b 100644
--- a/src/Microsoft.AspNet.Mvc.Razor.Host/Properties/Resources.Designer.cs
+++ b/src/Microsoft.AspNet.Mvc.Razor.Host/Properties/Resources.Designer.cs
@@ -63,7 +63,7 @@ namespace Microsoft.AspNet.Mvc.Razor.Host
var value = _resourceManager.GetString(name);
System.Diagnostics.Debug.Assert(value != null);
-
+
if (formatterNames != null)
{
for (var i = 0; i < formatterNames.Length; i++)
diff --git a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Properties/Resources.Designer.cs b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Properties/Resources.Designer.cs
index a127d68320..35e49f5cc1 100644
--- a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Properties/Resources.Designer.cs
+++ b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Properties/Resources.Designer.cs
@@ -31,7 +31,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
var value = _resourceManager.GetString(name);
System.Diagnostics.Debug.Assert(value != null);
-
+
if (formatterNames != null)
{
for (var i = 0; i < formatterNames.Length; i++)