How to implement micro frontend architecture in legacy application using Angular - c#

Recently our team has decided to implement micro front end architecture in our legacy product. It has been developed using Asp.Net aspx pages along with javascript/jquery.
Last year we started using angular in our application for some of the views. To load angular we are placing the prod build files in .net project and we are loading the component in aspx master page.
We are planning to migrate our rest pending older views to angular using micro front end architecture.
So I did a small poc for the same and was able to achieve the architecture to somewhere close to it.
I followed this url for implementation and ran it on port 4400.
https://medium.com/swlh/build-micro-frontends-using-angular-elements-the-beginners-guide-75ffeae61b58
And in my existing angular project i am loading this using customElements
this.appendCustomElementWithUrls('app-positions','http://localhost:4400/main-es5.js', (<HTMLElement>document.getElementById("chartAppContainerNamInqA")) );
appendCustomElementWithUrls(name: string,url: string,target: HTMLElement){
if (!customElements.get(name)) {
const script = document.createElement('script');
script.src = url;
document.head.appendChild(script);
}
const component = document.createElement(name);
target.appendChild(component);
}
And this works as expected and I am able to load customElements in my dev env. But for production I am really not sure how to implement.
My concern:
Will I have to run app on some port in prod as well? If yes how to do that and can it be dynamic such that user has ability to change the port. The way we have in .net application. Since client may have something already running on that port
The way I am trying to achieve is correct or not.
Thanks in advance.

For those who might have requirement like this.
I did lot of research and went through lot of articles and came out with a solution.
So I created a separate application using Angular elements and generated single bundle using cmd;
ng build --prod --output-hashing none --single-bundle true
then I created an application in IIS and placed all the prod generated files in it on port 9091. You can use any port for that.
In my web.config file I created a key such that if user changes the port number then they directly update web.config:
<add key="MicroFrontEnd" value="http://localhost:9190"/>
Since port should be configurable so I created an api to fetch the port number.
Then I used this in my shell app and it works like a charm.

Related

How to set Custom Base URL in Azure App Service with .Net Core?

I have created a web application in .Net core(v5.0) and hosted it in Azure App Service. I have created a view and that allows me to add a new URL based on that create a new subdomain in the same service and publish code in that. This concept also uses in Jira software where our <projectname>.atlassian.com
Eg:
I have added dev in a text box then-new subdomain added like. dev.<myappservicename>.azurewebsites.net
In this case, all code copy and run this code properly.
Main Domain:
Base URL(Created URL): <myappservicename>.azurewebsites.net
Custom URL(Added from View): dev.<myappservicename>.azurewebsites.net
,
admin.<myappservicename>.azurewebsites.net
Technology Specification:
.Net Core(5.0)
C#
Azure App Service
If anyone has an idea then suggest thought.
It helps me a lot.
You can use restapi or .net sdk to create subdomain.
From your description, I see that there should be no need to redeploy your webapp, so if there is a business need, it is recommended to identify it through the program, what is the input url of the browser, to process your program.
Eg:
company1.<projec_tname>.azurewebsites.net
Get HttpRequest url to handle company1's bussiness.
company2.<projec_tname>.azurewebsites.net
Get HttpRequest url to handle company2's bussiness.

Blazor httpclient endpoint address configs

I'm playing around with Blazor in .net core 3 preview 5.
My solution is quite simple, with one project for the web api and a second for the blazor client app.
The api is currently serving on localhost:5000 and the blazor app on localhost:5001, and I'm using httpclient to make http calls to the rest endpoint.
One thing in struggling with is understanding the best way to avoid baking in the api server URLs into the blazor app.
Is there am established pattern which will enable be to specify the base url by config or run time?
Edit to add info from comment:
Ultimately, I'd like to run it in a container in our test k8s cluster, that means the target url for the api would change to (say) api.test.companydns.com. the blazor app will end up running inside a container, so ideally I could pass in the api url as a parameter. I wasnt sure of the best way to do that as the blazor code ends up being executed on the client side
Question:
Is there am established pattern which will enable be to specify the base url by config or run time?
Answer: Yes, the base Uri of your Blazor client side is determined by the <base> HTML element set in /wwwroot/index.html like so:
<base href="/" />
Hope this helps...
I've done a bit of a hack which works for me (posted more to show I'm putting effort into solving the problem for myself!!):
I've added a config file to wwwroot\config\config.json which contains:
{
"apiBaseUrl": "api.url.com"
}
Next, I've created an AppState.cs which used the HttpClient to download and store the base URL (Defaul DI instance of HttpClient has a BaseURL of the url serving the Blazor client app).
The AppState class is then made available using DI, so now all my Services can make calls to the new endpoint.
Lastly, I can use a build pipeline / CI / Docker volume / K8s config map to supply the relivent config.json depending on the hosting environment and without further changes to any Blazor app code.

AllScripts API HelloWorld

