Skip to content
This repository has been archived by the owner on Dec 14, 2018. It is now read-only.

Controllers declared in class library, returning 404 with AWS Lambda C#2.1 #8095

Closed
Eilon opened this issue Jul 16, 2018 · 6 comments
Closed
Assignees

Comments

@Eilon
Copy link
Member

Eilon commented Jul 16, 2018

From @thammadi on July 15, 2018 3:41

I created an AWS Serverless solution with a Web API and Class Library projects (2.1.0). Class Library is referenced by the Web API project.

Controller in Web API:

[Route("api/[controller]")]
public class ValuesController : Controller
{
        [HttpGet]
        public IEnumerable<string> Get()
        {
            return new string[] { "value1", "value2" };
        }
}

References: Microsoft.AspNetCore.App (2.1.0) and Microsoft.NETCore.App (2.1.0)
Compatability version set in Startup.cs:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}

Controller in Class Library:

[Route("api/[controller]")]
public class ClassesController : Controller
{
        [HttpGet]
        public IEnumerable<string> Get()
        {
            return new string[] { "class1", "class2" };
        }
}

References: Microsoft.AspNetCore.App (2.1.0) and Microsoft.NETCore.App (2.1.0)
SDK reference in Class Library project file is updated from Microsoft.NET.Sdk to Microsoft.NET.Sdk.Web

Deployed the above to AWS lambda (dotnet lambda package -c "Release")

When tested, '/api/values' works as expected but '/api/classes' returns 404
This used to work with 2.0 version.

Did I miss anything?

Copied from original issue: dotnet/aspnetcore#3330

@Eilon
Copy link
Member Author

Eilon commented Jul 16, 2018

@thammadi - would it be possible for you to upload a repro app to GitHub so that we can take a look?

@thammadi
Copy link

@Eilon - Below is the sample solution.
AWSServerlessApp.zip

Call to '/api/classes' responds as expected behind IIS, but doesn't when deployed to AWS Lambda (C# .NET 2.1 runtime) hooked up with AWS API Gateway.

@pranavkm
Copy link
Contributor

Thanks for the app @thammadi. Explicitly adding the library as an application part in your startup should address the issue:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
            .AddApplicationPart(typeof(AWSServerlessClassLibrary.Controllers.ClassesController).Assembly);
}

Background:

By default, MVC looks at an application's deps file to determine what assemblies may contain controllers. The assumption is that only things that reference MVC, either directly or transitively, would contain controllers. The shared runtime poses some unique problems in this - references to it often times get erased from the "runtime" deps file graph which results in MVC deciding that an assembly \ library does not reference MVC. In 2.1.0, we switched this to use the "compile" time graph which was more considered more reliable, but it looks like the lamda deployment scripts explicitly turn this off - https://github.com/aws/aws-extensions-for-dotnet-cli/blob/92c7a3d91ad5167d82949c88130c03335fffa18b/src/Amazon.Lambda.Tools/LambdaDotNetCLIWrapper.cs#L97-L102. Explicitly adding the library workarounds MVC's auto-discovery. That said, I'd encourage you to talk to the lambda folks and figure out why they publish with compilation context disabled.

@thammadi
Copy link

@pranavkm - That explains very well. Thank you. Adding the class library as application part solves the issue. I'll raise this with AWS Lambda team.

Thanks for your time looking into this!

@normj
Copy link

normj commented Jul 19, 2018

From the AWS team who wrote this tool.

The reason I set PreserveCompilationContext to false was the ref folder would bloat the package bundle and package bundle size is critical to Lambda cold start performance. I assumed the refs folder wouldn't be needed since the views were precompiled. Is there any other work around that doesn't involve the whole refs folder being created?

@pranavkm
Copy link
Contributor

Is there any other work around that doesn't involve the whole refs folder being created?

Unfortunately not. I created an issue in the Dotnet Sdk to address this - dotnet/sdk#2122 - once that becomes available setting it would do the right thing. In the meanwhile, physically deleting the directory might be the best bet outside of setting the flag.

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

No branches or pull requests

5 participants