I have a table view with list of roles and an action link to create new roles. Below is my roles.cshtml page
#model List<ExpenCare.Models.CompanyRole>
<div class="row">
#Html.Partial("_RightSidePane")
<div class="col-10 col-sm-8 col-xs-8 col-md-10">
<div class="tab-content" id="nav-tabContent">
<div class="tab-pane fade" id="list-Roles-Content" role="tabpanel" aria-labelledby="list-Roles"></div>
#using (#Html.BeginForm("UpdateRoles", "Admin", FormMethod.Post))
{
<table class="table">
<tr>
<th>
Name
</th>
<th>
Enable
</th>
</tr>
#for (var i = 0; i < Model.Count(); i++)
{
<tr>
<td>
#Html.HiddenFor(m => m[i].Id)
#Html.HiddenFor(m => m[i].Name)
#Html.DisplayFor(m => m[i].Name)
</td>
<td>
#Html.EditorFor(m => m[i].Enabled, new { #checked = "checked" })
</td>
</tr>
}
</table>
<p><input type="submit" value="Save Changes" /></p>
<p style="color:green; font-size:12px;">#ViewBag.Message</p>
<p>
#Html.ActionLink("Create new Roles", "ViewCreateRoles", "Admin", null, new { id = "CreateRoles", #class = "appao-btn" })
</p>
}
</div>
</div>
</div>
"Create new roles" button calls to ViewCreateRoles method in admin controller, which stated below.
public ActionResult ViewCreateRoles()
{
return View("Roles/CreateRoles");
}
In CreateRoles.cshtml page user can create a role and submit. when submitting it redirects to action CreateRoles in the same admin controller.
#model ExpenCare.Models.CompanyRole
#{
ViewBag.Title = "CreateRoles";
}
<div class="row">
#Html.Partial("_RightSidePane")
<div class="col-10 col-sm-8 col-xs-8 col-md-10">
<div class="tab-content" id="nav-tabContent">
<div class="tab-pane fade show active" id="list-Profile-Content" role="tabpanel" aria-labelledby="list-Profile">
#using (Html.BeginForm("CreateRoles", "Admin", FormMethod.Post))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.Name, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Name, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Name, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Enabled, "Enable", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
<div class="checkbox">
#Html.EditorFor(model => model.Enabled)
#Html.ValidationMessageFor(model => model.Enabled, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
</div>
</div>
</div>
</div>
Below is the CreateRoles methodin admin controller.
public ActionResult CreateRoles(CompanyRole role)
{
List<CompanyRole> roles;
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("http://localhost:1888/api/");
var responseTask = client.PostAsJsonAsync("CompanyRoles", role);
responseTask.Wait();
var result = responseTask.Result;
if (result.IsSuccessStatusCode)
{
var readTask = result.Content.ReadAsAsync<List<CompanyRole>>();
readTask.Wait();
roles = readTask.Result;
return View("Roles/Roles", model: roles);
}
else
{
ViewBag.Message = "not updated.";
return View("Roles/CreateRoles");
}
}
After creating a role on success user is redirecting to roles.cshtml mentioned above which shows all the roles. My problem is that my process of adding a role (go to roles page-> create new role-> redirect to roles page) is working fine. But just after redirecting to the roles page I get "An exception of type 'System.Web.Http.HttpResponseException' occurred in ExpenCare.dll but was not handled in user code" error in my web api which is getting called in CreateRoles. when I debug the process I see that after going to "Dispose" method of admin contoller "CreateRoles" method is getting called again and null "CompanyRole role" data is passed to the web API. I dunno how it is getting called again. I checked in google and tried removing all "#" from href and src of my view and layout pages, but it is still not working. I can't find why the same method is getting called twice without the button click.
Related
I am using a modal bootstrap but my data is not loading into the bootstrap even though I am passing it trough from the controller.
My Grid pulls in data from a list for Notes Object
#foreach (var notes in Model) {
<tr>
<td>#notes.LastModifedDate</td>
<td>#notes.LastModifiedBy</td>
<td>#notes.Notes </td>
<td>
<p>#notes.Id</p> <i class="glyphicon glyphicon-pencil"></i>Edit
|<p>#notes.Id</p> <i class="glyphicon glyphicon-trash"></i>Delete
</td>
</tr>
}
I am using the following to Return the data to the popup.
public ActionResult NotesEditPopupPartial(int id ) {
var record = _context.MISNotes.Where(w => w.Id == id).FirstOrDefault();
return PartialView("NotesEditPopupPartial", record);
}
And using the following call to load the data but the data is not in the model for me to edit the text fields are still blank.
<script>
var AddOrEditNotes = function (id) {
var url = "/MISOjbects/NotesEditPopupPartial?id=" + id;
$("#myModalBodyDiv1").load(url, function () {
$("#MyEditUpateModal").modal("show");
})
}
</script>
<script>
function EditModal(id) {
$("#editMode").val(id);
}
</script>
My Modal
<div class="modal fade" id="NotesEditPopupPartial">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
×
<h3 class="modal-title">Notes Entry</h3>
</div>
<div class="modal-body" id="myModalBodyDiv1">
<div>
<input type="text" name="linkId" id="linkId" />
#using (Html.BeginForm("SaveCaseNotes", "MISObjects", FormMethod.Post, new { #id = "myNotesEditForm", #name = "myNotesEditForm", enctype = "multipart/form-data" })) {
<form id="myForm" asp-action="">
<div asp-validation-summary="All" class="text-danger"></div>
#Html.LabelFor(model => model.Title)
#Html.TextBoxFor(model => model.Title, new { #class = "form-control", #placeholder = "Title" })
#Html.ValidationMessageFor(model => model.Title, string.Empty, new { #style = "color:red;" })
<div class="form-group">
#Html.LabelFor(model => model.Notes, new { #class = "col-lg-2 control-label" })
<div class="col-lg-9">
#Html.TextAreaFor(model => model.Notes, new { #class = "form-control", #row = 5 })
</div>
</div>
#Html.LabelFor(model => model.DateActioned)
#Html.EditorFor(model => model.DateActioned, new { htmlAttributes = new { #class = "form-control datetimepicker" } })
#Html.ValidationMessageFor(model => model.DateActioned)
#Html.DisplayNameFor(model => model.LastModifiedBy)
#Html.LabelFor(model => model.LastModifiedBy)
<input name="IsValid" type="hidden" value="#ViewData.ModelState.IsValid.ToString()" />
<div class="modal-footer">
<button type="submit" id="btnEditSave" class="btn btn-primary">Save</button>
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</form>
}
</div>
<div style="text-align:center;display:none" id="loaderDiv">
<img src="~/Content/InternetSlowdown_Day.gif" width="150" />
</div>
</div>
</div>
Wrap your modal with div:
<div id="modalWrapper">
<div class="modal fade" id="NotesEditPopupPartial">
...
</div>
</div>
and then load and show the modal:
$("#modalWrapper").load(url, function () {
$("#NotesEditPopupPartial").modal("show");
})
<script>
var AddOrEditNotes = function (id) {
var url = "/MISOjbects/NotesEditPopupPartial?id=" + id;
$("#myModalBodyDiv1").load(url, function () {
$("#MyEditUpateModal").modal("show");
})
}
</script>
<script>
function EditModal(id) {
$("#editMode").val(id);
}
</script>
According to your code, I didn't find where you call the AddorEditNotes function to call the NotesEditPopupPartial action and display the partial, and in the EditModel method, you also didn't call the action method to show the partial, so, the popup modal is blank.
In my opinion, I suggest you put the bootstrap Modal on the main page (with note grid), because the trigger button (Edit hyperlink) is on this page. Then, in the hyperlink click event, you could use JQuery Ajax to call the action method and load the partial view and put it on the Bootstrap Modal.
Sample code as below:
Code in the Main page:
#model IEnumerable<NetMvcSample.Models.Note>
#{
ViewBag.Title = "ShowNotes";
}
<h2>ShowNotes</h2>
<script>
function EditModal(id) {
event.preventDefault(); // prevent the hyperlink default event.
$.ajax({
type: "POST",
url: "/Home/NotesEditPopupPartial", //change the url to your owns.
data: '{id: '+ id + "}",
contentType: "application/json; charset=utf-8",
success: function (data) {
console.log(data)
//put the partial view in the modal content.
$('#myModalBodyDiv1').html(data);
},
failure: function (response) {
console.log(response.responseText);
},
error: function (response) {
console.log(response.responseText);
}
});
}
</script>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.LastModifyDate)
</th>
<th>
#Html.DisplayNameFor(model => model.LastModifiedBy)
</th>
<th>
#Html.DisplayNameFor(model => model.Notes)
</th>
<th></th>
</tr>
#foreach (var notes in Model) {
<tr>
<td>
#notes.LastModifyDate
</td>
<td>
#notes.LastModifiedBy
</td>
<td>
#notes.Notes
</td>
<td>
<p>#notes.Id</p> <i class="glyphicon glyphicon-pencil"></i>Edit
|<p>#notes.Id</p> <i class="glyphicon glyphicon-trash"></i>Delete
</td>
</tr>
}
</table>
<div class="modal fade" id="NotesEditPopupPartial">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
×
<h3 class="modal-title">Notes Entry</h3>
</div>
<div class="modal-body" id="myModalBodyDiv1">
</div>
</div>
</div>
</div>
Code in the controller method:
[HttpPost]
public ActionResult NotesEditPopupPartial(int id)
{
var record = GetNotes().Where(c => c.Id == id).FirstOrDefault();
return PartialView("NotesEditPopupPartial", record);
}
public ActionResult SaveCaseNotes(Note note)
{
// do something
return View();
}
Code in the NotesEditPopupPartial view (NotesEditPopupPartial.cshtml):
#model NetMvcSample.Models.Note
#using (Html.BeginForm("SaveCaseNotes", "Home", FormMethod.Post))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Note</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.Id)
<div class="form-group">
#Html.LabelFor(model => model.LastModifyDate, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.LastModifyDate, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.LastModifyDate, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.LastModifiedBy, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.LastModifiedBy, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.LastModifiedBy, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Notes, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Notes, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Notes, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
The output like this:
I need to run Partial View from action method as a child action method but it redirect me to another view.
1- I tried to use Html.Action("myAction","myController") and I use [ChildActionOnly] data annotation but without any benefit
2- I tried to use Html.RenderAction("myAction", "My Controller") and I change the action method as PartialViewResult and return PartialView("View", myData) but without any benefit.
3- I tried to use JQuery AJAX but without any benefit also.
What I get
What I Expect
** This is the controller
[Authorize(Roles = "Admin")]
[HttpPost]
[ChildActionOnly]
public ActionResult _GetUserRoles(string UserName)
{
SqlParameter param1 = new SqlParameter("#UserName", UserName);
try
{
IList<GetUserRolesViewModel> roles = Identitydb.Database.SqlQuery<GetUserRolesViewModel>("admin.sp_GetUserRoles #UserName",
((ICloneable)param1).Clone()).ToArray().ToList();
return View(roles);
}
catch (Exception ex)
{
ViewBag.Error = ex.ToString();
return RedirectToAction("ErrorSaveData");
}
}
** This is PartialView Code
#model IEnumerable<AMSIdentity.Controllers.GetUserRolesViewModel>
#if (Model == null)
{
<table></table>
}
else
{
<table class="table table-responsive table-striped table-hover table-bordered table-condensed container" style="margin-top: 5%;">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.Name)
</th>
<th>
#Html.DisplayNameFor(model => model.Id)
</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.Id)
</td>
</tr>
}
</tbody>
</table>
<br />
#Html.ActionLink("Return Back", "RemoveRoleFromUser", "Manage")
}
** This is Parent Page Code
ViewBag.Title = "RemoveRoleFromUser";
var error = ViewBag.Error as IEnumerable<String>;
}
<h2> Remove role from user </h2>
<ul></ul>
<div class="row container">
<div class="col-md-6">
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.Label("Username", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.Editor("UserName", new { htmlAttributes = new { #class = "form-control" } })
</div>
<hr />
#Html.Label("Role Id", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.Editor("RoleId", new { htmlAttributes = new { #class = "form-control" } })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Remove" class="btn btn-default btn-danger" />
</div>
</div>
</div>
}
</div>
<div class="col-md-6">
<div class="row container">
<div class="col-md-12">
<h3> Get user roles </h3>
#using (Html.BeginForm("_GetUserRoles", "Manage", FormMethod.Post))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.Label("Username", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.Editor("UserName", new { htmlAttributes = new { #class = "form-control" } })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Get rules" class="btn btn-default btn-success" id="btnRules"/>
</div>
</div>
</div>
}
</div>
</div>
<div class="row container">
<div class="col-md-12">
#Html.Partial("_GetUserRoles")
</div>
</div>
</div><!--Second Column-->
</div> <!--End of row-->
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
** This is the view Model
public class GetUserRolesViewModel
{
[DisplayName("Username")]
public string Name { get; set; }
[Key]
[DisplayName("Role Id")]
public string Id { get; set; }
}
** This is AJAX Code that i used to run partial view
<script type="text/javascript">
//$(document).ready(function ()
//{
$("#btnRules").click(function (e)
{
var UserName = $("#UserName").val();
$.ajax({
url: '/Manage/_GetUserRoles',
dataType: 'html',
data:{"UserName": UserName},
success: function (data)
{
$('#listRules').html(data);
},
error: function (xhr, ajaxOptions, thrownError)
{
alert('Failed to retrieve rules.');
}
});
});
//});
</script>
** Route Picture
Route Config Picture
I expect to run the Action Method (_GetUserRoles) Partially in the same view of RemoveRoleFromUser.
your return must be a PartialView() and not a view. view() will return a complete view where as PartialView() will return a partial view. So yo need to change your
return View();
to
return PartialView("YourPartialViewName");
and if you need to pass a parameter to your partial view
return PartialView("YourPartialViewName",roles);
if you are rendering a partial view from your View them you can use Html hepler
return PartialView("~/views/ABC/PartialViewName.cshtml", Yourmodel);
I am assuming that your ajax call hits the controller action. And the partial view needs to be placed in the parent view code at-
<div class="row container">
<div class="col-md-12">
#Html.Partial("_GetUserRoles")
</div>
</div>
Based on these assumptions, you need to change few things in your code:
return PartialView instead of View from the action. Something like this:
return PartialView("_GetUserRoles", roles);
// the partial view name mentioned here is just a sample based on the context.
//You need to give your partial view's name here.
add an id attribute to the div inside which you have written #Html.Partial("_GetUserRoles"). Something like this:
<div class="row container">
<div class="col-md-12" id="userRoles">
</div>
</div>
within the success function in the ajax method, you need to use the id attribute set in above step and populate the data inside it. Something like this:
success: function (data)
{
$('#userRoles').html(data);
}
Install the Microsoft.Jquery.Unobtrusive.Ajax and Microsoft.Jquery.Unobtrusive.Validation in your project. Then add the reference of these two within your view file. Something like this:
#section scripts{
#Scripts.Render("~/Scripts/jquery{version}.js")
#Scripts.Render("~/Scripts/jquery.unobtrusive-ajax.min.js")
}
This way you should be able to see the partial view within your existing view itself.
Here is the answer
I use ViewData[""] rather than PartialView and i put one parameter in the same action result to check which view i will use.
** Action Method RemoveRoleFromUserConfirmed
public ActionResult RemoveRoleFromUserConfirmed(string UserName, string RoleId, string btnval)
{
if (btnval == "Remove")
{
if (UserName == null && RoleId == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
SqlParameter param1 = new SqlParameter("#RoleId", RoleId);
SqlParameter param2 = new SqlParameter("#UserName", UserName);
try
{
Identitydb.Database.ExecuteSqlCommand("admin.sp_RemoveUserFromRole #RoleId, #UserName", param1, param2);
}
catch (Exception ex)
{
ViewBag.Error = ex.ToString();
return RedirectToAction("ErrorSaveData");
}
return RedirectToAction("Roles");
}
else if (btnval == "Get Rules")
{
SqlParameter param1 = new SqlParameter("#UserName", UserName);
try
{
IList<GetUserRolesViewModel> roles = Identitydb.Database.SqlQuery<GetUserRolesViewModel>("admin.sp_GetUserRoles #UserName",
((ICloneable)param1).Clone()).ToArray().ToList();
string result = "";
foreach (var item in roles)
{
result += "<tr>"
+ "<td>" + item.Name + "</td>"
+ "<td>" + item.Id + "</td>"
+ "</tr>";
}
ViewData["getrules"] = result;
return View();
}
catch (Exception ex)
{
ViewBag.Error = ex.ToString();
return RedirectToAction("ErrorSaveData");
}
}
return View();
}
** This is the view
#{
ViewBag.Title = "RemoveRoleFromUser";
var error = ViewBag.Error as IEnumerable<String>;
}
<h2> Remove role from user </h2>
<ul></ul>
<div class="row container">
<div class="col-md-6">
#using (Html.BeginForm("RemoveRoleFromUser", "Manage", FormMethod.Post))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.Label("Username", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.Editor("UserName", new { htmlAttributes = new { #class = "form-control" } })
</div>
<hr />
#Html.Label("Role Id", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.Editor("RoleId", new { htmlAttributes = new { #class = "form-control" } })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Remove" name="btnval" class="btn btn-default btn-danger" />
</div>
</div>
</div>
}
</div>
<div class="col-md-6">
<div class="row container">
<div class="col-md-12">
<h3> Get user roles </h3>
#using (Html.BeginForm("RemoveRoleFromUser", "Manage", FormMethod.Post))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.Label("Username", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.Editor("UserName", new { htmlAttributes = new { #class = "form-control" } })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Get Rules" name="btnval" class="btn btn-default btn-success" id="btnRules" />
</div>
</div>
</div>
}
</div>
</div>
<div class="row container">
<div class="col-md-12" id="listRules">
<!--Data Come from ViewData-->
<table class="table table-responsive table-striped table-hover table-bordered table-condensed container" style="margin-top: 5%;">
<thead>
<tr>
<th>
Role Name
</th>
<th>
Role Id
</th>
</tr>
</thead>
<tbody>
#Html.Raw(ViewData["getrules"])
</tbody>
</table>
</div>
</div>
</div><!--Second Column-->
</div> <!--End of row-->
<div>
#Html.ActionLink("Back to List", "Roles")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
I put the name of button same in two buttons (remove and get rules)
after that i checked the value of the button in ActionMethod and if it
is remove it will do some function and if it is get rules i will use
ViewData[""] to put the view.
Regards,
Ali Mosaad
Software Developer
I would suggest changing
return View(roles);
to
return PartialView(roles);
or
return PartialView("_GetUserRoles", roles);
Using ajax
$.ajax({
url: '/Manage/_GetUserRoles',
dataType: 'html',
data:{"UserName": UserName},
success: function (data)
{
$('#listRules').html(data);
},
error: function (xhr, ajaxOptions, thrownError)
{
alert('Failed to retrieve rules.');
}
});
...
<div class="row container">
<div id="listRules" class="col-md-12">
#Html.Partial("_GetUserRoles", Model.Roles)
</div>
</div>
Im trying to load a MVC partial view in to a modal popup. The popup contains a drop down list which I am trying to populate on the ActionResult that loads when the view is loaded. The problem is the controller code isn't getting ran.
My code is as follows -
View:
<div id="modal_form_horizontal_addnote" class="modal fade">
<div class="modal-dialog modal-md">
<div class="modal-content">
<div class="modal-header bg-primary">
<button type="button" class="close" data-dismiss="modal">×</button>
<h5 class="modal-title">Add Note</h5>
</div>
#Html.Partial("AddNote", new IHD.Core.Models.CreateTicketNoteModel { TicketHeaderId = Model.Id })
</div>
</div>
The partial view:
#model IHD.Core.Models.CreateTicketNoteModel
#using (Html.BeginForm("AddNote", "Ticket", FormMethod.Post))
{
#Html.HiddenFor(model => model.TicketHeaderId)
#Html.AntiForgeryToken()
<div class="row">
<div class="col-md-12">
<div class="tab-content">
<div class="tab-pane active" id="highlighted-justified-tab1">
<div class="form-group">
#Html.LabelFor(model => model.WorkType, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-12">
#Html.DropDownListFor(model => model.WorkType, new SelectList(Model.WorkTypeOptions, "Key", "Value", Model.WorkType), new { #name = "select", #class = "form-control" })
#Html.ValidationMessageFor(model => model.WorkType, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
</div>
</div>
}
The controller:
public ActionResult AddNotePhase(int id = 0, int taskId = 0)
{
CreateTicketPhaseNoteModel note = new CreateTicketPhaseNoteModel();
note.TicketHeaderId = id;
// Populate the work type dropdown list
note.WorkTypeOptions.Add("", "-- Select a Work Type --");
note.WorkTypes = _workTypeService.GetAll().ToList();
foreach (var c in note.WorkTypes)
{
note.WorkTypeOptions.Add(c.Id.ToString(), c.Description);
}
//note.PhaseTask = taskId;
return PartialView(note);
}
You controller code isn't being hit because you are passing a model to the partial view and not calling the action. You need to use #{Html.RenderAction();} instead to call your action with the appropriate values.
I have an MVC application that allows customers to log in and submit any queries they are experiencing, they enter their name and describe their issue.This query is then sent to our support email address via our server email, in doing so I need to include the user's logged in email address as a string in the email. I've tried a few ways but I experience run time error as the email field returns null.
My controller:This is in my controller method for the email
Email.Body = $"<p><b>Name:</b> {support.UserNameSurname}</p> <p><b>Email:</b> {support.Email=User.Identity.GetUserName()}</p> <p><b>Message:</b> {support.SupportMessage}</p>";
The View
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="col-sm-offset-3 col-sm-6">
<div class="form-horizontal">
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.UserNameSurname, "Full Name" , htmlAttributes: new { #class = "control-label col-md-3" })
<div class="col-md-9">
#Html.EditorFor(model => model.UserNameSurname, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.UserNameSurname, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.SupportMessage,"Describe Issue", htmlAttributes: new { #class = "control-label col-md-3" })
<div class="col-md-9">
#Html.TextAreaFor(model => model.SupportMessage, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.SupportMessage, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Request Help" class="btn btn-default" style="background-color: #0a9dbd;-webkit-text-fill-color: white; border-color: #0a9dbd; height: 40px; float:right;" />
</div>
<div>
#Html.ActionLink("Back to List", "CustomerView")
</div>
</div>
</div>
</div>
}
If i had to put what i wrote as an answer, you can go
public static string GetUserEmail(this HttpSessionState session)
{
if(Session["Email"] != null)
{
Session["email"] = ..Set Session email here
}
return session["Email"]
}
then you can either create a set session method or just use the Session["key"] to set the value, then you will have access to your email.
I followed an online tutorial to dynamically add items to a bound list model using ajax, which works perfectly. (http://www.mattlunn.me.uk/blog/2014/08/how-to-dynamically-via-ajax-add-new-items-to-a-bound-list-model-in-asp-mvc-net/comment-page-2/#comment-68909)
My question is, how would I correctly remove items from the list?
Right now what I have done is add a delete link which when clicked removes the item from the view. However, when I submit the form I noticed that the modelState is no longer valid and it has null entries for the item that was removed from the view. So I guess the model is not being updated.
Test.cshtml
#model TesterManager.Models.Test
<div class="form-group">
#Html.LabelFor(model => model.Software, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
<div class="form-group">
<div class="col-md-5">
#Html.DropDownListFor(m => m.Software, TesterManager.Models.Helper.GetTestSoftwares(), "Choose a USB Card", new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.Software, "", new { #class = "text-danger" })
</div>
<div class="col-md-5">
#Html.EditorFor(model => model.Version, new { htmlAttributes = new { #class = "form-control", #title = "Enter a USB FW Version", #placeholder = "Enter a USB FW Version" } })
#Html.ValidationMessageFor(model => model.Version, "", new { #class = "text-danger" })
</div>
<div class="col-md-2">
Delete
</div>
</div>
</div>
</div>
AdminTesterConfigurations.cshtml (snippet):
#model TesterManager.Models.AdminTesterConfigurations
<div class="form-group">
<div class="col-md-6">
....
</div>
</div>
<hr />
<div class="form-group">
<div class="col-md-12">
<h3>Test Software</h3>
<div id="test-list">
#Html.EditorForMany(x => x.Tests, x => x.Index)
</div>
<input type="button" id="add-test" value="Add" />
</div>
</div>
RequestEditViewModel.cshtml:
#model TesterManager.Models.RequestEditViewModel
<div class="form-horizontal">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.EditorFor(model => model.ShippingLocation)
#Html.EditorFor(model => model.RequesterTesterConfigurations)
#Html.EditorFor(model => model.AdminTesterConfigurations)
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
Edit.cshtml:
#model TesterManager.Models.RequestEditViewModel
#Styles.Render("~/Content/Edit")
#{
ViewBag.Title = "Edit";
Layout = "~/Views/Shared/_Layout.cshtml";
}
#section Scripts
{
<script>
jQuery(document).ready(function ($) {
$('#add-test').on('click', function () {
jQuery.get('/TesterManager/Request/AddTest').done(function (html) {
$('#test-list').append(html);
});
});
});
</script>
}
#using (Html.BeginForm())
{
<h2>Edit</h2>
#Html.AntiForgeryToken()
#Html.EditorFor(x => x);
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
RequestController.cs
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(RequestEditViewModel request)
{
if (ModelState.IsValid)
{
Request domainRequest = new Request(request);
requests.Add(domainRequest);
return RedirectToAction("Index");
}
return View(request);
}
[OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
public ActionResult AddTest()
{
var request = new RequestEditViewModel();
request.AdminTesterConfigurations.Tests.Add(new Test());
return View(request);
}
I realized that the problem was that when I would remove the item from the list in the view, I was not removing the hidden input for the collection indexer as well. I updated the code to remove the hidden input and it works fine now.