Skip to content

Adding ApiVersioning causes RouteData to be cleared in HttpContext's IRoutingFeature #176

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
maciejjarzynski opened this issue Aug 29, 2017 · 1 comment · Fixed by #178
Closed
Assignees

Comments

@maciejjarzynski
Copy link

maciejjarzynski commented Aug 29, 2017

Bug occured after the migration to .NET Core 2.0 / ASP .NET Core 2.0.

Adding ApiVersioning with the method

 services.AddApiVersioning(o =>
            {
                o.AssumeDefaultVersionWhenUnspecified = true;
                o.DefaultApiVersion = new ApiVersion(1, 0);
            });

causes RouteData to be removed from HttpContext's IRoutingFeature (taken by HttpContext.GetRouteData())
The RouteData still exists in ControllerContext/ActionContext though.

Reproduction:

 public class Startup
{
	public Startup(IHostingEnvironment env)
	{
		var builder = new ConfigurationBuilder()                
			.AddEnvironmentVariables();
		Configuration = builder.Build();
	}

	public IConfigurationRoot Configuration { get; }
	
	public void ConfigureServices(IServiceCollection services)
	{
		services.AddMvc();
		
		services.AddApiVersioning(o =>
		{
			o.AssumeDefaultVersionWhenUnspecified = true;
			o.DefaultApiVersion = new ApiVersion(1, 0);
		});
	}
	
	public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
	{	  
		app.UseMvc();
	}
}  

public class Program
{
	public static void Main(string[] args)
	{
		BuildWebHost(args).Run();
	}

	public static IWebHost BuildWebHost(string[] args) =>
		WebHost.CreateDefaultBuilder(args)
			.UseStartup<Startup>()
			.Build();
}  

public class ValuesController : Controller
{
	[HttpGet("/test/{MyValue:int}")]
	public string Get()
	{
		// equals to this.HttpContext.Features.Get<IRoutingFeature>().RouteData;
		var fromHttp = this.HttpContext.GetRouteData();
		var fromController = this.ControllerContext.RouteData;

		if (fromHttp.Values.Count != fromController.Values.Count)
		{
			throw new Exception("Different RouteData values when taken from HttpContext and ActionContext.");
		}

		return "VALUE";
	}
}

Web Application: netcoreapp2.0
Microsoft.AspNetCore.Mvc.Versioning: 2.0.0-preview2-final
Microsoft.AspNetCore: 2.0.0
Microsoft.AspNetCore.Mvc: 2.0.0

Operating system: Windows 10 Professional 15063.540
IDE: Visual Studio Professional 2017 15.3.2

@commonsensesoftware
Copy link
Collaborator

This is an interesting find, but it is a bug. The explanation for why this happens is a bit long, but it occurs during the application of the versioning policy. The original route data is provided to the action context, which eventually makes it's way to the controller context, but the route data is not restored on the route context. The route context provides the route data for the IRoutingFeature. That's why they don't match.

I've located the issue and I should have the fix out soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants