Imported Upstream version 3.6.0

Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
This commit is contained in:
Jo Shields
2014-08-13 10:39:27 +01:00
commit a575963da9
50588 changed files with 8155799 additions and 0 deletions

View File

@ -0,0 +1,68 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;
using System.Web.Mvc.Properties;
namespace System.Web.Mvc
{
[SuppressMessage("Microsoft.Design", "CA1019:DefineAccessorsForAttributeArguments", Justification = "The accessor is exposed as an ICollection<string>.")]
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public sealed class AcceptVerbsAttribute : ActionMethodSelectorAttribute
{
public AcceptVerbsAttribute(HttpVerbs verbs)
: this(EnumToArray(verbs))
{
}
public AcceptVerbsAttribute(params string[] verbs)
{
if (verbs == null || verbs.Length == 0)
{
throw new ArgumentException(MvcResources.Common_NullOrEmpty, "verbs");
}
Verbs = new ReadOnlyCollection<string>(verbs);
}
public ICollection<string> Verbs { get; private set; }
private static void AddEntryToList(HttpVerbs verbs, HttpVerbs match, List<string> verbList, string entryText)
{
if ((verbs & match) != 0)
{
verbList.Add(entryText);
}
}
internal static string[] EnumToArray(HttpVerbs verbs)
{
List<string> verbList = new List<string>();
AddEntryToList(verbs, HttpVerbs.Get, verbList, "GET");
AddEntryToList(verbs, HttpVerbs.Post, verbList, "POST");
AddEntryToList(verbs, HttpVerbs.Put, verbList, "PUT");
AddEntryToList(verbs, HttpVerbs.Delete, verbList, "DELETE");
AddEntryToList(verbs, HttpVerbs.Head, verbList, "HEAD");
AddEntryToList(verbs, HttpVerbs.Patch, verbList, "PATCH");
AddEntryToList(verbs, HttpVerbs.Options, verbList, "OPTIONS");
return verbList.ToArray();
}
public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo)
{
if (controllerContext == null)
{
throw new ArgumentNullException("controllerContext");
}
string incomingVerb = controllerContext.HttpContext.Request.GetHttpMethodOverride();
return Verbs.Contains(incomingVerb, StringComparer.OrdinalIgnoreCase);
}
}
}

View File

@ -0,0 +1,198 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Web.Mvc.Properties;
namespace System.Web.Mvc
{
public abstract class ActionDescriptor : ICustomAttributeProvider, IUniquelyIdentifiable
{
private static readonly ActionMethodDispatcherCache _staticDispatcherCache = new ActionMethodDispatcherCache();
private static readonly ActionSelector[] _emptySelectors = new ActionSelector[0];
private readonly Lazy<string> _uniqueId;
private ActionMethodDispatcherCache _instanceDispatcherCache;
protected ActionDescriptor()
{
_uniqueId = new Lazy<string>(CreateUniqueId);
}
public abstract string ActionName { get; }
public abstract ControllerDescriptor ControllerDescriptor { get; }
internal ActionMethodDispatcherCache DispatcherCache
{
get
{
if (_instanceDispatcherCache == null)
{
_instanceDispatcherCache = _staticDispatcherCache;
}
return _instanceDispatcherCache;
}
set { _instanceDispatcherCache = value; }
}
[SuppressMessage("Microsoft.Security", "CA2119:SealMethodsThatSatisfyPrivateInterfaces", Justification = "This is overridden elsewhere in System.Web.Mvc")]
public virtual string UniqueId
{
get { return _uniqueId.Value; }
}
private string CreateUniqueId()
{
return DescriptorUtil.CreateUniqueId(GetType(), ControllerDescriptor, ActionName);
}
public abstract object Execute(ControllerContext controllerContext, IDictionary<string, object> parameters);
internal static object ExtractParameterFromDictionary(ParameterInfo parameterInfo, IDictionary<string, object> parameters, MethodInfo methodInfo)
{
object value;
if (!parameters.TryGetValue(parameterInfo.Name, out value))
{
// the key should always be present, even if the parameter value is null
string message = String.Format(CultureInfo.CurrentCulture, MvcResources.ReflectedActionDescriptor_ParameterNotInDictionary,
parameterInfo.Name, parameterInfo.ParameterType, methodInfo, methodInfo.DeclaringType);
throw new ArgumentException(message, "parameters");
}
if (value == null && !TypeHelpers.TypeAllowsNullValue(parameterInfo.ParameterType))
{
// tried to pass a null value for a non-nullable parameter type
string message = String.Format(CultureInfo.CurrentCulture, MvcResources.ReflectedActionDescriptor_ParameterCannotBeNull,
parameterInfo.Name, parameterInfo.ParameterType, methodInfo, methodInfo.DeclaringType);
throw new ArgumentException(message, "parameters");
}
if (value != null && !parameterInfo.ParameterType.IsInstanceOfType(value))
{
// value was supplied but is not of the proper type
string message = String.Format(CultureInfo.CurrentCulture, MvcResources.ReflectedActionDescriptor_ParameterValueHasWrongType,
parameterInfo.Name, methodInfo, methodInfo.DeclaringType, value.GetType(), parameterInfo.ParameterType);
throw new ArgumentException(message, "parameters");
}
return value;
}
internal static object ExtractParameterOrDefaultFromDictionary(ParameterInfo parameterInfo, IDictionary<string, object> parameters)
{
Type parameterType = parameterInfo.ParameterType;
object value;
parameters.TryGetValue(parameterInfo.Name, out value);
// if wrong type, replace with default instance
if (parameterType.IsInstanceOfType(value))
{
return value;
}
else
{
object defaultValue;
if (ParameterInfoUtil.TryGetDefaultValue(parameterInfo, out defaultValue))
{
return defaultValue;
}
else
{
return TypeHelpers.GetDefaultValue(parameterType);
}
}
}
public virtual object[] GetCustomAttributes(bool inherit)
{
return GetCustomAttributes(typeof(object), inherit);
}
public virtual object[] GetCustomAttributes(Type attributeType, bool inherit)
{
if (attributeType == null)
{
throw new ArgumentNullException("attributeType");
}
return (object[])Array.CreateInstance(attributeType, 0);
}
public virtual IEnumerable<FilterAttribute> GetFilterAttributes(bool useCache)
{
return GetCustomAttributes(typeof(FilterAttribute), inherit: true).Cast<FilterAttribute>();
}
[EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete("Please call System.Web.Mvc.FilterProviders.Providers.GetFilters() now.", true)]
public virtual FilterInfo GetFilters()
{
return new FilterInfo();
}
public abstract ParameterDescriptor[] GetParameters();
[SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "This method may perform non-trivial work.")]
public virtual ICollection<ActionSelector> GetSelectors()
{
return _emptySelectors;
}
public virtual bool IsDefined(Type attributeType, bool inherit)
{
if (attributeType == null)
{
throw new ArgumentNullException("attributeType");
}
return false;
}
internal static string VerifyActionMethodIsCallable(MethodInfo methodInfo)
{
// we can't call static methods
if (methodInfo.IsStatic)
{
return String.Format(CultureInfo.CurrentCulture,
MvcResources.ReflectedActionDescriptor_CannotCallStaticMethod,
methodInfo,
methodInfo.ReflectedType.FullName);
}
// we can't call instance methods where the 'this' parameter is a type other than ControllerBase
if (!typeof(ControllerBase).IsAssignableFrom(methodInfo.ReflectedType))
{
return String.Format(CultureInfo.CurrentCulture, MvcResources.ReflectedActionDescriptor_CannotCallInstanceMethodOnNonControllerType,
methodInfo, methodInfo.ReflectedType.FullName);
}
// we can't call methods with open generic type parameters
if (methodInfo.ContainsGenericParameters)
{
return String.Format(CultureInfo.CurrentCulture, MvcResources.ReflectedActionDescriptor_CannotCallOpenGenericMethods,
methodInfo, methodInfo.ReflectedType.FullName);
}
// we can't call methods with ref/out parameters
ParameterInfo[] parameterInfos = methodInfo.GetParameters();
foreach (ParameterInfo parameterInfo in parameterInfos)
{
if (parameterInfo.IsOut || parameterInfo.ParameterType.IsByRef)
{
return String.Format(CultureInfo.CurrentCulture, MvcResources.ReflectedActionDescriptor_CannotCallMethodsWithOutOrRefParameters,
methodInfo, methodInfo.ReflectedType.FullName, parameterInfo);
}
}
// we can call this method
return null;
}
}
}

