Ajax.BeginForm submitting the form twice - ajax

I have a problem with my modal on inserting data. Every time I add a new row it get's a second identical row into the database. I don't really know exactly what I did wrong so if you have a ideea on how to solve this please help me.
This is my controller:
public ActionResult IndexEvent()
{
return View(db.tbl_Event.ToList());
}
[HttpGet]
public ActionResult AddEvent()
{
return PartialView();
}
[HttpPost]
public ActionResult AddEvent(BOL3.tbl_Event eve)
{
if(ModelState.IsValid)
{
db.tbl_Event.Add(eve);
db.SaveChanges();
}
return PartialView("_Detail", db.tbl_Event.ToList());
}
,here is my Index view, _Detail partial view and Add partial view (in the same order):
#model IEnumerable<BOL3.tbl_Event>
#{
ViewBag.Title = "Index";
}
<link href="#Url.Content("~/Content/bootstrap/css/bootstrap.min.css")" rel="stylesheet" />
<link href="#Url.Content("~/Content/bootstrap/css/bootstrap-theme.min.cs")" rel="stylesheet" />
<link href="#Url.Content("~/Content/bootstrap/css/font-awesome.min.cs")" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script>
<script src="~/Scripts/bootstrap.min.js"></script>
<div id="main-div">
<div class="clearfix"> </div>
<div class="clearfix"> </div>
<div class="container">
<i class="glyphicon glyphicon-plus"></i> Add New
<br />
<br />
<div id="div-record">
#Html.Partial("_Detail")
</div>
</div>
</div>
<div class="modal fade" id="Add-Model" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<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">Add Event</h4>
</div>
<div class="divForAdd">
</div>
</div>
</div>
</div>
<script>
$(document).ready(function () {
$('#Add').click(function (event) {
event.preventDefault();
$.get(this.href, function (response) {
$('.divForAdd').html(response);
});
$('#Add-Model').modal({
backdrop: 'static',
}, 'show');
});
#model IEnumerable<BOL3.tbl_Event>
<div class="table-responsive">
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Event Name</th>
<th>Starting Event (Date and Time)</th>
<th>Ending Event (Date and time)</th>
<th>All Day ?</th>
<th>Edit</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
#foreach(var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Event)
</td>
<td>
#Html.DisplayFor(modelItem => item.Start_Date)
</td>
<td>
#Html.DisplayFor(modelItem => item.End_Date)
</td>
<td>
#Html.DisplayFor(modelItem => item.All_Day)
</td>
<td>
<i class="glyphicon glyphicon-pencil"></i> Edit
</td>
<td>
#Ajax.ActionLink(" Delete", "DeleteEvent", "Prog", new { #id = item.ID }, new AjaxOptions { HttpMethod = "GET", UpdateTargetId = "div-record" }, new { #class = "glyphicon glyphicon-trash" })
</td>
</tr>
}
</tbody>
</table>
</div>
#model BOL3.tbl_Event
#using (Ajax.BeginForm("AddEvent", "Prog", new AjaxOptions { HttpMethod = "POST", UpdateTargetId = "div-record", OnSuccess = "$('.close').click()" }))
{
<div class="modal-body">
<div class="row form-group">
<div class="col-md-12">
<div class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-pushpin"></i></span>
#Html.TextBoxFor(m => m.Event, new { #class = "form-control" })
</div>
</div>
</div>
<div class="row form-group">
<div class="col-md-12">
<div class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span>
#Html.TextBoxFor(m => m.Start_Date, new { #class = "form-control" })
</div>
</div>
</div>
<div class="row form-group">
<div class="col-md-12">
<div class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span>
#Html.TextBoxFor(m => m.End_Date, new { #class = "form-control" })
</div>
</div>
</div>
<div class="row form-group">
<div class="col-md-12">
<div class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span>
#Html.TextBoxFor(m => m.All_Day, new { #class = "form-control" })
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-danger" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-success" name="cmd">Save</button>
</div>
}
I tried something else but that also gave me a problem (see this link: "Refresh table list using Ajax in Asp.Net Mvc") Thank you.

this problem is occuring because you have loaded <script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script> twice in the _layout page as well as index page and because of that it causes ajax to send request twice. so remove the link either from Index page or _layout page
Why it causes to submit twice?
if you look at the code of unobtrusive-ajax it has function $(document).on("click", "form[data-ajax=true] which is responsible for sending the request so when you submit the form this function trigger's differently on each script you loaded which causes the request to send twice (if someone can explain better feel free to edit)

It is because you have JS function binded to element #Add and you are not disabling anchror href correctly, thus having two requests (since your anchor has link attribute as well). In this SO question How can I disable HREF if onclick is executed? you can se, that correct click handling should be like
$('#Add').click(function (event) {
event.preventDefault();
$.get(this.href, function (response) {
$('.divForAdd').html(response);
});
$('#Add-Model').modal({
backdrop: 'static',
}, 'show');
return false; // this is essential
});

Related

how to list dropdown from VIewBag with one to many relation on a partial page?

this is my model.
This is a partial page:
#model FinalForm.Models.Employee
<div class="container">
#using (Html.BeginForm("SaveMarks", "Reg", FormMethod.Post))
{
<div class="form-group">
<button type="button" id="Submit" class="btn btn-info col-md-2" onclick="SubmitM()">Add Marks</button>
<div>
<label class="form-label col-md-1">Qualification</label>
#Html.DropDownList("Quallist", null, "Select", htmlAttributes: new { #class = "form-control search-select offerItem Item border border-dark", id = "Item", #Name = "QualificationList.Q_Name" })
#Html.ValidationMessageFor(model => model.EMP_QUALIFICATION, "", new { #class = "text-danger" })
</div>
<div>
<label class="form-label col-md-1">Marks</label>
<input type="text" id="Marks" name="Marks" class="form-control col-md-1" placeholder="" />
</div>
</div>
}
<div class="panel-body">
<table id="tbl_qlist" class="table table-bordered" cellspacing="0" width="100%">
<thead>
<tr>
<th>Q_id</th>
<th>Q_Name</th>
<th>Marks</th>
<th>Del</th>
</tr>
</thead>
</table>
</div>
</div>
this is contoller method:
[ChildActionOnly]
public ActionResult Equalify()
{
ViewBag.Quallist = new SelectList(new List<QualificationList>(), "Q_id", "Q_Name");
return PartialView("Equalify");
}
```
System.InvalidOperationException: 'There is no ViewData item of type 'IEnumerable<SelectListItem>' that has the key 'Quallist'.'

Server Side Field validation in .NET Core 3.1 MVC in modal popup not working

I have a partial view within a modal popup. Client side field validation works, such as required fields. But there are some server side validations that don't present themselves whilst keeping the modal popup open.
For example, I create a new 'teacher band' and the controller checks for a duplicate band. When I press submit, the page actually browses to the partial view and presents the error in the validationsumary, rather than keeping it within the modal.
Controller -
public async Task<IActionResult> Add()
{
CreateTeacherBandViewModel model = new CreateTeacherBandViewModel();
return PartialView(model);
}
[HttpPost]
public async Task<IActionResult> Add(CreateTeacherBandViewModel model)
{
if (ModelState.IsValid)
{
if (await _teacherBandService.BandExists(model.BandName))
{
ModelState.AddModelError("", "A band with that name already exists");
return PartialView(model);
}
else
{
await _teacherBandService.Add(model);
return RedirectToAction("Index", "TeacherBand", null);
}
}
else
{
return PartialView();
}
}
Partial View
#model Models.CreateTeacherBandViewModel
<script src="~/assets/js/plugins/pickers/color/spectrum.js"></script>
<script src="~/assets/js/demo_pages/picker_color.js"></script>
#using (Html.BeginForm("Add", "TeacherBand", null))
{
<!-- Iconified modal -->
<div id="modal_addband" class="modal fade" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header bg-primary text-white">
<h5 class="modal-title"><i class="icon-user-plus mr-2"></i> Add New Band</h5>
<button type="button" class="close" data-dismiss="modal">×</button>
</div>
<div class="modal-body">
<div class="form-group">
<label>Name</label>
#Html.TextBoxFor(model => model.BandName, new { #class = "form-control"})
#Html.ValidationMessageFor(model => model.BandName)
</div>
<h6 class="font-weight-semibold">Charge Rates</h6>
<div class="row">
<div class="col-md-4">
<div class="form-group">
<label>AM</label>
#Html.TextBoxFor(model => model.DefaultChargeRateAM, new { #class = "form-control"})
#Html.ValidationMessageFor(model => model.DefaultChargeRateAM)
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label>PM</label>
#Html.TextBoxFor(model => model.DefaultChargeRatePM, new { #class = "form-control"})
#Html.ValidationMessageFor(model => model.DefaultChargeRatePM)
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label>Daily</label>
#Html.TextBoxFor(model => model.DefaultChargeRateDaily, new { #class = "form-control"})
#Html.ValidationMessageFor(model => model.DefaultChargeRateDaily)
</div>
</div>
</div>
<h6 class="font-weight-semibold">Pay Rates</h6>
<div class="row">
<div class="col-md-4">
<div class="form-group">
<label>AM</label>
#Html.TextBoxFor(model => model.DefaultPayRateAM, new { #class = "form-control"})
#Html.ValidationMessageFor(model => model.DefaultPayRateAM)
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label>PM</label>
#Html.TextBoxFor(model => model.DefaultPayRatePM, new { #class = "form-control"})
#Html.ValidationMessageFor(model => model.DefaultPayRatePM)
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label>Daily</label>
#Html.TextBoxFor(model => model.DefaultPayRateDaily, new { #class = "form-control"})
#Html.ValidationMessageFor(model => model.DefaultPayRateDaily)
</div>
</div>
</div>
<hr />
<div class="form-group">
<label>Colour</label>
#Html.TextBoxFor(model => model.Colour, new { #class = "form-control"})
#Html.ValidationMessageFor(model => model.Colour)
</div>
#Html.ValidationSummary()
<div class="modal-footer">
<button type="button" class="btn btn-link" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-primary">Create Band</button>
</div>
</div>
</div>
</div>
<!-- /iconified modal -->
<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js">
</script>
}
Finally, the Index page that renders the partial view
#Html.Partial("Add", new CreateTeacherBandViewModel())

Repopulate Textbox in PartialView When Page Fails Validation

I have a View that besides being bound to a model, has 3 partial views (a people picker) of a reuseable component. I perform a validation to check for duplicates of the data in the model at submit. If the record is a dup, it redirects back to the page, where the model can repopulate the model fields. However, I'd like the People Picker values to be retained as well, but since it is not part of the model, I don't know how to do that.
This is the controller
public ActionResult Create(IFormCollection collection)
{
try
{
Dept_COEModel Dept = new DeptModel();
Dept.DeptName = collection["DeptName"];
Dept.DeptAcronym = collection["DeptAcronym"];
Dept.DeptCeNtId = collection["UserIdHidden_20"];
Dept.DeptCeUserName = collection["UserNameHidden_20"];
Dept.DeptCeEmail = collection["UserEmailHidden_20"];
Dept.delegate1PocNtId = collection["UserIdHidden_30"];
Dept.delegate1PocName = collection["UserNameHidden_30"];
Dept.delegate1PocEmail = collection["UserEmailHidden_30"];
Dept.delegate2PocNtId = collection["UserIdHidden_40"];
Dept.delegate2PocName = collection["UserNameHidden_40"];
Dept.delegate2PocEmail = collection["UserEmailHidden_40"];
int result = _adoSqlService.CheckDept(collection["DeptName"]);
if (result == 0)
{
_adoSqlService.InsertDept(dept);
return RedirectToAction(nameof(Index));
}
else
{
ModelState.AddModelError("DeptName", "This Department already exists");
ViewData["UserResultTextbox_20"] = Dept.DeptCeUserName;
return View(Dept);
}
}
catch
{
return View(Dept);
}
}
Here is the View
#model EDAD.Models.LOB_COEModel
#{
ViewData["Title"] = "Create";
}
<h1>Create</h1>
<h4>LOB_COE</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Create">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
#*<div class="form-group">
<label asp-for="lobCoeId" class="control-label"></label>
<input asp-for="lobCoeId" class="form-control" />
<span asp-validation-for="lobCoeId" class="text-danger"></span>
</div>*#
<div class="form-group">
<label asp-for="lobCoeName" class="control-label"></label>
<input asp-for="lobCoeName" class="form-control" />
<span asp-validation-for="lobCoeName" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="lobCoeAcronym" class="control-label"></label>
<input asp-for="lobCoeAcronym" class="form-control" />
<span asp-validation-for="lobCoeAcronym" class="text-danger"></span>
</div>
<div class="form-group">
<label class="control-label">Select Chief Engineer</label>
<div class="form-group form-field-div">
<table>
<tr style="white-space:nowrap;">
<td>
#Html.Action("PeoplePicker", "PeoplePicker", new EDAD.Models.PeoplePickerViewModel { PickerId = 20 })
</td>
<td></td>
</tr>
</table>
</div>
#*<span asp-validation-for="lobCoeCeNtId" class="text-danger"></span>*#
</div>
<div class="form-group">
<label class="control-label">Select Delegate 1</label>
<div class="form-group form-field-div">
<table>
<tr style="white-space:nowrap;">
<td>
#Html.Action("PeoplePicker", "PeoplePicker", new EDAD.Models.PeoplePickerViewModel { PickerId = 30 })
</td>
<td></td>
</tr>
</table>
</div>
#*<span asp-validation-for="lobCoeCeNtId" class="text-danger"></span>*#
</div>
<div class="form-group">
<label class="control-label">Select Delegate 2</label>
<div class="form-group form-field-div">
<table>
<tr style="white-space:nowrap;">
<td>
#Html.Action("PeoplePicker", "PeoplePicker", new EDAD.Models.PeoplePickerViewModel { PickerId = 40 })
</td>
<td></td>
</tr>
</table>
</div>
#*<span asp-validation-for="lobCoeCeNtId" class="text-danger"></span>*#
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
<a asp-action="Index">Back to List</a>
</div>
#section Scripts {
#{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
Here is the cshmtl for the People Picker (note that this is reusable so I don't want to modify any code in this)
#model ABC.Models.PeoplePickerViewModel
<script src="~/lib/jquery/jquery.js"></script>
<script src="~/js/site.js"></script>
<script>
$(function () {
setUpGlyphicons(#Model.PickerId, '#Url.Action("SearchForUsers", "PeoplePicker")');
});
</script>
<div class="people-picker">
#Html.TextBox("UserResultTextbox_" + Model.PickerId, Model.User.userName, new { #onkeypress = "userSearchKeyPress(event);", #class = "form-control input-smaller", style = "display: inline", placeholder = "Last Name, First Name", autocomplete = "off" })
#Html.Hidden("UserIdHidden_" + Model.PickerId, Model.User.NTId)
#Html.Hidden("StoredUserNameHidden_" + Model.PickerId, Model.User.userName)
#Html.Hidden("UserNameHidden_" + Model.PickerId, Model.User.userName)
#Html.Hidden("UserEmailHidden_" + Model.PickerId, Model.User.userEmail)
<span id="UserEditButton_#Model.PickerId" class="fa fa-pencil icon-inline"></span>
<span id="UserCancelButton_#Model.PickerId" class="fas fa-ban hide icon-inline"></span>
<span id="UserSearchButton_#Model.PickerId" class="fa fa-search hide icon-inline"></span>
#*<span id="InjectButtonPlaceholder_#Model.PickerId" class="hide"></span>*#
<img id="PeoplePickerLoading_#Model.PickerId" class="hide" alt="Loading..." src="~/Images/loading.gif" /><br />
<span id="PeoplePickerError_#Model.PickerId" class="error-label">*</span>
<div id="UserSearchContent_#Model.PickerId" class="list-group user-results"
onmouseout="$('.disable-scroll-container').removeClass('disable-scroll');"
onmouseover="$('.disable-scroll-container').addClass('disable-scroll');">
</div>
</div>
How can I update the fields that start with the word "User" when the view fails validation
I'm going to close this question. I discovered that the issue lies in a different direction and I'm going to post a new question.

Asp.net MVC - error after second attempt on opening a modal window

I am trying to implement bootstrap modal window when opening details. The modal window is open on ajax call. The problem is, I can only open it once. It opens with whole template, while it should not and during the second attempt I get error:
Uncaught error: modal is not a function
Then I get this error and can not open modal window any more.
Container for main view:
<div id="data-container">
#Html.Action("PartialDisplay", "Disp")
</div>
I display all data in partial view, so the controller looks like this:
public ActionResult Display()
{
return View();
}
public PartialViewResult PartialDisplay(int[] checkId)
{
if (checkId == null)
{
[my code]
return PartialView(viewModel);
}
details view:
#{
ViewBag.Title = "PartialDisplay";
Layout = null;
}
<!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Detail</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body" id="modalContent">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<table class="table">
<thead>
<tr>
<th>Nazev Jidla</th>
<th>Kategorie</th>
<th>Akce</th>
</tr>
</thead>
<tbody>
#foreach (Jidlo jidlo in Model.Jidlos)
{
<tr>
<td>
#Html.DisplayFor(modelItem => jidlo.name)
</td>
<td>
#Html.DisplayFor(modelItem => jidlo.Category.popis)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = jidlo.JidloID }) |
#Ajax.ActionLink("Details","Details", new { id = jidlo.JidloID }, new AjaxOptions(){ UpdateTargetId = "modalContent", InsertionMode = InsertionMode.Replace, OnBegin = "openModalWindow" }) |
#Html.ActionLink("Delete", "Delete", new { id = jidlo.JidloID }, new { onclick = "return confirm('opravdu smazat polozku " + jidlo.name + "?');" })
</td>
</tr>
}
</tbody>
</table>
<script type="text/javascript">
function openModalWindow() {
$('#myModal').modal("show");
}
</script>
Controller Action:
public ActionResult Details(int id = 0)
{
Jidlo jidlo = db.Jidlos.Find(id);
if (Request.IsAjaxRequest())
{
return PartialView(jidlo);
}
else {
return View(jidlo);
}
}
Layout scripts included:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="#Url.Content("~/Scripts/jquery-3.2.1.js")"></script>
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")"></script>
<script src="#Url.Content("~/Scripts/bootstrap.js")"></script>
What am I missing here? I tried to change priority for loading and couple more things like add jQuery.noConflict to script and still nothing.
Problem is loading jquery script twice
<script src="#Url.Content("~/Scripts/jquery-3.2.1.js")"></script>
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")"></script>
<script src="#Url.Content("~/Scripts/bootstrap.js")"></script>
That is correct.
Another this was removing the template markup in the details view.

Failed to load resource: the server responded with a status of 500 (Internal Server Error) dynamic api

downloaded latest(3.0) boilerplate with zero.
Followed up the task creator application implementation on codeproject.com
I have added simple entity (Clients) instead of tasks.
The displaying of tasks work fine. However, when I try to add a new client the it seems that the dynamic api is not available and I get the following error:
ClientsController:
`[AbpMvcAuthorize]
public class ClientsController : MyAppControllerBase
{
private readonly IClientAppService _clientService;
public ClientsController(IClientAppService clientService)
{
_clientService = clientService;
}
public async Task<ViewResult> Index(GetAllClientsInput input)
{
var output = await _clientService.GetAll(input);
var model = new Web.Models.Clients.IndexViewModel(output.Items);
return View("Index", model);
}
public async Task Create(CreateClientInput input)
{
await _clientService.Create(input);
}
public async Task Delete(CreateClientInput input)
{
await _clientService.Create(input);
}
}`
Index.js:
(function() {
$(function() {
var _clientService = abp.services.app.client;
var _$modal = $('#ClientCreateModal');
var _$form = _$modal.find('form');
_$form.validate();
_$form.find('button[type="submit"]').click(function (e) {
e.preventDefault();
if (!_$form.valid()) {
return;
}
var client = _$form.serializeFormToObject(); //serializeFormToObject is defined in main.js
abp.ui.setBusy(_$modal);
_clientService.create(client).done(function () {
_$modal.modal('hide');
location.reload(true); //reload page to see new user!
}).always(function () {
abp.ui.clearBusy(_$modal);
});
});
_$modal.on('shown.bs.modal', function () {
_$modal.find('input:not([type=hidden]):first').focus();
});
});
})();
Index.cshtml
#section scripts
{
<environment names="Development">
<script src="~/js/views/clients/Index.js" asp-append-version="true"></script>
</environment>
<environment names="Staging,Production">
<script src="~/js/views/clients/Index.min.js" asp-append-version="true"></script>
</environment>
}
<div class="row clearfix">
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<div class="card">
<div class="header">
<h2>
#L("Clients")
</h2>
<ul class="header-dropdown m-r--5">
<li class="dropdown">
<a href="javascript:void(0);" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
<i class="material-icons">more_vert</i>
</a>
<ul class="dropdown-menu pull-right">
<li>Action</li>
<li>Another action</li>
<li>Something else here</li>
</ul>
</li>
</ul>
</div>
<div class="body table-responsive">
<table class="table">
<thead>
<tr>
<th>#L("UserName")</th>
<th>#L("FullName")</th>
<th>#L("EmailAddress")</th>
<th>#L("IsActive")</th>
</tr>
</thead>
<tbody>
#foreach (var user in Model.Clients)
{
<tr>
<td>#user.FirstName</td>
<td>#user.LastName</td>
<td>#user.Email</td>
<td>#user.Mobile</td>
</tr>
}
</tbody>
</table>
<button type="button" class="btn btn-primary btn-circle waves-effect waves-circle waves-float pull-right" data-toggle="modal" data-target="#ClientCreateModal">
<i class="material-icons">add</i>
</button>
</div>
</div>
</div>
</div>
<div class="modal fade" id="ClientCreateModal" tabindex="-1" role="dialog" aria-labelledby="ClientCreateModalLabel" data-backdrop="static">
<div class="modal-dialog" role="document">
<div class="modal-content">
<form name="userCreateForm" role="form" novalidate class="form-validation">
<div class="modal-header">
<h4 class="modal-title">
<span>#L("CreateNewClient")</span>
</h4>
</div>
<div class="modal-body">
<div class="form-group form-float">
<div class="form-line">
<input class="form-control" type="text" name="FirstName" required maxlength="#AbpUserBase.MaxUserNameLength" minlength="2">
<label class="form-label">#L("FirstName")</label>
</div>
</div>
<div class="form-group form-float">
<div class="form-line">
<input type="text" name="LastName" class="form-control" required maxlength="#AbpUserBase.MaxNameLength">
<label class="form-label">#L("LastName")</label>
</div>
</div>
<div class="form-group form-float">
<div class="form-line">
<input type="text" name="Mobile" class="form-control" required maxlength="#AbpUserBase.MaxSurnameLength">
<label class="form-label">#L("Mobile")</label>
</div>
</div>
<div class="form-group form-float">
<div class="form-line">
<input type="email" name="Email" class="form-control" required maxlength="#AbpUserBase.MaxEmailAddressLength">
<label class="form-label">#L("Email")</label>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default waves-effect" data-dismiss="modal">#L("Cancel")</button>
<button type="submit" class="btn btn-primary waves-effect">#L("Save")</button>
</div>
</form>
</div>
</div>
</div>
client service :
[AbpAuthorize(PermissionNames.Pages_Tenants)]
public class ClientAppService : ApplicationService, IClientAppService
{
private readonly IRepository<Client> _clientRepository;
public ClientAppService(IRepository<Client> clientRepository)
{
_clientRepository = clientRepository;
}
public async Task<ListResultDto<ClientListDto>> GetAll(GetAllClientsInput input)
{
var clients = await _clientRepository
.GetAll().ToListAsync<Client>();
return new ListResultDto<ClientListDto>(
ObjectMapper.Map<List<ClientListDto>>(clients));
}
public async Task Create(CreateClientInput input)
{
var task = ObjectMapper.Map<Client>(input);
await _clientRepository.InsertAsync(task);
}
}
the server does not get hit at all on the create action.
any idea what I am missing?
I think there's a misunderstanding with IMustHaveTenant interface. When you derive an entity from IMustHaveTenant you cannot use that entity in host environment. The host has no tenant id. As far as i understand clients are belonging to tenants. So what you have to do is, remove the Clients page from host menu. Whenever you want to see clients of tenants, just use impersonation.
To show/hide specific menu items you can use requiredPermissionName. A permission can be configured to use just for tenants/host/both. So create a new permission which is configured to be used for tenants. Set that permission while you create new MenuItemDefinition for clients page. That's it!
Read => https://aspnetboilerplate.com/Pages/Documents/Navigation?searchKey=navigation#registering-navigation-provider

Resources