Fixing WebAPI Issue 151

Topics: ASP.NET Web API
Aug 8, 2012 at 11:02 AM

Hi!

I'm going to solve this issue. Does anybody mind?

 

Regards, Alex

Aug 9, 2012 at 6:50 AM

Sounds great!

Could you describe briefly how you plan to address the issue?

Aug 9, 2012 at 3:20 PM

Alexander,

Great! I have been playing with this as well -- the way I did it was adding a method to the IHttpControllerTypeResolver interface for getting the route name from the controller type:

    /// <summary>
    /// Provides an abstraction for managing the controller types of an application. A different
    /// implementation can be registered via the <see cref="T:System.Web.Http.Services.DependencyResolver"/>.
    /// </summary>
    public interface IHttpControllerTypeResolver
    {
        /// <summary>
        /// Returns a list of controllers available for the application.
        /// </summary>
        /// <returns>An <see cref="ICollection{Type}"/> of controllers.</returns>
        [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "This is better handled as a method.")]
        ICollection<Type> GetControllerTypes(IAssembliesResolver assembliesResolver);

        /// <summary>
        /// Gets the <c>controller</c> route parameter for a given controller <see cref="Type"/>.
        /// </summary>
        /// <param name="controllerType">Type of controller to provide the <c>controller</c> route parameter for.</param>
        /// <returns>A string representing the <c>controller</c> route parameter for this controller type or <c>null</c> 
        /// if <paramref name="controllerType"/> is not a controller.</returns>
        string GetControllerRouteName(Type controllerType);
    }

And then have the places where the mapping is needed call into registered instance:

        IHttpControllerTypeResolver controllersResolver = _configuration.Services.GetHttpControllerTypeResolver();
        string name = controllersResolver.GetControllerRouteName(t);

In DefaultHttpControllerTypeResolver, the implementation of the new method looks something like this:

        /// <summary>
        /// Gets the <c>controller</c> route parameter for a given controller <see cref="Type"/>.
        /// </summary>
        /// <param name="controllerType">Type of controller to provide the <c>controller</c> route parameter for.</param>
        /// <returns>A string representing the <c>controller</c> route parameter for this controller type or <c>null</c> 
        /// if <paramref name="controllerType"/> is not a valid controller name.</returns>
        public virtual string GetControllerRouteName(Type controllerType)
        {
            if (controllerType == null)
            {
                throw Error.ArgumentNull("controllerType");
            }

            if (HasValidControllerName(controllerType))
            {
                string controllerName = controllerType.Name;
                return controllerName.Substring(0, controllerName.Length - _controllerSuffix.Length);
            }
            return null;
        }

        /// <summary>
        /// We match if type name ends with _controllerSuffix and that is not 
        /// the only part of the name. That is, the route name has to be a non-empty
        /// prefix of the controller type name, it can't be just _controllerSuffix.
        /// </summary>
        /// <param name="controllerType">The type name to validate.</param>
        /// <returns>true if controller type has valid controller name; otherwise false.</returns>
        internal static bool HasValidControllerName(Type controllerType)
        {
            Contract.Assert(controllerType != null);
            return controllerType.Name.Length > _controllerSuffix.Length && controllerType.Name.EndsWith(_controllerSuffix, StringComparison.OrdinalIgnoreCase);
        }

How about I commit this to my fork and then you can have a look a that?

Btw, I am incorporating your fix for 150 and will commit soon as well.

Thanks!

Henrik

Aug 10, 2012 at 9:50 PM

Henrik,

actually I've just started fixing this issue. So, please feel free to commit to your fork. I'll have a look there. I'll post a comment and my plan on the weekend.

 

Cheers!

Alex