I'm using the AllScripts HelloWorld TouchWorks C# Project, as provided on their site. I've also created a valid application, using the svcUsername and svcPassword on the app.config file to log and added my own appName instead of the default web20.
Didnt change anything else, tried with many different application ID's, all trying to log into the default sandbox server in the example and some trying other sandboxes.
Regardless of what I do, I keep getting
Error: Service Application not licensed on this server!
Despite this being a sandbox server, thus suppouseably accessable to all applications.
What did I do wrong?
edit: Tried to do the same in Slueth, I get the same error.
It's more simple than it seems. Sandbox servers DO require licenses. Talked with the staff, they're nice people, so they manually added me after a few explanations of my requirements.

DNN Database Repository Reuse in Console Application

I have a project based on the Chris Hammond, Christoc, module template. I have a ton of code that I use to access data an external database. In my repositories I change the database from the default to whichever I need for that particular object. I do so with code that looks like this:
using (IDataContext ctx = DataContext.Instance(MyModuleSettingsBase.DATABASE_CONNECTION_STRING_KEY))
{
var rep = ctx.GetRepository<Product>();
products = rep.Get().ToList();
}
The default database is switched in the call to .Instance(). The repositories are used by my custom DNN modules. The repository is part of the solution that contains multiple custom modules. When I compile and install using the Extensions part of DNN, everything works well. In the code above, MyModuleSettingsBase.DATABASE_CONNECTION_STRING_KEY is found in a file MyModuleSettingsBase.cs file of my module solution. It is set to a simple string like "ProductDatabase". In the solution for the base DNN install (not the module solution), within the web.config file, there is a value in <connectionStrings> with name="ProductDatabase" which contains the actual connection string. This all links up fine on the DNN website.
Now I am writing a console application that does some monitoring of the site. I want to access the database to check values in the product table. I would like to reuse all of the repository code I have written. In an attempt to do so, I added a reference to the MyModules.dll file so I would only have one copy of the base code. This works to give me access to all the objects and the associated repositories but when I attempt to query data it fails. When debugging I can see that it fails on the line:
using (IDataContext ctx = DataContext.Instance(MyModuleSettingsBase.DATABASE_CONNECTION_STRING_KEY))
When viewed in a debugger, the string value MyModuleSettingsBase.DATABASE_CONNECTION_STRING_KEY is correctly set to "ProductDatabase" but the code is unable to link this with the actual connection string. I don't know where it would be checking for the connections string when running from my console application. I attempted to put a <connectionStrings> section into my App.config file but this didn't do the trick.
Is it possible to have MyModuleSettingsBase.DATABASE_CONNECTION_STRING_KEY map to the connection string in an external application which references the DLL?
If so, where can I set the value of my connection string so it matches up to the key value stored in MyModuleSettingsBase.DATABASE_CONNECTION_STRING_KEY?
I was faced similar problem 3 months ago, at that time I want to use DNN core libraries in my console application but I was failed.
I placed my queries in DNN official forum website and I got a valid response from Wes Tatters (DNN MVP).
Here is the post link: Reference URL
As your requirement of monitoring, I suggest you to create DNN Schedule Application. You can schedule it within DNN (Host->AdvancedSettings->Schedule), even good point is that you can use your repositories (DNN Libraries) in that schedule application.
I hope it solved your problem. Let me know if you have any questions.

Wildcard mapping for ASP.NET and issues with PHP

I have an application written in .NET 3.5 with C# as the language. I'm using Web Forms, but using url routing with the routes defined in my global file. Everything is working as expected. In order for the pretty paths (see: user/665 instead of user.aspx?uid=665) to work properly, I had to add a wildcard mapping in IIS5.1 (local box, not test, staging, or production) the aspnet_isapi file for the 2.0 framework. Everything works fine.
Now, my site needs a plugin for PHP. However, the PHP files are now being serviced by ASP.NET due to the wild card mapping, and hence are not processed by the PHP interpretter. Is there any way to get around this? Would I have to add some sort of handler to my web app that will take all PHP requests being handled by the ASP.NET framework and have them routed to the PHP engine? Is there an easier way? Maybe a way to exclude them in the web.config (PHP files) and have them served by the proper PHP engine?
Thanks all!
-Steve
This is a solution, but is not an elegant way (IMHO):
Create a virtual directory
Have it point to the folder with the files (in this case, a PHP plugin)
Give it the proper permissions
Change the config options for the virtual directory in IIS and make sure the wildcard mapping for that directory is removed.
This works like a charm for my situation. However, is there any way to not have to deal with virtual directories?
The problem is that the PHP extension needs to be registered.
In IIS Manager right-click on Default Website -> Properties -> Home Directory -> Configuration
Under Application Mappings make sure that .php is added and is it pointing to PHP.EXE. There should be an entry like this: extension .php, executable path C:\PHP\PHP.EXE %s %s
From what I gather, the problem is that ASP.NET is attempting to route your PHP requests, so what I would do is add a StopRoutingHandler() to your routes in the global.asax. Something like this should work:
routes.Add(new Route("{resource}.php/{*pathInfo}", new StopRoutingHandler()));
Edit: Be mindful that routes are processed in order, so I would add this to the top of your routes.

Categories

Resources