View File

@ -0,0 +1,48 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Reflection;
namespace System.Web.Mvc
{
internal static class ActionDescriptorHelper
{
public static ICollection<ActionSelector> GetSelectors(MethodInfo methodInfo)
{
ActionMethodSelectorAttribute[] attrs = (ActionMethodSelectorAttribute[])methodInfo.GetCustomAttributes(typeof(ActionMethodSelectorAttribute), inherit: true);
ActionSelector[] selectors = Array.ConvertAll(attrs, attr => (ActionSelector)(controllerContext => attr.IsValidForRequest(controllerContext, methodInfo)));
return selectors;
}
public static bool IsDefined(MemberInfo methodInfo, Type attributeType, bool inherit)
{
return methodInfo.IsDefined(attributeType, inherit);
}
public static object[] GetCustomAttributes(MemberInfo methodInfo, bool inherit)
{
return methodInfo.GetCustomAttributes(inherit);
}
public static object[] GetCustomAttributes(MemberInfo methodInfo, Type attributeType, bool inherit)
{
return methodInfo.GetCustomAttributes(attributeType, inherit);
}
public static ParameterDescriptor[] GetParameters(ActionDescriptor actionDescriptor, MethodInfo methodInfo, ref ParameterDescriptor[] parametersCache)
{
ParameterDescriptor[] parameters = LazilyFetchParametersCollection(actionDescriptor, methodInfo, ref parametersCache);
// need to clone array so that user modifications aren't accidentally stored
return (ParameterDescriptor[])parameters.Clone();
}
private static ParameterDescriptor[] LazilyFetchParametersCollection(ActionDescriptor actionDescriptor, MethodInfo methodInfo, ref ParameterDescriptor[] parametersCache)
{
return DescriptorUtil.LazilyFetchOrCreateDescriptors<ParameterInfo, ParameterDescriptor>(
cacheLocation: ref parametersCache,
initializer: methodInfo.GetParameters,
converter: parameterInfo => new ReflectedParameterDescriptor(parameterInfo, actionDescriptor));
}
}
}

View File

