.Net Core Override Controller Route for Universal Controller

I am writing RestFramework and I am trying to understand how I can allow users to create their own name for a common controller. I register my general controllers as follows:

public class GenericControllerFeatureProvider : IApplicationFeatureProvider<ControllerFeature>
{
    public void PopulateFeature(IEnumerable<ApplicationPart> parts, ControllerFeature feature)
    {
        foreach (var entityConfig in _entityConfigurations)
        {
            var entityType = entityConfig.Type;
            var typeName = entityType.Name + "Controller";
            if (!feature.Controllers.Any(t => t.Name == typeName))
            {
                var controllerType = typeof(GenericController<>)
                    .MakeGenericType(entityType.AsType())
                    .GetTypeInfo();

               //Normally I would expect there to be an overload to configure the controller name
               //feature.Controllers.Add(controllerType, entityConfig.ControllerName);
            }
        }
    }
}

No matter how I want to figure out how I can redefine the route for the controllers. The only information about this in the documentation shows how to create an agreement with the controller as follows:

public class GenericControllerNameConvention : Attribute, IControllerModelConvention
{
    public void Apply(ControllerModel controller)
    {
        if (controller.ControllerType.GetGenericTypeDefinition() != 
        typeof(GenericController<>))
        {
            return;
        }

        var entityType = controller.ControllerType.GenericTypeArguments[0];
        controller.ControllerName = entityType.Name;
    }
}

This will not work as it is executed at compile time. I need the user to be able to override the controller name at startup, how can I do this?

+4
source share
2 answers

, . . , .

, :

public class GenericController<T> : Controller
    where T: class
{

    public IActionResult Get()
    {
        return Content(typeof(T).FullName);
    }
}

Get. . , Feature ( , ):

public class GenericControllerFeatureProvider : IApplicationFeatureProvider<ControllerFeature>
{
    public void PopulateFeature(IEnumerable<ApplicationPart> parts, ControllerFeature feature)
    {
        foreach (var entityConfig in ControllerEntity.EntityTypes)
        {
            var entityType = entityConfig;
            var typeName = entityType.Name + "Controller";
            if (!feature.Controllers.Any(t => t.Name == typeName))
            {
                var controllerType = typeof(GenericController<>)
                    .MakeGenericType(entityType)
                    .GetTypeInfo();

                feature.Controllers.Add(controllerType);
            }
        }
    }
}

IControllerModelConvention.

public class GenericControllerModelConvention : IControllerModelConvention
{
    public void Apply(ControllerModel controller)
    {
        if (!controller.ControllerType.IsGenericType || controller.ControllerType.GetGenericTypeDefinition() != typeof(GenericController<>))
        {
            return;
        }

        var entityType = controller.ControllerType.GenericTypeArguments[0];
        controller.ControllerName = entityType.Name + "Controller";
        controller.RouteValues["Controller"] = entityType.Name;
    }
}

, , . IControllerModelConvention MVC, FeatureProvider.

public void ConfigureServices(IServiceCollection services)
{
    var mvcBuilder = services.AddMvc();
    mvcBuilder.AddMvcOptions(o => o.Conventions.Add(new GenericControllerModelConvention()));
    mvcBuilder.ConfigureApplicationPartManager(c =>
    {
        c.FeatureProviders.Add(new GenericControllerFeatureProvider());
    });
}

.

  • , GenericControllerNameConvention ?
  • Controller Route Value ( + name).

(EntityA EntityB),

/Entitya/get/ WebApplication11.Infrastructure.EntityA

/Entityb/get/ WebApplication11.Infrastructure.EntityB

+3

(/) .

-1

Source: https://habr.com/ru/post/1694891/


All Articles