Can I make a call to an MVC controller or Model using the Razor Host Module in DNN? - razor

We have a content page that runs a boolean check in our controller and we are moving that page to DNN. Is there a way to keep running that check using the Razor Host module?
I would basically show or hide button based on the status of a registration process.

My manager found the solution:
It turns out if you create a static file and save it in the Components folder (remember this is for DNN modules), you can just make a call to that class and its methods from within the Razor Host module as such:
#using MYNAMESPACE.Modules.Myproject.MyModule.Components
Some html
#{ var isRegistrationOpen = MyStaticClass.IsRegistrationOpen(); }
Registration Status: #isRegistrationOpen

Related

ASP.NET Core 6 MVC + views: exception when switching from AddDefaultIdentity to AddIdentity

I have opened a test project (.NET 6, VS2022) based on ASP.NET Core MVC and views template (not Razor pages), with activated individual user accounts.
Program.cs looks like this (from the template):
builder.Services.AddDefaultIdentity<IdentityUser>(options ...
builder.Services.AddControllersWithViews();
...
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.MapRazorPages();
So far so good.
Now I added some example code to seed the user database, which needs access to the RoleManager:
var roleManager = services.GetRequiredService<RoleManager<IdentityRole>>();`
However, that throws an exception
No service for type Microsoft.AspNetCore.Identity.RoleManager`1[Microsoft.AspNetCore.Identity.IdentityRole]'
which could be fixed (thanks Stackoverflow) by changing the AddDefaultIdentity() to AddIdentity() which introduces IdentityRole:
builder.Services.AddIdentity<IdentityUser, IdentityRole>(options ...
However, now I get an exception further down with
app.MapRazorPages();
System.InvalidOperationException: 'Unable to find the required services. Please add all the required services by calling 'IServiceCollection.AddRazorPages' inside the call to 'ConfigureServices(...)' in the application startup code.'
Which services need to be configured and how?
When I remove app.MapRazorPages();, the user management pages (login, user registration) do no longer work (404 error).
When I instead add builder.Service.AddRazorPages() above, the routing is also broken: a route to "/account/login" is missing, probably because Razor pages are somewhat differently organized than MVC controllers. Obviously, I do not want Razor pages, just Razor logic in a few views, and basically MVC architecture.
I am, honestly, a bit confused, since the official documentation does not help much.
Follow your document, I fount that what you did is adding an initialization to create data in the database. So I created a new .net 6 MVC app and integrate default authentication. Pick up Authentication type field with Individual User Accounts when creating the project, then run Update-Database command in Package Manager Console window. Now I have a empty .net 6 MVC project with default asp.net core authentication.
Next, I followed the document and created a SeedData.cs file in the root folder:
using Microsoft.AspNetCore.Identity;
namespace WebAppDefIdentity
{
public static class SeedData
{
//public const string AdministratorRole = "Administrator";
public static async Task InitializeAsync(IServiceProvider services) {
var roleManager = services.GetRequiredService<RoleManager<IdentityRole>>();
await EnsureRolesAsync(roleManager);
}
private static async Task EnsureRolesAsync(RoleManager<IdentityRole> roleManager)
{
var alreadyExists = await roleManager.RoleExistsAsync("Administrator");
}
}
}
And the document is .net 5 oriented project, so need a little change. In the Program.cs file, adding following codes.
using (var scope = app.Services.CreateScope())
{
var aa = scope.ServiceProvider;
await SeedData.InitializeAsync(aa);
}
Then I reproduce your first exception
To solve this exception, I changed in Program.cs with code .AddRoles<IdentityRole>()
Then no exception.

RazorView/RazorPages related data

I have some data specific to each razor view and and i do not want to hard-code it to each view. So, i want to add view related compile-time data to each view.
Custom attributes do not work for me because we cannot add custom attributes to razor views.
I do not want to re-fetch/populate this data from the data source(dictionary etc.) for each request or when view reached.
So, is there any way to attach data to each view at once throughout the life time of asp.net application?
Note
Actually i want to add scripts/styles generated by webpack for each view statically. Their links include hash values so they change when source scripts/styles change. So, i just want to get them added to each view only once(equivalent to typing them into view) through out the asp.net application, not every time a view loads.
I created a demo application for you here.
You will want to use your appsettings.json file, and inject your settings into your view.
In my appsettings.json I added a section called "ViewConfiguration":
"ViewConfiguration": {
"ExampleKey": "ExampleValue"
}
Your various values will need to go into your ViewConfiguration section.
For example where I have ExampleKey, you will use a generic name like "IndexPageStyleSheet", and where I have ExampleValue, you will need to update each release with the new stylesheet path. This will only need to be updated when the filename changes.
I then created a ViewConfiguration class which stores all of the values from the appsettings.json file.
You will need to create one property per configuration line, and ensure that the name of the property matches the name of the key in your appsettings.json.
For example where my appsettings.json has ExampleKey, my ViewConfiguration class also has an ExampleKey.
public class ViewConfiguration {
public string ExampleKey { get; set; }
}
In your Startup.cs you will need to tell your IOC container to load your configuration values into your configuration object.
In my Startup.cs, my ConfigureServices method loads my "ExampleValue" into ViewConfiguration.ExampleKey automatically.
public void ConfigureServices(IServiceCollection services) {
// This line is the magic that loads the values from appsettings.json into a ViewConfiguration object.
services.Configure<ViewConfiguration>(Configuration.GetSection("ViewConfiguration"));
services.AddMvc();
}
Now, in my _ViewImports.cshtml I inject my ViewConfiguration object so that I don't need to inject it into every single page. This can be anywhere in the _ViewImports.cshtml file. If you only want to inject specific configuration per folder, you can create a new _ViewImports.cshtml file per folder and inject different configuration objects into each one. It's flexible.
#using Microsoft.Extensions.Options;
#* Please rename this variable to something more appropriate to your application: *#
#inject IOptions<ViewConfiguration> InjectedViewConfig
Now, in any page, you can simply reference the property in your ViewConfiguration object.
For example in my Index.cshtml, I reference the ViewConfiguration.ExampleKey property by referencing the strongly typed property on InjectedViewConfig.Value, and it outputs "ExampleValue" on the page.
This value could just as easily be injected into a script or css link tag as the name of a file. It's very flexible.
<h1>Value: #InjectedViewConfig.Value.ExampleKey</h1>
With further research, you will be able to inject these values from any configuration source, such as Azure application settings or Azure Key Vault. Please see this article for more details.
If you are using mvc, you can create models and add it into the views. Since you don't want to recreate for each view, you can create readonly variables.
static readonly MyModel ModelData = new MyModel { PropName = "Hello" };
public IActionResult Index () => View(ModelData);
In your view you can now strongly type the value. If you are looking to use MVVM, you can refer to ViewModel concept still exists in ASP.NET MVC Core?
Implementing IFileProvider and IFileInfo provides changing the contents of view at compile-time. So, we could replace and provide static data in views with a template engine(i.e. http://dotliquidmarkup.org/).
Check this;
https://www.mikesdotnetting.com/article/301/loading-asp-net-core-mvc-views-from-a-database-or-other-location

Yii2 access to actions in new controllers

Comrades, I have had issues implementing yii2 basic but I'm yet to give up. I have successfully installed yii2, activated pretty url and created the .htaccess file in the root folder. The Home, About, Contact and Login urlswork fine.
i. I have created a new model, InstTypes with the CRUD. Why does http://localhost:8081/we#ss/instTypes/create return Not Found (#404)?
ii. I have also created a module instClients. I can access the index action in the DefaultControler. I have a model Insts with its CRUD under this modules. Why does http://localhost:8081/we#ss/instClients/insts/create return Not Found (#404)?
I tend to think that this could be due to the removal of the import and autoload from the config.
Could someone demonstrate how they've created a new model and CRUD and successfully accessed its actions?
Thanks in advance
I have created a new model, InstTypes with the CRUD. Why does
http://localhost:8081/we#ss/instTypes/create return Not Found (#404)?
You cannot access a model directly, the only way to interact with a model is via a controller which will intern interact with the model and the view. By initializing the model $model = new YourModelNmae(); or by rendering a view.
From your URL
http://localhost:8081/we#ss/instTypes/create
InstType should be your controller while create is an action under InstType
Using Yii2 Gii tool to generate a CRUD do the following : -
Generate your model
Generate your CRUD
go to
http://localhost:8081/we#ss/yourController/YourActionOnYourController
Refer to this youtube link for more detail https://www.youtube.com/watch?v=6B52-li6IgU
Happy coding :)
Just to add to the other answers, your url isn't working because it's camelCase. You need to make it hyphenated, so
http://localhost:8081/we#ss/instTypes/create
will become
http://localhost:8081/we#ss/inst-types/create
You're getting the 404 because you're trying to access instTypes, it should be inst-types.
this solved my problem. I needed to add the controllers to the controller map.

Angular app can't find controller on transclude

I am unable to get my controller linked to my view. If I include the view using ng-view and have the controller name in the route, the transclusion fails in Angular-route.js when it trys to link in the ngViewFillContentFactory. If I use the ng-controller attribute in the view itself, it fails in angular.js on the boundTranscludeFn that binds the controller to the view. In both cases I can see the application and the 'shell' controller are loaded into the DOM. In both cases the error message "Argument 'shell' is not a function".
The ng-app tag is set in the html tag to the name of the application. Why can the application not find the controller? What tiny little detail am I missing?
Here is the error message (I am calling the controller on two different divs) and here is the controller function loaded into the angular controllers collection.
The ng_app attribute is set to "cockpit" in the html tag and in both cases now I am using the router to assign the shell controller to both the view and the ng-included partial. The same thing happens if I assign the ng-attribute tag to "shell" in shell.html only the error occurs in another part of the code.
I am trying to put together a test app to reproduce the problem which I can post on git.
So the problem was how I was constructing my module. I can't tell you exactly what I did wrong because I don't yet understand exactly how modules work. What I did was to reduce the application down until I got it to work and added things back one by one until I found the thing that broke the app.

"Server Error in '/' Application." in MVC4 when I create new folder with new view

I am fairly new in MVC4. I'm working with C# Razor view engine using Entity Framework.
I wanted to add new view model that incorporated multiple models (obviously). But I needed a new view. So I created new folder inside Views named "MasterView" with a sample Index.cshtml inside, linked it inside _Layout.cshtml with
<li>#Html.ActionLink("Klick me", "Index", "MasterView")</li>
and when I ran my application, all the default links worked except that one (Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly. ). Am I missing some permission for that page inside some project file? How do I fix it? Thanks in advance.
In MVC you link to Actions inside Controllers rather than pages/views.
In this case you would need a MasterViewController (in the Controllers folder) with an Index action like this:
public ActionResult Index()
{
return View();
}
This will render and return your Index.cshtml file.