@ -0,0 +1,44 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Diagnostics.CodeAnalysis;
namespace System.Web.Mvc
{
public class ActionExecutedContext : ControllerContext
{
private ActionResult _result;
// parameterless constructor used for mocking
public ActionExecutedContext()
{
}
[SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors", Justification = "The virtual property setters are only to support mocking frameworks, in which case this constructor shouldn't be called anyway.")]
public ActionExecutedContext(ControllerContext controllerContext, ActionDescriptor actionDescriptor, bool canceled, Exception exception)
: base(controllerContext)
{
if (actionDescriptor == null)
{
throw new ArgumentNullException("actionDescriptor");
}
ActionDescriptor = actionDescriptor;
Canceled = canceled;
Exception = exception;
}
public virtual ActionDescriptor ActionDescriptor { get; set; }
public virtual bool Canceled { get; set; }
public virtual Exception Exception { get; set; }
public bool ExceptionHandled { get; set; }
public ActionResult Result
{
get { return _result ?? EmptyResult.Instance; }
set { _result = value; }
}
}
}

View File

@ -0,0 +1,39 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
namespace System.Web.Mvc
{
public class ActionExecutingContext : ControllerContext
{
// parameterless constructor used for mocking
public ActionExecutingContext()
{
}
[SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors", Justification = "The virtual property setters are only to support mocking frameworks, in which case this constructor shouldn't be called anyway.")]
public ActionExecutingContext(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary<string, object> actionParameters)
: base(controllerContext)
{
if (actionDescriptor == null)
{
throw new ArgumentNullException("actionDescriptor");
}
if (actionParameters == null)
{
throw new ArgumentNullException("actionParameters");
}
ActionDescriptor = actionDescriptor;
ActionParameters = actionParameters;
}
public virtual ActionDescriptor ActionDescriptor { get; set; }
[SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "The property setter is only here to support mocking this type and should not be called at runtime.")]
public virtual IDictionary<string, object> ActionParameters { get; set; }
public ActionResult Result { get; set; }
}
}

View File

@ -0,0 +1,27 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
namespace System.Web.Mvc
{
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
public abstract class ActionFilterAttribute : FilterAttribute, IActionFilter, IResultFilter
{
// The OnXxx() methods are virtual rather than abstract so that a developer need override
// only the ones that interest him.
public virtual void OnActionExecuting(ActionExecutingContext filterContext)
{
}
public virtual void OnActionExecuted(ActionExecutedContext filterContext)
{
}
public virtual void OnResultExecuting(ResultExecutingContext filterContext)
{
}
public virtual void OnResultExecuted(ResultExecutedContext filterContext)
{
}
}
}

View File

@ -0,0 +1,81 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;
namespace System.Web.Mvc
{
// The methods in this class don't perform error checking; that is the responsibility of the
// caller.
internal sealed class ActionMethodDispatcher
{
private ActionExecutor _executor;
public ActionMethodDispatcher(MethodInfo methodInfo)
{
_executor = GetExecutor(methodInfo);
MethodInfo = methodInfo;
}
private delegate object ActionExecutor(ControllerBase controller, object[] parameters);
private delegate void VoidActionExecutor(ControllerBase controller, object[] parameters);
public MethodInfo MethodInfo { get; private set; }
public object Execute(ControllerBase controller, object[] parameters)
{
return _executor(controller, parameters);
}
private static ActionExecutor GetExecutor(MethodInfo methodInfo)
{
// Parameters to executor
ParameterExpression controllerParameter = Expression.Parameter(typeof(ControllerBase), "controller");
ParameterExpression parametersParameter = Expression.Parameter(typeof(object[]), "parameters");
// Build parameter list
List<Expression> parameters = new List<Expression>();
ParameterInfo[] paramInfos = methodInfo.GetParameters();
for (int i = 0; i < paramInfos.Length; i++)
{
ParameterInfo paramInfo = paramInfos[i];
BinaryExpression valueObj = Expression.ArrayIndex(parametersParameter, Expression.Constant(i));
UnaryExpression valueCast = Expression.Convert(valueObj, paramInfo.ParameterType);
// valueCast is "(Ti) parameters[i]"
parameters.Add(valueCast);
}
// Call method
UnaryExpression instanceCast = (!methodInfo.IsStatic) ? Expression.Convert(controllerParameter, methodInfo.ReflectedType) : null;
MethodCallExpression methodCall = methodCall = Expression.Call(instanceCast, methodInfo, parameters);
// methodCall is "((TController) controller) method((T0) parameters[0], (T1) parameters[1], ...)"
// Create function
if (methodCall.Type == typeof(void))
{
Expression<VoidActionExecutor> lambda = Expression.Lambda<VoidActionExecutor>(methodCall, controllerParameter, parametersParameter);
VoidActionExecutor voidExecutor = lambda.Compile();
return WrapVoidAction(voidExecutor);
}
else
{
// must coerce methodCall to match ActionExecutor signature
UnaryExpression castMethodCall = Expression.Convert(methodCall, typeof(object));
Expression<ActionExecutor> lambda = Expression.Lambda<ActionExecutor>(castMethodCall, controllerParameter, parametersParameter);
return lambda.Compile();
}
}
private static ActionExecutor WrapVoidAction(VoidActionExecutor executor)
{
return delegate(ControllerBase controller, object[] parameters)
{
executor(controller, parameters);
return null;
};
}
}
}

View File

@ -0,0 +1,18 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Reflection;
namespace System.Web.Mvc
{
internal sealed class ActionMethodDispatcherCache : ReaderWriterCache<MethodInfo, ActionMethodDispatcher>
{
public ActionMethodDispatcherCache()
{
}
public ActionMethodDispatcher GetDispatcher(MethodInfo methodInfo)
{
return FetchOrCreateItem(methodInfo, () => new ActionMethodDispatcher(methodInfo));
}
}
}

View File

@ -0,0 +1,118 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Web.Mvc.Properties;
namespace System.Web.Mvc
{
internal sealed class ActionMethodSelector
{
public ActionMethodSelector(Type controllerType)
{
ControllerType = controllerType;
PopulateLookupTables();
}
public Type ControllerType { get; private set; }
public MethodInfo[] AliasedMethods { get; private set; }
public ILookup<string, MethodInfo> NonAliasedMethods { get; private set; }
private AmbiguousMatchException CreateAmbiguousMatchException(List<MethodInfo> ambiguousMethods, string actionName)
{
StringBuilder exceptionMessageBuilder = new StringBuilder();
foreach (MethodInfo methodInfo in ambiguousMethods)
{
string controllerAction = Convert.ToString(methodInfo, CultureInfo.CurrentCulture);
string controllerType = methodInfo.DeclaringType.FullName;
exceptionMessageBuilder.AppendLine();
exceptionMessageBuilder.AppendFormat(CultureInfo.CurrentCulture, MvcResources.ActionMethodSelector_AmbiguousMatchType, controllerAction, controllerType);
}
string message = String.Format(CultureInfo.CurrentCulture, MvcResources.ActionMethodSelector_AmbiguousMatch,
actionName, ControllerType.Name, exceptionMessageBuilder);
return new AmbiguousMatchException(message);
}
public MethodInfo FindActionMethod(ControllerContext controllerContext, string actionName)
{
List<MethodInfo> methodsMatchingName = GetMatchingAliasedMethods(controllerContext, actionName);
methodsMatchingName.AddRange(NonAliasedMethods[actionName]);
List<MethodInfo> finalMethods = RunSelectionFilters(controllerContext, methodsMatchingName);
switch (finalMethods.Count)
{
case 0:
return null;
case 1:
return finalMethods[0];
default:
throw CreateAmbiguousMatchException(finalMethods, actionName);
}
}
internal List<MethodInfo> GetMatchingAliasedMethods(ControllerContext controllerContext, string actionName)
{
// find all aliased methods which are opting in to this request
// to opt in, all attributes defined on the method must return true
var methods = from methodInfo in AliasedMethods
let attrs = ReflectedAttributeCache.GetActionNameSelectorAttributes(methodInfo)
where attrs.All(attr => attr.IsValidName(controllerContext, actionName, methodInfo))
select methodInfo;
return methods.ToList();
}
private static bool IsMethodDecoratedWithAliasingAttribute(MethodInfo methodInfo)
{
return methodInfo.IsDefined(typeof(ActionNameSelectorAttribute), true /* inherit */);
}
private static bool IsValidActionMethod(MethodInfo methodInfo)
{
return !(methodInfo.IsSpecialName ||
methodInfo.GetBaseDefinition().DeclaringType.IsAssignableFrom(typeof(Controller)));
}
private void PopulateLookupTables()
{
MethodInfo[] allMethods = ControllerType.GetMethods(BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Public);
MethodInfo[] actionMethods = Array.FindAll(allMethods, IsValidActionMethod);
AliasedMethods = Array.FindAll(actionMethods, IsMethodDecoratedWithAliasingAttribute);
NonAliasedMethods = actionMethods.Except(AliasedMethods).ToLookup(method => method.Name, StringComparer.OrdinalIgnoreCase);
}
private static List<MethodInfo> RunSelectionFilters(ControllerContext controllerContext, List<MethodInfo> methodInfos)
{
// remove all methods which are opting out of this request
// to opt out, at least one attribute defined on the method must return false
List<MethodInfo> matchesWithSelectionAttributes = new List<MethodInfo>();
List<MethodInfo> matchesWithoutSelectionAttributes = new List<MethodInfo>();
foreach (MethodInfo methodInfo in methodInfos)
{
ICollection<ActionMethodSelectorAttribute> attrs = ReflectedAttributeCache.GetActionMethodSelectorAttributes(methodInfo);
if (attrs.Count == 0)
{
matchesWithoutSelectionAttributes.Add(methodInfo);
}
else if (attrs.All(attr => attr.IsValidForRequest(controllerContext, methodInfo)))
{
matchesWithSelectionAttributes.Add(methodInfo);
}
}
// if a matching action method had a selection attribute, consider it more specific than a matching action method
// without a selection attribute
return (matchesWithSelectionAttributes.Count > 0) ? matchesWithSelectionAttributes : matchesWithoutSelectionAttributes;
}
}
}

View File

@ -0,0 +1,12 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Reflection;
namespace System.Web.Mvc
{
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public abstract class ActionMethodSelectorAttribute : Attribute
{
public abstract bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo);
}
}

