PageRenderTime 257ms CodeModel.GetById 44ms RepoModel.GetById 12ms app.codeStats 0ms

/src/MvcFutures/Mvc/LinkBuilder.cs

https://bitbucket.org/markhneedham/aspnet-mvc
C# | 65 lines | 44 code | 4 blank | 17 comment | 6 complexity | 070cf15dd2eebde5f9a852255ed13f22 MD5 | raw file
  1. namespace Microsoft.Web.Mvc {
  2. using System;
  3. using System.Linq.Expressions;
  4. using System.Reflection;
  5. using System.Web;
  6. using System.Web.Mvc;
  7. using System.Web.Routing;
  8. using Microsoft.Web.Mvc.Internal;
  9. [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
  10. public static class LinkBuilder {
  11. /// <summary>
  12. /// Builds a URL based on the Expression passed in
  13. /// </summary>
  14. /// <typeparam name="TController">Controller Type Only</typeparam>
  15. /// <param name="context">The current ViewContext</param>
  16. /// <param name="action">The action to invoke</param>
  17. /// <returns></returns>
  18. [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")]
  19. public static string BuildUrlFromExpression<TController>(ViewContext context, RouteCollection routeCollection, Expression<Action<TController>> action) where TController : Controller {
  20. RouteValueDictionary values = ExpressionHelper.GetRouteValuesFromExpression(action);
  21. VirtualPathData vpd = routeCollection.GetVirtualPath(context, values);
  22. return (vpd == null) ? null : vpd.VirtualPath;
  23. }
  24. /// <summary>
  25. /// Creates a querystring as a Dictionary based on the passed-in Lambda
  26. /// </summary>
  27. /// <param name="call">The Lambda of the Controller method</param>
  28. /// <returns></returns>
  29. [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")]
  30. public static RouteValueDictionary BuildParameterValuesFromExpression(MethodCallExpression call) {
  31. RouteValueDictionary result = new RouteValueDictionary();
  32. ParameterInfo[] parameters = call.Method.GetParameters();
  33. if (parameters.Length > 0) {
  34. for (int i = 0; i < parameters.Length; i++) {
  35. Expression arg = call.Arguments[i];
  36. object value;
  37. ConstantExpression ce = arg as ConstantExpression;
  38. if (ce != null) {
  39. // If argument is a constant expression, just get the value
  40. value = ce.Value;
  41. }
  42. else {
  43. // Otherwise, convert the argument subexpression to type object,
  44. // make a lambda out of it, compile it, and invoke it to get the value
  45. var lambda = Expression.Lambda<Func<object>>(Expression.Convert(arg, typeof(object)));
  46. try {
  47. value = lambda.Compile()();
  48. }
  49. catch {
  50. // ?????
  51. value = String.Empty;
  52. }
  53. }
  54. // Code should be added here to appropriately escape the value string
  55. result.Add(parameters[i].Name, value);
  56. }
  57. }
  58. return result;
  59. }
  60. }
  61. }