Hi I wanna use a modal popup for Create User view in Asp Net Core 5 (mvc).
I wanna use this modal as a ViewComponent
In User Index view (which shows the list of users).
I added a button that is related to Create User method.
I want when I click on that button the modal popup that is a ViewComponent opens.
but after running the application I cant go to Index User page,
because of an exception that shows a conflict between the model used in Index.cshtml (which is IEnumerable) and the model used in ViewComponent View (which is UserViewModel).
I will upload the Exception.
ViewConponent Class:
public class CreateViewComponent : ViewComponent
{
public async Task<IViewComponentResult> InvokeAsync()
{
return View("Default");
}
}
ViewComponent View:
@model UserViewModel
@{
Layout = "_LayoutAdmin";
ViewData["Title"] = "Create";
}
<div class="modal fade" id="modal-default">
<div class="modal-dialog">
<div class="modal-content">
**<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title">افزودن کاربر جدید</h4>
</div>**
<div class="modal-body">
<form asp-action="Create" method="post" class="form-horizontal">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="box-body">
<div class="form-group">
<label class="col-sm-3 control-label">اسم کاربر</label>
<div class="col-xs-5">
<input type="text" asp-for="Name" class="form-control" placeholder="اسم کاربر">
<span asp-validation-for="Name" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">نام کاربری</label>
<div class="col-xs-5">
<input type="text" asp-for="UserName" class="form-control" placeholder="نام کاربری">
@if (ViewBag.UserNameExistence != null)
{
<p class="text-red small"> @ViewBag.Message </p>
}
<span asp-validation-for="UserName" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">رمز عبور</label>
<div class="col-xs-5">
<input type="text" asp-for="Password" class="form-control" placeholder="رمز عبور">
<span asp-validation-for="Password" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">ایمیل</label>
<div class="col-xs-5">
<input type="text" asp-for="Email" class="form-control" placeholder="ایمیل">
@if (ViewBag.EmailExistence != null)
{
<p class="text-red small"> @ViewBag.Message </p>
}
<span asp-validation-for="Email" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">شماره تلفن</label>
<div class="col-xs-5">
<input type="text" asp-for="PhoneNumber" class="form-control" placeholder="شماره تلفن">
@if (ViewBag.PhoneNumberExistence != null)
{
<p class="text-red small"> @ViewBag.Message </p>
}
<span asp-validation-for="PhoneNumber" class="text-danger"></span>
</div>
</div>
</div>
<!-- /.box-body -->
<!--<div class="box-footer">
<button asp-action="Index" class="btn btn-default">انصراف</button>
<button type="submit" class="btn btn-info pull-right">افزودن</button>
</div>-->
<!-- /.box-footer -->
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default pull-left" data-dismiss="modal">خروج</button>
<button type="button" asp-action="Create" class="btn btn-primary">تأیید</button>
</div>
</div>
<!-- /.modal-content -->
</div>
<!-- /.modal-dialog -->
</div>
Index.cshtml View:
@model IEnumerable<ShopOnline.Domain.Entites.User>
@{
Layout = "_LayoutAdmin";
ViewData["Title"] = "Index";
}
<div class="box mt-3">
<div class="box-header">
<h3 class="box-title">لیست کاربران</h3>
</div>
<div>
<button class="btn bg-olive margin" action=("@await Component.InvokeAsync("Create")")
data-toggle="modal" data-target="#modal-default">
<i class="fa fa-fw fa-plus-square"></i>
افزودن کاربر جدید
</button>
</div>
<!-- /.box-header -->
<div class="box-body">
<div id="example2_wrapper" class="dataTables_wrapper form-inline dt-bootstrap">
<div class="row"><div class="col-sm-6"></div><div class="col-sm-6"></div></div><div class="row">
<div class="col-sm-12">
<table id="example2" class="table table-bordered table-hover dataTable" role="grid" aria-describedby="example2_info">
<thead>
<tr role="row">
<th class="sorting_asc" tabindex="0" aria-controls="example2" rowspan="1" colspan="1" aria-sort="ascending" aria-label="موتور رندر: activate to sort column descending">نام</th>
<th class="sorting" tabindex="0" aria-controls="example2" rowspan="1" colspan="1" aria-label="نام کاربری: activate to sort column ascending">نام کاربری</th>
<th class="sorting" tabindex="0" aria-controls="example2" rowspan="1" colspan="1" aria-label="ایمیل: activate to sort column ascending">ایمیل</th>
<th class="sorting" tabindex="0" aria-controls="example2" rowspan="1" colspan="1" aria-label="شماره تلفن: activate to sort column ascending">شماره تلفن</th>
<th>عملیات</th>
</tr>
</thead>
<tbody>
@if (Model != null)
{
@foreach (var item in Model)
{
<tr role="row" class="odd">
<td class="sorting_1">
@Html.DisplayFor(modelItem => item.DisplayName)
</td>
<td>
@Html.DisplayFor(modelItem => item.UserName)
</td>
<td>
@Html.DisplayFor(modelItem => item.Email)
</td>
<td>
@Html.DisplayFor(modelItem => item.PhoneNumber)
</td>
<td>
<a class="btn btn-warning waves-effect waves-light m-b-5" data-toggle="tooltip" data-placement="top" title="ویرایش کاربر"
asp-action="Edit" asp-route-id="@item.Id">
<i class="fa fa-user-circle"></i>
</a>
<a class="btn btn-danger waves-effect waves-light m-b-5" data-toggle="tooltip" data-placement="top" title="حذف کاربر"
asp-action="Delete" asp-route-id="@item.Id">
<i class="fa fa-remove"></i>
</a>
<a class="btn btn-info waves-effect waves-light m-b-5" data-toggle="tooltip" data-placement="top" title="سطح دسترسی"
asp-action="Access" asp-route-id="@item.Id">
<i class="fa fa-universal-access"></i>
</a>
</td>
</tr>
}
}
</tbody>
<tfoot>
<tr>
<th rowspan="1" colspan="1">نام</th>
<th rowspan="1" colspan="1">نام کاربری</th>
<th rowspan="1" colspan="1">ایمیل</th>
<th rowspan="1" colspan="1">شماره تلفن</th>
<th rowspan="1" colspan="1">عملیات</th>
</tr>
</tfoot>
</table>
</div>
</div>
<div class="row">
<div class="col-sm-5">
<div class="dataTables_info" id="example2_info" role="status" aria-live="polite">Showing 1 to 10 of 57 entries</div>
</div><div class="col-sm-7">
<div class="dataTables_paginate paging_simple_numbers" id="example2_paginate">
<ul class="pagination">
<li class="paginate_button previous disabled" id="example2_previous">
<a href="#" aria-controls="example2" data-dt-idx="0" tabindex="0">Previous</a>
</li>
<li class="paginate_button active"><a href="#" aria-controls="example2" data-dt-idx="1" tabindex="0">1</a></li>
<li class="paginate_button "><a href="#" aria-controls="example2" data-dt-idx="2" tabindex="0">2</a></li>
<li class="paginate_button "><a href="#" aria-controls="example2" data-dt-idx="3" tabindex="0">3</a></li>
<li class="paginate_button "><a href="#" aria-controls="example2" data-dt-idx="4" tabindex="0">4</a></li>
<li class="paginate_button "><a href="#" aria-controls="example2" data-dt-idx="5" tabindex="0">5</a></li>
<li class="paginate_button "><a href="#" aria-controls="example2" data-dt-idx="6" tabindex="0">6</a></li>
<li class="paginate_button next" id="example2_next">
<a href="#" aria-controls="example2" data-dt-idx="7" tabindex="0">Next</a>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<!-- /.box-body -->
The exception:
An unhandled exception occurred while processing the request.
InvalidOperationException: The model item passed into the ViewDataDictionary is of type ‘System.Collections.Generic.List`1[ShopOnline.Domain.Entites.User]’, but this ViewDataDictionary instance requires a model item of type ‘ShopOnline.Web.ViewModel.UserViewModel’.
Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary.EnsureCompatible(object value)
In stack part of exception page:
AspNetCore.Areas_Admin_Views_User_Index.ExecuteAsync() in Index.cshtml
<a class="btn bg-olive margin" action="@await Component.InvokeAsync("Create")"
Now What should I do.
Sorry for any grammatical mistake, I’m not English or American.
2
Answers
The above exception is clear, when you display the Default View Component, it requires a UserViewModel, instead of the List of User.
To solve the above issue, you could modify the CreateViewComponent as below:
its true and you need model for show
for show modal you should move all Modal control into View of ViewComponent and call view component in primary view not into Button tag
ViewComponent View:
in index view