/src/MvcFutures/Mvc/LinkBuilder.cs
C# | 65 lines | 44 code | 4 blank | 17 comment | 6 complexity | 070cf15dd2eebde5f9a852255ed13f22 MD5 | raw file
- namespace Microsoft.Web.Mvc {
- using System;
- using System.Linq.Expressions;
- using System.Reflection;
- using System.Web;
- using System.Web.Mvc;
- using System.Web.Routing;
- using Microsoft.Web.Mvc.Internal;
-
- [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
- public static class LinkBuilder {
- /// <summary>
- /// Builds a URL based on the Expression passed in
- /// </summary>
- /// <typeparam name="TController">Controller Type Only</typeparam>
- /// <param name="context">The current ViewContext</param>
- /// <param name="action">The action to invoke</param>
- /// <returns></returns>
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1055:UriReturnValuesShouldNotBeStrings", Justification = "The return value is not a regular URL since it may contain ~/ ASP.NET-specific characters"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an Extension Method which allows the user to provide a strongly-typed argument via Expression"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Justification = "Need to be sure the passed-in argument is of type Controller::Action")]
- public static string BuildUrlFromExpression<TController>(ViewContext context, RouteCollection routeCollection, Expression<Action<TController>> action) where TController : Controller {
- RouteValueDictionary values = ExpressionHelper.GetRouteValuesFromExpression(action);
- VirtualPathData vpd = routeCollection.GetVirtualPath(context, values);
- return (vpd == null) ? null : vpd.VirtualPath;
- }
-
- /// <summary>
- /// Creates a querystring as a Dictionary based on the passed-in Lambda
- /// </summary>
- /// <param name="call">The Lambda of the Controller method</param>
- /// <returns></returns>
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Allowing Lambda compilation to fail if it doesn't compile at run time - design-time compilation will not allow for runtime Exception")]
- public static RouteValueDictionary BuildParameterValuesFromExpression(MethodCallExpression call) {
- RouteValueDictionary result = new RouteValueDictionary();
-
- ParameterInfo[] parameters = call.Method.GetParameters();
-
- if (parameters.Length > 0) {
- for (int i = 0; i < parameters.Length; i++) {
- Expression arg = call.Arguments[i];
- object value;
- ConstantExpression ce = arg as ConstantExpression;
- if (ce != null) {
- // If argument is a constant expression, just get the value
- value = ce.Value;
- }
- else {
- // Otherwise, convert the argument subexpression to type object,
- // make a lambda out of it, compile it, and invoke it to get the value
- var lambda = Expression.Lambda<Func<object>>(Expression.Convert(arg, typeof(object)));
- try {
- value = lambda.Compile()();
- }
- catch {
- // ?????
- value = String.Empty;
- }
- }
- // Code should be added here to appropriately escape the value string
- result.Add(parameters[i].Name, value);
- }
- }
- return result;
- }
- }
- }