I'm writing a very simple content management system and I'm wondering if it's possible to dynamically and a ViewComponent (or other active elements) to a Razor page dynamically, ideally from a database.
I've created a bunch of widgets but I have to place them on the page but then selectively show or hide them based on the user's selections. It works fine but I am thinking there must be a better way.
I've been looking at this for a while now and I can't seem to find a solution, or maybe you just can't do that.
Any thoughts much appreciated
:)
Thanks to @Arjun Vachhani this is what I came up with if anyone else wants to try it.
//item is a class containing ComponentName as a string property and Data as a dynamic property. @model is a List<> of those classes.
public class MyClass
{
public string ComponentName { get; set; }
public dynamic Data { get; set; }
}
In my view I have
@model List<MyClass>
@foreach (var item in Model)
{
@await Component.InvokeAsync(item.ComponentName, item.Data );
}
In the controller (as a test)
List<MyClass> list = new List<MyClass>();
var definition = new { id = "" };
var user = await _adminService.GetUserByEmail(User.Identity.Name);
//one of these for each component. You could just as easily get them from the database via `dbcontext` or `Service` method.
//in this case I wanted the logged in user id from Asp.Net.Identity but could equally be any parameter you wanted.
list.Add(new JsonApiResult { ComponentName = "CompenentName1", Data = JsonConvert.DeserializeAnonymousType($"{{ id : {user.Id} }}", definition) });
list.Add(new JsonApiResult { ComponentName = "CompenentName2", Data = JsonConvert.DeserializeAnonymousType($"{{ id : {user.Id} }}", definition) });
//etc...
return View(list);
I'm working on jQuery.Sortable so if I get a nice solution I'll post that up too.
You can save the name of the view component in the database and optionally value passed in view component. Users can select the component he is interested in. selected component will be saved in DB. during page rendering loop through the selected component and render dynamically.
Here is a sample code to render the component dynamically.
This is an idea of how it can be done. Implementation detail may vary based on your requirements.
https://learn.microsoft.com/en-us/aspnet/core/mvc/views/view-components?view=aspnetcore-3.0 is an official document on view component for more info