View File

@ -0,0 +1,28 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Reflection;
using System.Web.Mvc.Properties;
namespace System.Web.Mvc
{
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public sealed class ActionNameAttribute : ActionNameSelectorAttribute
{
public ActionNameAttribute(string name)
{
if (String.IsNullOrEmpty(name))
{
throw new ArgumentException(MvcResources.Common_NullOrEmpty, "name");
}
Name = name;
}
public string Name { get; private set; }
public override bool IsValidName(ControllerContext controllerContext, string actionName, MethodInfo methodInfo)
{
return String.Equals(actionName, Name, StringComparison.OrdinalIgnoreCase);
}
}
}

View File

@ -0,0 +1,12 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Reflection;
namespace System.Web.Mvc
{
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public abstract class ActionNameSelectorAttribute : Attribute
{
public abstract bool IsValidName(ControllerContext controllerContext, string actionName, MethodInfo methodInfo);
}
}

View File

@ -0,0 +1,9 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
namespace System.Web.Mvc
{
public abstract class ActionResult
{
public abstract void ExecuteResult(ControllerContext context);
}
}

View File

@ -0,0 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
namespace System.Web.Mvc
{
public delegate bool ActionSelector(ControllerContext controllerContext);
}

View File

@ -0,0 +1,40 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
namespace System.Web.Mvc
{
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Property, AllowMultiple = true)]
public sealed class AdditionalMetadataAttribute : Attribute, IMetadataAware
{
private object _typeId = new object();
public AdditionalMetadataAttribute(string name, object value)
{
if (name == null)
{
throw new ArgumentNullException("name");
}
Name = name;
Value = value;
}
public override object TypeId
{
get { return _typeId; }
}
public string Name { get; private set; }
public object Value { get; private set; }
public void OnMetadataCreated(ModelMetadata metadata)
{
if (metadata == null)
{
throw new ArgumentNullException("metadata");
}
metadata.AdditionalValues[Name] = Value;
}
}
}

View File

