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

How to use Falco directly with an existing C# MVC application via IEndpointRouteBuilder and the RazorViewEngine? #43

Closed
willnationsdev opened this issue Jan 16, 2021 · 1 comment

Comments

@willnationsdev
Copy link
Contributor

willnationsdev commented Jan 16, 2021

I'm currently using OrchardCore to build a SaaS platform, and it relies exclusively on C# MVC using .NET Core. It uses a system that pulls Startup classes from any referenced class libraries ("modules") and merges together their content. Specifically, each Startup mounts endpoints using an IEndpointRouteBuilder with calls to MapAreaControllerRoute which all have to specify exact details like the controller, the action, the area, the pattern, etc.

I've been trying to see if I can use F# from start to finish in creating a basic module, but I have to fully emulate the experience of using MVC. That is...

  • they compile virtual razor template paths using "areas" scoped to each specific module's name.
  • they use physical paths during development and embedded views with virtual paths during production.
  • the controller/action/area metadata has to be associated with each route.
  • the controller actions all return Task<IActionResult>, and if it's a View, then it gets embedded within a larger View powered by a configurable Theme system in OrchardCore.

I can't really use Giraffe since it just writes content to the response directly (which would disregard the Theme system). It also only supports Microsoft's endpoint stuff in it's most recent alpha builds, so meh. Falco, on the other hand, is built entirely with seamless integration of AspNetCore in mind, so I'm hoping you have suggestions on how I might approach this.

I figure I could write some sort of HttpHandler that registers the endpoints along with the appropriate metadata. Then, it's just a matter of figuring out how to take an HTML string and directly inject it into an inline View that is picked up by Razor and used in OC's theme system.

@willnationsdev
Copy link
Contributor Author

willnationsdev commented Jan 16, 2021

Hmmm. If I'm reading this right, the routing logic that MVC relies on all happens here in Falco. Only, it doesn't support MapAreaControllerRoute, so the necessary metadata never makes it into the routing system. So, I'd have to modify the code to allow for the HttpEndpoint record to support more information (perhaps using a union type) so that when it enters the UseFalco function, it can check to see if that data is present and, if so, use the property IEndpointRouteBuilder method.

I think we'd then need to create some extension method, or add more to the UseFalco stuff, that registers services implementing IControllerFeatureProvider and IViewFeatureProvider, that way you can explicitly bind area/controller/action combinations to request delegates and bind HTML strings (generated from F# code) to a view name, or something to that effect. I found a decent example of implementing an IControllerFeatureProvider here.

Edit: Okay, I'm starting to think I'm making things too complicated. You don't really need to spoof controllers and actions to make things work. It'd be convenient to be able to make the routes recognizable to other modules, but they can always just use a URL, and that would work fine for most use cases anyway. So vanilla Falco will probably work just fine. The more difficult problem is figuring out how to use an F# view engine to generate text that appears inside an Orchard Core theme. The only way I know of to make it work is to return a ViewResult from an action which is magically picked up because reasons. Will have to investigate further. But regardless, I suppose that means it isn't a relevant issue here anymore.

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

No branches or pull requests

1 participant