Skip to content
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

[Regression] .NET 9 ILLinker trims out ControllerContext setter out of ControllerBase #59039

Closed
JustArchi opened this issue Nov 18, 2024 · 2 comments
Labels
area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates

Comments

@JustArchi
Copy link

JustArchi commented Nov 18, 2024

Description

When using ASP.NET controllers that reference HttpContext, the context itself is always null when -p:PublishTrimmed=true is used.

Reproduction Steps

[ApiController]
[Route("Api")]
public sealed class NLogController : ControllerBase {
	[HttpGet]
	public async Task<ActionResult> Get() {
		if (HttpContext == null) {
			throw new InvalidOperationException(nameof(HttpContext));
		}

		return new EmptyResult();
	}
}

The above should give you 500 when trying to execute it in .NET 9-trimmed application.

Expected behavior

Controller actions should have access to HttpContext, it should not be null.

Actual behavior

HttpContext is null, after further digging, the problem is with ControllerContext, I'm not 100% sure but my blind take is that setter gets trimmed out and the property is never initialized when the action is executed as part of incoming request.

Regression?

Yes, the property was not trimmed in .NET 8 and earlier (with exactly the same config).

Known Workarounds

<linker>
	<assembly fullname="Microsoft.AspNetCore.Mvc.Core">
		<type fullname="Microsoft.AspNetCore.Mvc.ControllerBase">
			<property name="ControllerContext" />
		</type>
	</assembly>
</linker>

Configuration

.NET SDK:
 Version:           9.0.100
 Commit:            59db016f11
 Workload version:  9.0.100-manifests.3068a692
 MSBuild version:   17.12.7+5b8665660

Other information

Let me know if you're unable to reproduce it, I'll try to come up with repro based on my issue in https://github.com/JustArchiNET/ArchiSteamFarm then. If you're fine reproducing it in my public project, then:

git checkout b1b04b3ebe410390c05fbf73aa26198fc9442aab

# Replace linux-x64 with your target machine
dotnet publish ArchiSteamFarm -c Release -o out -r linux-x64 -p:PublishTrimmed=true -p:PublishSingleFile=true --self-contained

./out/ArchiSteamFarm

Shortly after launch of the program you can navigate to localhost:1242/swagger and try to execute selected endpoints that use HttpContext, e.g. GET /Api/NLog, which should normally inform you that you didn't send in websocket request, but in affected build crashes with 500 due to my safeguard here.

2024-11-18 11:03:02|ArchiSteamFarm-17506|ERROR|Microsoft.AspNetCore.Server.Kestrel|Connection id "0HN87N0NV3BJR", Request id "0HN87N0NV3BJR:00000001": An unhandled exception was thrown by the application. System.InvalidOperationException: HttpContext
   at ArchiSteamFarm.IPC.Controllers.Api.NLogController.Get()
   at lambda_method9(Closure, Object)
   at Microsoft.Extensions.Internal.ObjectMethodExecutorAwaitable.Awaiter.GetResult()
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfActionResultExecutor.Execute(ActionContext, IActionResultTypeMapper, ObjectMethodExecutor, Object, Object[])
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker, ValueTask`1 )
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker, Task, State, Scope, Object , Boolean)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State&, Scope&, Object&, Boolean&)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|20_0(ResourceInvoker, Task, State, Scope, Object , Boolean)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker, Task, IDisposable )
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker, Task, IDisposable )
   at ArchiSteamFarm.IPC.Integration.ApiAuthenticationMiddleware.InvokeAsync(HttpContext context, IOptions`1 jsonOptions)
   at Microsoft.AspNetCore.ResponseCompression.ResponseCompressionMiddleware.InvokeCore(HttpContext)
   at Microsoft.AspNetCore.ResponseCaching.ResponseCachingMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1)

The commit that fixes the issue for me, which is more like a workaround than actual fix: JustArchiNET/ArchiSteamFarm@8aa0170

I'm not 100% sure if this is an actual issue, since it could also be considered intended behaviour of ILLinker, but I don't believe a regression this big could be intended improvement and expectation from the consumers to add it manually if they need it, hence me reporting it.

@dotnet-issue-labeler dotnet-issue-labeler bot added the needs-area-label Used by the dotnet-issue-labeler to label those issues which couldn't be triaged automatically label Nov 18, 2024
@JustArchi JustArchi changed the title .NET 9 ILLinker trims out ControllerContext setter out of ControllerBase [Regression] .NET 9 ILLinker trims out ControllerContext setter out of ControllerBase Nov 18, 2024
@jeffschwMSFT jeffschwMSFT transferred this issue from dotnet/runtime Nov 18, 2024
@martincostello martincostello added area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates and removed untriaged needs-area-label Used by the dotnet-issue-labeler to label those issues which couldn't be triaged automatically labels Nov 19, 2024
@martincostello
Copy link
Member

MVC doesn't support trimming: #41767 #27384 (comment)

If it worked in previous releases for your application, that was just a happy accident.

@JustArchi
Copy link
Author

Alright, then I guess we can consider this issue as irrelevant considering the feature is not supported.

Considering other people also report it worked fine in .NET 8, there is probably not that much work needed to have at least basic examples working fine under trimming, so perhaps it's worth prioritizing for the future.

Thanks for answer 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates
Projects
None yet
Development

No branches or pull requests

2 participants