@ -0,0 +1,360 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Web.Mvc.Html;
using System.Web.Mvc.Properties;
using System.Web.Routing;
namespace System.Web.Mvc.Ajax
{
public static class AjaxExtensions
{
private const string LinkOnClickFormat = "Sys.Mvc.AsyncHyperlink.handleClick(this, new Sys.UI.DomEvent(event), {0});";
private const string FormOnClickValue = "Sys.Mvc.AsyncForm.handleClick(this, new Sys.UI.DomEvent(event));";
private const string FormOnSubmitFormat = "Sys.Mvc.AsyncForm.handleSubmit(this, new Sys.UI.DomEvent(event), {0});";
public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, AjaxOptions ajaxOptions)
{
return ActionLink(ajaxHelper, linkText, actionName, (string)null /* controllerName */, ajaxOptions);
}
public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, object routeValues, AjaxOptions ajaxOptions)
{
return ActionLink(ajaxHelper, linkText, actionName, (string)null /* controllerName */, routeValues, ajaxOptions);
}
public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, object routeValues, AjaxOptions ajaxOptions, object htmlAttributes)
{
return ActionLink(ajaxHelper, linkText, actionName, (string)null /* controllerName */, routeValues, ajaxOptions, htmlAttributes);
}
public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions)
{
return ActionLink(ajaxHelper, linkText, actionName, (string)null /* controllerName */, routeValues, ajaxOptions);
}
public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions, IDictionary<string, object> htmlAttributes)
{
return ActionLink(ajaxHelper, linkText, actionName, (string)null /* controllerName */, routeValues, ajaxOptions, htmlAttributes);
}
public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, string controllerName, AjaxOptions ajaxOptions)
{
return ActionLink(ajaxHelper, linkText, actionName, controllerName, null /* values */, ajaxOptions, null /* htmlAttributes */);
}
public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, string controllerName, object routeValues, AjaxOptions ajaxOptions)
{
return ActionLink(ajaxHelper, linkText, actionName, controllerName, routeValues, ajaxOptions, null /* htmlAttributes */);
}
public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, string controllerName, object routeValues, AjaxOptions ajaxOptions, object htmlAttributes)
{
RouteValueDictionary newValues = new RouteValueDictionary(routeValues);
RouteValueDictionary newAttributes = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
return ActionLink(ajaxHelper, linkText, actionName, controllerName, newValues, ajaxOptions, newAttributes);
}
public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, string controllerName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions)
{
return ActionLink(ajaxHelper, linkText, actionName, controllerName, routeValues, ajaxOptions, null /* htmlAttributes */);
}
public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, string controllerName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions, IDictionary<string, object> htmlAttributes)
{
if (String.IsNullOrEmpty(linkText))
{
throw new ArgumentException(MvcResources.Common_NullOrEmpty, "linkText");
}
string targetUrl = UrlHelper.GenerateUrl(null, actionName, controllerName, routeValues, ajaxHelper.RouteCollection, ajaxHelper.ViewContext.RequestContext, true /* includeImplicitMvcValues */);
return MvcHtmlString.Create(GenerateLink(ajaxHelper, linkText, targetUrl, GetAjaxOptions(ajaxOptions), htmlAttributes));
}
public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, string controllerName, string protocol, string hostName, string fragment, object routeValues, AjaxOptions ajaxOptions, object htmlAttributes)
{
RouteValueDictionary newValues = new RouteValueDictionary(routeValues);
RouteValueDictionary newAttributes = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
return ActionLink(ajaxHelper, linkText, actionName, controllerName, protocol, hostName, fragment, newValues, ajaxOptions, newAttributes);
}
public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, string controllerName, string protocol, string hostName, string fragment, RouteValueDictionary routeValues, AjaxOptions ajaxOptions, IDictionary<string, object> htmlAttributes)
{
if (String.IsNullOrEmpty(linkText))
{
throw new ArgumentException(MvcResources.Common_NullOrEmpty, "linkText");
}
string targetUrl = UrlHelper.GenerateUrl(null /* routeName */, actionName, controllerName, protocol, hostName, fragment, routeValues, ajaxHelper.RouteCollection, ajaxHelper.ViewContext.RequestContext, true /* includeImplicitMvcValues */);
return MvcHtmlString.Create(GenerateLink(ajaxHelper, linkText, targetUrl, ajaxOptions, htmlAttributes));
}
public static MvcForm BeginForm(this AjaxHelper ajaxHelper, AjaxOptions ajaxOptions)
{
string formAction = ajaxHelper.ViewContext.HttpContext.Request.RawUrl;
return FormHelper(ajaxHelper, formAction, ajaxOptions, new RouteValueDictionary());
}
public static MvcForm BeginForm(this AjaxHelper ajaxHelper, string actionName, AjaxOptions ajaxOptions)
{
return BeginForm(ajaxHelper, actionName, (string)null /* controllerName */, ajaxOptions);
}
public static MvcForm BeginForm(this AjaxHelper ajaxHelper, string actionName, object routeValues, AjaxOptions ajaxOptions)
{
return BeginForm(ajaxHelper, actionName, (string)null /* controllerName */, routeValues, ajaxOptions);
}
public static MvcForm BeginForm(this AjaxHelper ajaxHelper, string actionName, object routeValues, AjaxOptions ajaxOptions, object htmlAttributes)
{
return BeginForm(ajaxHelper, actionName, (string)null /* controllerName */, routeValues, ajaxOptions, htmlAttributes);
}
public static MvcForm BeginForm(this AjaxHelper ajaxHelper, string actionName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions)
{
return BeginForm(ajaxHelper, actionName, (string)null /* controllerName */, routeValues, ajaxOptions);
}
public static MvcForm BeginForm(this AjaxHelper ajaxHelper, string actionName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions, IDictionary<string, object> htmlAttributes)
{
return BeginForm(ajaxHelper, actionName, (string)null /* controllerName */, routeValues, ajaxOptions, htmlAttributes);
}
public static MvcForm BeginForm(this AjaxHelper ajaxHelper, string actionName, string controllerName, AjaxOptions ajaxOptions)
{
return BeginForm(ajaxHelper, actionName, controllerName, null /* values */, ajaxOptions, null /* htmlAttributes */);
}
public static MvcForm BeginForm(this AjaxHelper ajaxHelper, string actionName, string controllerName, object routeValues, AjaxOptions ajaxOptions)
{
return BeginForm(ajaxHelper, actionName, controllerName, routeValues, ajaxOptions, null /* htmlAttributes */);
}
public static MvcForm BeginForm(this AjaxHelper ajaxHelper, string actionName, string controllerName, object routeValues, AjaxOptions ajaxOptions, object htmlAttributes)
{
RouteValueDictionary newValues = new RouteValueDictionary(routeValues);
RouteValueDictionary newAttributes = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
return BeginForm(ajaxHelper, actionName, controllerName, newValues, ajaxOptions, newAttributes);
}
public static MvcForm BeginForm(this AjaxHelper ajaxHelper, string actionName, string controllerName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions)
{
return BeginForm(ajaxHelper, actionName, controllerName, routeValues, ajaxOptions, null /* htmlAttributes */);
}
public static MvcForm BeginForm(this AjaxHelper ajaxHelper, string actionName, string controllerName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions, IDictionary<string, object> htmlAttributes)
{
// get target URL
string formAction = UrlHelper.GenerateUrl(null, actionName, controllerName, routeValues ?? new RouteValueDictionary(), ajaxHelper.RouteCollection, ajaxHelper.ViewContext.RequestContext, true /* includeImplicitMvcValues */);
return FormHelper(ajaxHelper, formAction, ajaxOptions, htmlAttributes);
}
public static MvcForm BeginRouteForm(this AjaxHelper ajaxHelper, string routeName, AjaxOptions ajaxOptions)
{
return BeginRouteForm(ajaxHelper, routeName, null /* routeValues */, ajaxOptions, null /* htmlAttributes */);
}
public static MvcForm BeginRouteForm(this AjaxHelper ajaxHelper, string routeName, object routeValues, AjaxOptions ajaxOptions)
{
return BeginRouteForm(ajaxHelper, routeName, (object)routeValues, ajaxOptions, null /* htmlAttributes */);
}
public static MvcForm BeginRouteForm(this AjaxHelper ajaxHelper, string routeName, object routeValues, AjaxOptions ajaxOptions, object htmlAttributes)
{
RouteValueDictionary newAttributes = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
return BeginRouteForm(ajaxHelper, routeName, new RouteValueDictionary(routeValues), ajaxOptions, newAttributes);
}
public static MvcForm BeginRouteForm(this AjaxHelper ajaxHelper, string routeName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions)
{
return BeginRouteForm(ajaxHelper, routeName, routeValues, ajaxOptions, null /* htmlAttributes */);
}
public static MvcForm BeginRouteForm(this AjaxHelper ajaxHelper, string routeName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions, IDictionary<string, object> htmlAttributes)
{
string formAction = UrlHelper.GenerateUrl(routeName, null /* actionName */, null /* controllerName */, routeValues ?? new RouteValueDictionary(), ajaxHelper.RouteCollection, ajaxHelper.ViewContext.RequestContext, false /* includeImplicitMvcValues */);
return FormHelper(ajaxHelper, formAction, ajaxOptions, htmlAttributes);
}
[SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "You don't want to dispose of this object unless you intend to write to the response")]
private static MvcForm FormHelper(this AjaxHelper ajaxHelper, string formAction, AjaxOptions ajaxOptions, IDictionary<string, object> htmlAttributes)
{
TagBuilder builder = new TagBuilder("form");
builder.MergeAttributes(htmlAttributes);
builder.MergeAttribute("action", formAction);
builder.MergeAttribute("method", "post");
ajaxOptions = GetAjaxOptions(ajaxOptions);
if (ajaxHelper.ViewContext.UnobtrusiveJavaScriptEnabled)
{
builder.MergeAttributes(ajaxOptions.ToUnobtrusiveHtmlAttributes());
}
else
{
builder.MergeAttribute("onclick", FormOnClickValue);
builder.MergeAttribute("onsubmit", GenerateAjaxScript(ajaxOptions, FormOnSubmitFormat));
}
if (ajaxHelper.ViewContext.ClientValidationEnabled)
{
// forms must have an ID for client validation
builder.GenerateId(ajaxHelper.ViewContext.FormIdGenerator());
}
ajaxHelper.ViewContext.Writer.Write(builder.ToString(TagRenderMode.StartTag));
MvcForm theForm = new MvcForm(ajaxHelper.ViewContext);
if (ajaxHelper.ViewContext.ClientValidationEnabled)
{
ajaxHelper.ViewContext.FormContext.FormId = builder.Attributes["id"];
}
return theForm;
}
public static MvcHtmlString GlobalizationScript(this AjaxHelper ajaxHelper)
{
return GlobalizationScript(ajaxHelper, CultureInfo.CurrentCulture);
}
[SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "ajaxHelper", Justification = "This is an extension method")]
public static MvcHtmlString GlobalizationScript(this AjaxHelper ajaxHelper, CultureInfo cultureInfo)
{
return GlobalizationScriptHelper(AjaxHelper.GlobalizationScriptPath, cultureInfo);
}
internal static MvcHtmlString GlobalizationScriptHelper(string scriptPath, CultureInfo cultureInfo)
{
if (cultureInfo == null)
{
throw new ArgumentNullException("cultureInfo");
}
TagBuilder tagBuilder = new TagBuilder("script");
tagBuilder.MergeAttribute("type", "text/javascript");
string src = VirtualPathUtility.AppendTrailingSlash(scriptPath) + HttpUtility.UrlEncode(cultureInfo.Name) + ".js";
tagBuilder.MergeAttribute("src", src);
return tagBuilder.ToMvcHtmlString(TagRenderMode.Normal);
}
public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, object routeValues, AjaxOptions ajaxOptions)
{
return RouteLink(ajaxHelper, linkText, null /* routeName */, new RouteValueDictionary(routeValues), ajaxOptions,
new Dictionary<string, object>());
}
public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, object routeValues, AjaxOptions ajaxOptions, object htmlAttributes)
{
return RouteLink(ajaxHelper, linkText, null /* routeName */, new RouteValueDictionary(routeValues), ajaxOptions,
HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
}
public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, RouteValueDictionary routeValues, AjaxOptions ajaxOptions)
{
return RouteLink(ajaxHelper, linkText, null /* routeName */, routeValues, ajaxOptions,
new Dictionary<string, object>());
}
public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, RouteValueDictionary routeValues, AjaxOptions ajaxOptions, IDictionary<string, object> htmlAttributes)
{
return RouteLink(ajaxHelper, linkText, null /* routeName */, routeValues, ajaxOptions, htmlAttributes);
}
public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, string routeName, AjaxOptions ajaxOptions)
{
return RouteLink(ajaxHelper, linkText, routeName, new RouteValueDictionary(), ajaxOptions,
new Dictionary<string, object>());
}
public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, string routeName, AjaxOptions ajaxOptions, object htmlAttributes)
{
return RouteLink(ajaxHelper, linkText, routeName, new RouteValueDictionary(), ajaxOptions, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
}
public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, string routeName, AjaxOptions ajaxOptions, IDictionary<string, object> htmlAttributes)
{
return RouteLink(ajaxHelper, linkText, routeName, new RouteValueDictionary(), ajaxOptions, htmlAttributes);
}
public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, string routeName, object routeValues, AjaxOptions ajaxOptions)
{
return RouteLink(ajaxHelper, linkText, routeName, new RouteValueDictionary(routeValues), ajaxOptions,
new Dictionary<string, object>());
}
public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, string routeName, object routeValues, AjaxOptions ajaxOptions, object htmlAttributes)
{
return RouteLink(ajaxHelper, linkText, routeName, new RouteValueDictionary(routeValues), ajaxOptions,
HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
}
public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, string routeName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions)
{
return RouteLink(ajaxHelper, linkText, routeName, routeValues, ajaxOptions, new Dictionary<string, object>());
}
public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, string routeName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions, IDictionary<string, object> htmlAttributes)
{
if (String.IsNullOrEmpty(linkText))
{
throw new ArgumentException(MvcResources.Common_NullOrEmpty, "linkText");
}
string targetUrl = UrlHelper.GenerateUrl(routeName, null /* actionName */, null /* controllerName */, routeValues ?? new RouteValueDictionary(), ajaxHelper.RouteCollection, ajaxHelper.ViewContext.RequestContext, false /* includeImplicitMvcValues */);
return MvcHtmlString.Create(GenerateLink(ajaxHelper, linkText, targetUrl, GetAjaxOptions(ajaxOptions), htmlAttributes));
}
public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, string routeName, string protocol, string hostName, string fragment, RouteValueDictionary routeValues, AjaxOptions ajaxOptions, IDictionary<string, object> htmlAttributes)
{
if (String.IsNullOrEmpty(linkText))
{
throw new ArgumentException(MvcResources.Common_NullOrEmpty, "linkText");
}
string targetUrl = UrlHelper.GenerateUrl(routeName, null /* actionName */, null /* controllerName */, protocol, hostName, fragment, routeValues ?? new RouteValueDictionary(), ajaxHelper.RouteCollection, ajaxHelper.ViewContext.RequestContext, false /* includeImplicitMvcValues */);
return MvcHtmlString.Create(GenerateLink(ajaxHelper, linkText, targetUrl, GetAjaxOptions(ajaxOptions), htmlAttributes));
}
private static string GenerateLink(AjaxHelper ajaxHelper, string linkText, string targetUrl, AjaxOptions ajaxOptions, IDictionary<string, object> htmlAttributes)
{
TagBuilder tag = new TagBuilder("a")
{
InnerHtml = HttpUtility.HtmlEncode(linkText)
};
tag.MergeAttributes(htmlAttributes);
tag.MergeAttribute("href", targetUrl);
if (ajaxHelper.ViewContext.UnobtrusiveJavaScriptEnabled)
{
tag.MergeAttributes(ajaxOptions.ToUnobtrusiveHtmlAttributes());
}
else
{
tag.MergeAttribute("onclick", GenerateAjaxScript(ajaxOptions, LinkOnClickFormat));
}
return tag.ToString(TagRenderMode.Normal);
}
private static string GenerateAjaxScript(AjaxOptions ajaxOptions, string scriptFormat)
{
string optionsString = ajaxOptions.ToJavascriptString();
return String.Format(CultureInfo.InvariantCulture, scriptFormat, optionsString);
}
private static AjaxOptions GetAjaxOptions(AjaxOptions ajaxOptions)
{
return (ajaxOptions != null) ? ajaxOptions : new AjaxOptions();
}
}
}

View File

@ -0,0 +1,218 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Text;
namespace System.Web.Mvc.Ajax
{
public class AjaxOptions
{
private string _confirm;
private string _httpMethod;
private InsertionMode _insertionMode = InsertionMode.Replace;
private string _loadingElementId;
private string _onBegin;
private string _onComplete;
private string _onFailure;
private string _onSuccess;
private string _updateTargetId;
private string _url;
public string Confirm
{
get { return _confirm ?? String.Empty; }
set { _confirm = value; }
}
public string HttpMethod
{
get { return _httpMethod ?? String.Empty; }
set { _httpMethod = value; }
}
public InsertionMode InsertionMode
{
get { return _insertionMode; }
set
{
switch (value)
{
case InsertionMode.Replace:
case InsertionMode.InsertAfter:
case InsertionMode.InsertBefore:
_insertionMode = value;
return;
default:
throw new ArgumentOutOfRangeException("value");
}
}
}
internal string InsertionModeString
{
get
{
switch (InsertionMode)
{
case InsertionMode.Replace:
return "Sys.Mvc.InsertionMode.replace";
case InsertionMode.InsertBefore:
return "Sys.Mvc.InsertionMode.insertBefore";
case InsertionMode.InsertAfter:
return "Sys.Mvc.InsertionMode.insertAfter";
default:
return ((int)InsertionMode).ToString(CultureInfo.InvariantCulture);
}
}
}
internal string InsertionModeUnobtrusive
{
get
{
switch (InsertionMode)
{
case InsertionMode.Replace:
return "replace";
case InsertionMode.InsertBefore:
return "before";
case InsertionMode.InsertAfter:
return "after";
default:
return ((int)InsertionMode).ToString(CultureInfo.InvariantCulture);
}
}
}
public int LoadingElementDuration { get; set; }
public string LoadingElementId
{
get { return _loadingElementId ?? String.Empty; }
set { _loadingElementId = value; }
}
public string OnBegin
{
get { return _onBegin ?? String.Empty; }
set { _onBegin = value; }
}
public string OnComplete
{
get { return _onComplete ?? String.Empty; }
set { _onComplete = value; }
}
public string OnFailure
{
get { return _onFailure ?? String.Empty; }
set { _onFailure = value; }
}
public string OnSuccess
{
get { return _onSuccess ?? String.Empty; }
set { _onSuccess = value; }
}
public string UpdateTargetId
{
get { return _updateTargetId ?? String.Empty; }
set { _updateTargetId = value; }
}
[SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings", Justification = "This property is used by the optionsBuilder which always accepts a string.")]
public string Url
{
get { return _url ?? String.Empty; }
set { _url = value; }
}
internal string ToJavascriptString()
{
// creates a string of the form { key1: value1, key2 : value2, ... }
StringBuilder optionsBuilder = new StringBuilder("{");
optionsBuilder.Append(String.Format(CultureInfo.InvariantCulture, " insertionMode: {0},", InsertionModeString));
optionsBuilder.Append(PropertyStringIfSpecified("confirm", Confirm));
optionsBuilder.Append(PropertyStringIfSpecified("httpMethod", HttpMethod));
optionsBuilder.Append(PropertyStringIfSpecified("loadingElementId", LoadingElementId));
optionsBuilder.Append(PropertyStringIfSpecified("updateTargetId", UpdateTargetId));
optionsBuilder.Append(PropertyStringIfSpecified("url", Url));
optionsBuilder.Append(EventStringIfSpecified("onBegin", OnBegin));
optionsBuilder.Append(EventStringIfSpecified("onComplete", OnComplete));
optionsBuilder.Append(EventStringIfSpecified("onFailure", OnFailure));
optionsBuilder.Append(EventStringIfSpecified("onSuccess", OnSuccess));
optionsBuilder.Length--;
optionsBuilder.Append(" }");
return optionsBuilder.ToString();
}
public IDictionary<string, object> ToUnobtrusiveHtmlAttributes()
{
var result = new Dictionary<string, object>
{
{ "data-ajax", "true" },
};
AddToDictionaryIfSpecified(result, "data-ajax-url", Url);
AddToDictionaryIfSpecified(result, "data-ajax-method", HttpMethod);
AddToDictionaryIfSpecified(result, "data-ajax-confirm", Confirm);
AddToDictionaryIfSpecified(result, "data-ajax-begin", OnBegin);
AddToDictionaryIfSpecified(result, "data-ajax-complete", OnComplete);
AddToDictionaryIfSpecified(result, "data-ajax-failure", OnFailure);
AddToDictionaryIfSpecified(result, "data-ajax-success", OnSuccess);
if (!String.IsNullOrWhiteSpace(LoadingElementId))
{
result.Add("data-ajax-loading", "#" + LoadingElementId);
if (LoadingElementDuration > 0)
{
result.Add("data-ajax-loading-duration", LoadingElementDuration);
}
}
if (!String.IsNullOrWhiteSpace(UpdateTargetId))
{
result.Add("data-ajax-update", "#" + UpdateTargetId);
result.Add("data-ajax-mode", InsertionModeUnobtrusive);
}
return result;
}
// Helpers
private static void AddToDictionaryIfSpecified(IDictionary<string, object> dictionary, string name, string value)
{
if (!String.IsNullOrWhiteSpace(value))
{
dictionary.Add(name, value);
}
}
private static string EventStringIfSpecified(string propertyName, string handler)
{
if (!String.IsNullOrEmpty(handler))
{
return String.Format(CultureInfo.InvariantCulture, " {0}: Function.createDelegate(this, {1}),", propertyName, handler.ToString());
}
return String.Empty;
}
private static string PropertyStringIfSpecified(string propertyName, string propertyValue)
{
if (!String.IsNullOrEmpty(propertyValue))
{
string escapedPropertyValue = propertyValue.Replace("'", @"\'");
return String.Format(CultureInfo.InvariantCulture, " {0}: '{1}',", propertyName, escapedPropertyValue);
}
return String.Empty;
}
}
}

View File

@ -0,0 +1,11 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
namespace System.Web.Mvc.Ajax
{
public enum InsertionMode
{
Replace = 0,
InsertBefore = 1,
InsertAfter = 2
}
}

View File

@ -0,0 +1,85 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Diagnostics.CodeAnalysis;
using System.Web.Routing;
namespace System.Web.Mvc
{
public class AjaxHelper
{
private static string _globalizationScriptPath;
private DynamicViewDataDictionary _dynamicViewDataDictionary;
public AjaxHelper(ViewContext viewContext, IViewDataContainer viewDataContainer)
: this(viewContext, viewDataContainer, RouteTable.Routes)
{
}
public AjaxHelper(ViewContext viewContext, IViewDataContainer viewDataContainer, RouteCollection routeCollection)
{
if (viewContext == null)
{
throw new ArgumentNullException("viewContext");
}
if (viewDataContainer == null)
{
throw new ArgumentNullException("viewDataContainer");
}
if (routeCollection == null)
{
throw new ArgumentNullException("routeCollection");
}
ViewContext = viewContext;
ViewDataContainer = viewDataContainer;
RouteCollection = routeCollection;
}
public static string GlobalizationScriptPath
{
get
{
if (String.IsNullOrEmpty(_globalizationScriptPath))
{
_globalizationScriptPath = "~/Scripts/Globalization";
}
return _globalizationScriptPath;
}
set { _globalizationScriptPath = value; }
}
public RouteCollection RouteCollection { get; private set; }
public dynamic ViewBag
{
get
{
if (_dynamicViewDataDictionary == null)
{
_dynamicViewDataDictionary = new DynamicViewDataDictionary(() => ViewData);
}
return _dynamicViewDataDictionary;
}
}
public ViewContext ViewContext { get; private set; }
public ViewDataDictionary ViewData
{
get { return ViewDataContainer.ViewData; }
}
public IViewDataContainer ViewDataContainer { get; internal set; }
[SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "Instance method for consistency with other helpers.")]
public string JavaScriptStringEncode(string message)
{
if (String.IsNullOrEmpty(message))
{
return message;
}
return HttpUtility.JavaScriptStringEncode(message);
}
}
}

View File

@ -0,0 +1,41 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Web.Routing;
namespace System.Web.Mvc
{
public class AjaxHelper<TModel> : AjaxHelper
{
private DynamicViewDataDictionary _dynamicViewDataDictionary;
private ViewDataDictionary<TModel> _viewData;
public AjaxHelper(ViewContext viewContext, IViewDataContainer viewDataContainer)
: this(viewContext, viewDataContainer, RouteTable.Routes)
{
}
public AjaxHelper(ViewContext viewContext, IViewDataContainer viewDataContainer, RouteCollection routeCollection)
: base(viewContext, viewDataContainer, routeCollection)
{
_viewData = new ViewDataDictionary<TModel>(viewDataContainer.ViewData);
}
public new dynamic ViewBag
{
get
{
if (_dynamicViewDataDictionary == null)
{
_dynamicViewDataDictionary = new DynamicViewDataDictionary(() => ViewData);
}
return _dynamicViewDataDictionary;
}
}
public new ViewDataDictionary<TModel> ViewData
{
get { return _viewData; }
}
}
}

Some files were not shown because too many files have changed in this diff Show More