in my View I have something like this:
<div class="form-group">
<form asp-controller="Ticket" asp-action="Comment" method="post">
<label asp-for="Comment" class="control-label"></label>
<textarea asp-for="Comment.Content" class="form-control" placeholder="Add comment!"></textarea>
<span asp-validation-for="Comment.Content" class="text-danger"></span>
</form>
<input type="submit" value="Add comment" class="btn btn-default" />
This is in my Details View. Now I want to add comment to my model
public class TicketCommentViewModel
{
public Ticket Ticket { get; set; }
public Comment Comment { get; set; }
}
and Controller:
public async Task<IActionResult> Comment(TicketCommentViewModel model)
{
var ticket = await _context.Tickets.FirstOrDefaultAsync(u => u.TicketId == model.Ticket.TicketId);
var user = await GetCurrentUserAsync();
if(ticket == null)
{
return NotFound();
}
model.Comment.SendTime = DateTime.Now;
model.Comment.TicketID = ticket.TicketId;
model.Comment.Ticket = ticket;
model.Comment.UserId = user.Id;
model.Comment.User = user;
_context.Comments.Add(model.Comment);
ticket.Comments = await _context.Comments.ToListAsync();
return View();
}
I have problem with this -> How to go from first code (add Comment) to Controller, and add my Comment to DB.
Can someone help me with that ?
Thanks.
I am not sure what is the problem but I guess that when you click submit your data is not submitted. This is because your submit button is outside the <form>. Try move the submit button inside the <form>
//Two action methods in the controller
public ActionResult AddComment(int PageId, string name, string email, string comment)
{
Comment comment = new Comment()
{
PageID = PageId,
Name = name,
Email = email,
Comment = comment,
CreateDate = DateTime.Now
};
DbContext.Add(jobOffer);
return PartialView("ShowComments", DbContext.Where(c=> c.pageID == PageId));
}
public ActionResult ShowComments(int PageId)
{
return PartialView(DbContext.Where(c=> c.pageID == PageId));
}
//Add the script after the comment div in the View
<script>
function addComment() {
$.ajax({
url: "/Comment/AddComment/"+#Model.PageID,
type: "Get",
data: {
name: $("#txtName").val(), email: $("#txtEmail").val(),
comment : $("#txtComment").val() }
}).done(function(result) {
$("#offerList").html(result);
$("#txtName").val("");
$("#txtEmail").val("");
$("#txtComment").val("");
});
}
</script>
Related
I have a page, where I do a search. Then I can make some actions on results of the search.
Here the page:
#page "{handler?}"
#model Pricelists.ListModel
<form>
<div><label><input autocomplete="off" type="checkbox" asp-for="OnlyEnabled" /> Only enabled</label></div>
//all other filters used in the search
<input type="submit" formmethod="get" asp-page-handler="Search" />
#if (Model.SearchResult.PaginatedResults != null)
{
<input type="hidden" asp-for="PageNumber" value="#Model.PageNumber" />
<input type="hidden" asp-for="TotalPages" value="#Model.TotalPages" />
<table>
<tr>
//header result
</tr>
#foreach (var item in Model.SearchResult.PaginatedResults)
{
<tr>
//result
</tr>
}
</table>
<label>Page #Model.PageNumber of #Model.TotalPages (Number of records: #Model.SearchResult.Count)</label>
<input type="submit" formmethod="get" asp-page-handler="Previous" value="<" />
<input type="submit" formmethod="get" asp-page-handler="Next" value=">" />
<div>
<input type="submit" formmethod="post" asp-page-handler="Enable" value="Enable" />
<input type="submit" formmethod="post" asp-page-handler="Disable" value="Disable" />
<input type="submit" formmethod="post" asp-page-handler="Delete" value="Delete" />
</div>
}
</form>
As you can see, either when I do the search or when I change the page, I submit the form using GET.
But I would like to make a POST submit to modify (enable, disable or delete) the result of the search.
Here the PageModel:
public class ListModel : PageModel
{
private const int RECORDS_PER_PAGE = 20;
private readonly AdminApiClient _client;
#region Selected Filters
[BindProperty(SupportsGet=true)]
public bool OnlyEnabled { get; set; }
[BindProperty(SupportsGet = true)]
public long[] SelectedCategories { get; set; }
[BindProperty(SupportsGet = true)]
public string[] SelectedCarriers { get; set; }
[BindProperty(SupportsGet = true)]
public string[] SelectedDepartures { get; set; }
[BindProperty(SupportsGet = true)]
public string[] SelectedArrivals { get; set; }
[BindProperty(SupportsGet = true)]
public int PageNumber { get; set; }
[BindProperty(SupportsGet = true)]
public int TotalPages { get; set; }
#endregion
[BindProperty(SupportsGet = true)]
public PriceListSearchViewModel SearchResult { get; set; }
public ListModel(AdminApiClient clientFactory)
{
_client = clientFactory;
}
public async Task OnGet()
{
await this.LoadViewDataAsync();
}
public async Task OnGetSearch()
{
this.PageNumber = 1;
await this.LoadViewDataAsync();
this.SearchResult = await this._client.Pricelists.Search(this.SelectedCategories, this.SelectedCarriers, this.SelectedDepartures, this.SelectedArrivals, this.OnlyEnabled, this.PageNumber, RECORDS_PER_PAGE);
this.TotalPages = (int)Math.Ceiling(this.SearchResult.Count / (decimal)RECORDS_PER_PAGE);
}
public async Task OnGetNext()
{
...
}
public async Task OnGetPrevious()
{
...
}
public async Task OnPostEnable()
{
await this.LoadViewDataAsync();
await this._client.Pricelists.ChangeStatus(this.SelectedCategories, this.SelectedCarriers, this.SelectedDepartures, this.SelectedArrivals, this.OnlyEnabled, this.PageNumber, RECORDS_PER_PAGE, enable: true);
}
public async Task OnPostDisable()
{
await this.LoadViewDataAsync();
await this._client.Pricelists.ChangeStatus(this.SelectedCategories, this.SelectedCarriers, this.SelectedDepartures, this.SelectedArrivals, this.OnlyEnabled, this.PageNumber, RECORDS_PER_PAGE, enable: false);
}
public async Task OnPostDelete()
{
await this.LoadViewDataAsync();
await this._client.Pricelists.Delete(this.SelectedCategories, this.SelectedCarriers, this.SelectedDepartures, this.SelectedArrivals, this.OnlyEnabled, this.PageNumber, RECORDS_PER_PAGE);
}
}
To semplify I let you see just one GET and one POST method. But, in any case I use same binded properties.
Now, when I make a GET submit everything works correctly. But when I make a POST submit I get an error 400 Bad request. I let you see a fiddler:
The http request is what I expected, but obviously not the response.
Any idea?
EDIT
I never go in the methods OnPost*. It is like the way I have implemented the submit button is wrong. The problem is not the implementation of the OnPost* methods.
Thank you
You have two options, Separate forms and write a form for each method. or jsut handle it using javascript.
look at this sample:
<form id="frm" action="/test" method="post">
<button type="submit">save</button>
and script:
<script>
setTimeout(function () {
var frmElement = document.getElementById('frm');
frmElement.setAttribute('method', 'get')
}, 2000)
</script>
try to remove form that you have and make a special form for each button
<form asp-page-handler="delete" method="post">
<button class="btn btn-default">Delete</button>
</form>
.... and so on
You can try to add method="post" to <form>.Example:<form method="post">.
I test with your code,when click the inputs with formmethod="post",it will lose __RequestVerificationToken in the form data.And after you add method="post" to form,it will have a hidden input as the following shows:
result:
I've got a class Cart with property Lines which returns me a collection of type CartLine. here is my two classes Cart ad CartLine
public class Cart
{
private List<CartLine> lineCollection = new List<CartLine>();
public String Currency { get; set; }
public void UpdateCart(int ArticleID, string selectedQuantityType, int Quantity)
{
CartLine line = lineCollection.Where(p => p.Product.ArticleID == ArticleID).FirstOrDefault();
if (line != null)
{
line.SelectedQuantityType = selectedQuantityType;
line.Quantity = Quantity;
}
}
public IEnumerable<CartLine> Lines
{
get { return lineCollection; }
}
}
<
And here is my class CartLine
public class CartLine
{
public CartLine()
{
this.QuantityType= new List<QuantityType>();
}
public WebServiceBeaMenu Product { get; set; }
public int Quantity { get; set; }
public string Currency { get; set; }
public string SelectedQuantityType { get; set; }
}
I've got two actions which returns me strongly typed PartialView - CartIndexViewModel with two properties - one from Type Cart
public ActionResult CartPartial(string returnUrl)
{
return PartialView(new CartIndexViewModel
{
Cart = GetCart(),
ReturnUrl = returnUrl
});
}
[HttpPost]
public ActionResult CartPartial(CartLine line)
{
Cart crt = GetCart();
crt.UpdateCart(line.Product.ArticleID, line.SelectedQuantityType, line.Quantity);
return PartialView(new CartIndexViewModel
{
Cart = crt
});
}
private Cart GetCart()
{
Cart cart = (Cart)Session["Cart"];
if (cart == null)
{
cart = new Cart();
Session["Cart"] = cart;
}
return cart;
}
ANd here is my view whih loop through all thre cartlines of my cart and display their quantity and quantityType.
The problem is as you see for each CartLine I'm making an ajax form so when there is a change in the quantity of a CartLine (when there is a change in this helper #Html.TextBoxFor(x => line.Quantity,new { id = #liine.Product.ArticleID, onchange="SubmitForm(this.id)" })) you see that I submit the form to the httppost form of my CartPartial Action. The first time when I submit the form there is no problem and thanks to mvc model binding my CartLine parameter is filled with the data I need. The problem is when this action returns me the same view with the updated data after that if I try to change a quantity and submit the form for the second time my CartLine parameter is empty. What may be the reason. Thankls in advance.
#model MvcBeaWeb.Models.CartIndexViewModel
<div id="cartContainer">
<table width="100%" align="center" style="margin:auto;border-collapse:collapse;">
<tbody>
#foreach(var line in Model.Cart.Lines)
{
<tr style="height:90px" >
#using (Ajax.BeginForm("CartPartial", null, new AjaxOptions { UpdateTargetId = "centerCartBody", InsertionMode = InsertionMode.Replace }, new { id = "form" + #line.Product.ArticleID }))
{
<td align="left">#line.Product.SpecialWord</td>
<td >
<div class="inner-content">
#Html.TextBoxFor(x => line.Quantity,new { id = #liine.Product.ArticleID, onchange="SubmitForm(this.id)" })
<span class="qty-type">
#Html.DropDownListFor(x => line.SelectedQuantityType, new SelectList(line.QuantityType, "QuantityID", "Description"))
</span>
</div>
</td>
#Html.HiddenFor(x => line.Product.ArticleID, "Value");
}
</tr>
}
</tbody>
</table>
<div >
#using (Html.BeginForm("Index/","Confirmation"))
{
<input type="submit" id="btnCheckOut" />
}
</div>
</div>
</div>
</div>
script>
function SubmitForm(id)
{
$("#form_" + id).submit();
}
</script>
I've looking all over for something similar, couldn't find nothing..
I'm using ASP.NET MVC 4. I'm building a page so the users in my app can manage the permissions associated with each role.
So i have a view with #htmlDropDownList to show all the available roles, and below, one #Html.CheckBox for each Permission of the role wich is selected above.
The first time the view is rendered, the checkboxes are all set to true or false, according to the permission of that role.All is fine, life is good :) . When the value of the drop is changed, i post the SelectedRoleId using $.ajax. Then, i fetch all the permissions of the new selected role.
While in debug, in the razor view, i can confirm the new values (true or false) inside the model are correct. The problem is that the checkboxes show the old values, before the role was changed..
This is my first question asked, so i'll have to apologize if the question is not being made the best way.
And thx in advance to all of you :)
So here's my Controller:
public ActionResult Index(int ? SelectedRoleId)
{
ManagePermissionsViewModel model = new ManagePermissionsViewModel();
if (SelectedRoleId == null)
{
model.SelectedRoleID = 1; // value 1 is the supervisor Role
}
else
{
model.SelectedRoleID = SelectedRoleId;
}
//values for the dropdownlist of Roles
var items = from x in db.UserRoles
select x;
model.RoleList = new SelectList(items, "Id", "DESCRIPTION");
//gets all the permissions of the selected role
model.EntirePermissionList = (from k in db.Permissions
select new Permission
{
IdPermission = k.Id,
PermissionDescription = k.Description,
IsSet = db.RolePermissions.Any(n => n.RoleId == model.SelectedRoleID && n.PermissionId == k.Id),
PermissionGroupId = (int)k.PermissionGroupId
}).ToList();
//Gets all the groups of Permissions
model.ListPermissionGroups = (from l in db.PermissionGroups
select new PermissionGroup
{
Id = l.Id,
Description = l.Description
}).ToList();
return View(model);
}
[HttpPost]
public ActionResult Index(FormCollection form) {
switch (form["SubmitButton"])
{
case "Save":
SavePermissions();
break;
default:
return RedirectToAction("Index", new RouteValueDictionary(new { controller = "ManagePermissions", action = "Index", SelectedRoleId = Convert.ToInt32(form["SelectedRoleId"]) }));
}
return View();
}
And here is my View:
'#model AML.Web.Models.ManagePermissionsViewModel
#using (Html.BeginForm("Index", "ManagePermissions", FormMethod.Post, new { id = "MyForm" }))
{
#Html.Label("Role :", htmlAttributes: new { #class = "control-label col-md-2" })
#Html.DropDownList("RoleId", Model.RoleList, new { id = "RoleId" })
<div>
#foreach (var item in Model.ListPermissionGroups)
{
<h3> #item.Description</h3>
foreach (var permission in Model.EntirePermissionList.Where(n => n.PermissionGroupId == item.Id))
{
<h5>
#permission.PermissionDescription
#Html.CheckBox("Chk_Permisssion", permission.IsSet)
</h5>
}
}
</div>
<input type="submit" value="Save" name="SubmitButton" class="btn btn-default" />
}
#section Scripts {
<script type="text/JavaScript">
$(document).ready(function () {
$("#RoleId").change(function (e) {
e.preventDefault();
$.ajax({
url: "/ManagePermissions/Index",
cache: false,
type: "POST",
data: { 'SelectedRoleId': $(this).val() },
dataType: "json",
success: function (result) { console.log("Sucess!"); },
error: function (error) { console.log("Error!"); }
})
});
});
</script>
}
And my viewModel:
public class ManagePermissionsViewModel
{
public int? SelectedRoleID { get; set; }
public string SelectedRoleDescription { get; set; }
public SelectList RoleList { get; set; }
public List<Permission> EntirePermissionList { get; set; }
public List<PermissionGroup> ListPermissionGroups { get; set; }
}
public class Permission
{
public int IdPermission { get; set; }
public bool IsSet { get; set; }
public string PermissionDescription { get; set; }
public int PermissionGroupId { get; set; }
}
public class PermissionGroup {
public int Id { get; set; }
public string Description{ get; set; }
}
UPDATE 1 -
Well, i think i got it. Let me post my approach
In the View:
#Html.DropDownListFor(n => n.SelectedRoleID, Model.RoleList,null,
new { onchange = "document.location.href = '/ManagePermissions/Index?SelectedRoleId=' + this.options[this.selectedIndex].value;" })
<div>
#foreach (var item in Model.ListPermissionGroups)
{
<h3> #item.Description</h3>
foreach (var permission in Model.EntirePermissionList.Where(n => n.PermissionGroupId == item.Id))
{
<h5>
#permission.PermissionDescription
<input type="checkbox" id="#permission.IdPermission" checked="#permission.IsSet">
</h5>
}
}
</div>
And in the Controller:
public ActionResult Index(int? SelectedRoleId)
{
ManagePermissionsViewModel model = new ManagePermissionsViewModel();
ModelState.Clear();
if (SelectedRoleId == null)
{
model.SelectedRoleID = 1;
}
else
{
model.SelectedRoleID = SelectedRoleId;
}
var items = from x in db.UserRoles
select x;
model.RoleList = new SelectList(items, "Id", "DESCRIPTION");
model.EntirePermissionList = (from k in db.Permissions
select new Permission
{
IdPermission = k.Id,
PermissionDescription = k.Description,
IsSet = db.RolePermissions.Any(n => n.RoleId == model.SelectedRoleID && n.PermissionId == k.Id),
PermissionGroupId = (int)k.PermissionGroupId
}).ToList();
model.ListPermissionGroups = (from l in db.PermissionGroups
select new PermissionGroup
{
Id = l.Id,
Description = l.Description
}).ToList();
ModelState.Clear();
return View(model);
}
Now each time the Drop changes value, the permissions in the checkboxes are updated. I got it to work with the attribute on the drop, "on change = Document.location.hef = URL". Is this a good approach? Or should i use something like ajax request ?
UPDATE 2
The Controller:
public async Task<ActionResult> Index(int? SelectedRoleId)
{
if (SelectedRoleId == null)
{
SelectedRoleId = 1;
}
var model = await GetSelectedPermissions(SelectedRoleId);
return this.View("Index",model);
}
[HttpGet]
public async Task<ActionResult> GetPermissions(string Id)
{
var SelectedRoleId = int.Parse(Id);
var model = await this.GetSelectedPermissions(SelectedRoleId);
return PartialView("_ManagePermissions", model);
}
private async Task<ManagePermissionsViewModel> GetSelectedPermissions(int? SelectedRoleId)
{
ModelState.Clear();
ManagePermissionsViewModel model = new ManagePermissionsViewModel();
model.SelectedRoleID = SelectedRoleId;
var items = from x in db.UserRoles
select x;
model.RoleList = new SelectList(items, "Id", "DESCRIPTION");
model.EntirePermissionList = await (from k in db.Permissions
select new Permission
{
IdPermission = k.Id,
PermissionDescription = k.Description,
IsSet = db.RolePermissions.Any(n => n.RoleId == model.SelectedRoleID && n.PermissionId == k.Id),
PermissionGroupId = (int)k.PermissionGroupId
}).ToListAsync();
model.ListPermissionGroups = await (from l in db.PermissionGroups
select new PermissionGroup
{
Id = l.Id,
Description = l.Description
}).ToListAsync();
return model;
}
The View
<h2>Permissions - Ajax with Partial View</h2>
#using (Html.BeginForm("SaveData", "ManagePermissions", FormMethod.Post, new { id = "MyForm" }))
{
#Html.Label("Role :", htmlAttributes: new { #class = "control-label col-md-2" })
#Html.DropDownListFor(n => n.SelectedRoleID, Model.RoleList, null, null)
<div id="target">
#Html.Partial("~/Views/Shared/_ManagePermissions.cshtml", Model)
</div>
<input type="submit" value="Save" name="SubmitButton" class="btn btn-default" />
}
#section Scripts {
<script type="text/javascript">
$(document).ready(function () {
$("#SelectedRoleID").change(function () {
var SelectedRoleID = $("#SelectedRoleID").val();
$("#target").load('#(Url.Action("GetPermissions","ManagePermissions",null, Request.Url.Scheme))?Id=' + SelectedRoleID);
});
});
</script>
}
And the Partial View:
<div>
#foreach (var item in Model.ListPermissionGroups)
{
<h3> #item.Description</h3>
foreach (var permission in Model.EntirePermissionList.Where(n => n.PermissionGroupId == item.Id))
{
<h5>
#permission.PermissionDescription
<input type="checkbox" id="#permission.IdPermission" checked="#permission.IsSet">
</h5>
}
}
</div>
I've been trying to pass a model to a partial view with a form. Some of the model fields are already assigned in the GET request. When the form loads I can see the model fields values but after
submiting the form I get this error in this line: #Html.Hidden("From",Model.From):
Object reference not set to an instance of an object
Why these two fields are assigned with null on submit?
My controllers:
[HttpGet]
public ActionResult SendPrivateMessage(string from, List<string> to)
{
// two of the fields are already assigned
return PartialView("SendMessage", new MessageModel(from,to));
}
[HttpPost]
public ActionResult SendPrivateMessage(MessageModel m)
{
string fullname = "";
LoginModel loginData = (LoginModel)(Session["user"]);
if (Session["user"] != null)
{
fullname = loginData.LoginDS.Tables[0].Rows[0][loginData.LoginDS.Tables[0].Columns["fullname"].Ordinal].ToString();
}
m.fullname = fullname;
m.Send();
return PartialView("SendMessage");
}
The partial view:
#model HaifanetMobile.Models.MessageModel
<div id="contact_form">
<a id="back_contact" href="#" style="float:left">
<img style="height:20px; width:30px;" src="~/Images/back_btn.gif" alt="back" />.
</a>
<div id="contactus_title">
<div id="close_contactus" style="float:right"><img style="height:20px; width:20px;" src="~/Images/close_btn.gif" /></div>
</div>
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<br />
<fieldset>
#Html.Hidden("From", Model.From) //this is where I get the error
#Html.Hidden("To", Model.To)//this is where I get the error
<div>
#Html.TextBoxFor(m => m.Subject, new { #class = "", placeholder = "subject:", id = "msg_subject", onfocus = "this.placeholder = ''", onblur = "this.placeholder = 'subject:'" })
#Html.ValidationMessageFor(m => m.Subject, "required")
</div>
<div>
#Html.TextAreaFor(m => m.Content, new { #class = "", id = "msg_textarea" })
#Html.ValidationMessageFor(m => m.Content, "required")
</div>
</fieldset>
<p>
<input type="submit" value="send" />
</p>
}
</div>
The Model:
public class MessageModel
{
public string From { get; set; }
public List<string> To { get; set; }
public string Subject {get; set;}
public string Content { get; set; }
public string fullname { get; set; }
public MessageModel(string from, List<string> to)
{
// TODO: Complete member initialization
this.From = from;
this.To = to; ;
}
public MessageModel() {
}
public void Send()
{
ServiceReference2.WebService1Soap ws = new ServiceReference2.WebService1SoapClient();
if (!ws.SendMessage(this.From, this.Content, this.Subject, this.To.ToArray() ,this.fullname))
throw new Exception();
}
}
Thanks in advance
You're forgetting to pass the model to your view.
When you return this view, instead of this:
return PartialView("SendMessage");
you must do this:
return PartialView("SendMessage", m);
Where m is your model. That's why the model is null inside your view.
I am trying to use a variation of the code from this page:
Multiple button in MVC
But everytime I click on the buttons it goes to the index actionresult method and not one of the button methods. Index is the view name but the button clicks are happening in a partial view called "P_NewPersonForm.cshtml"
P_NewPersonForm.cshtml
#using (Html.BeginForm())
{
<div id="divClaimType">
#Html.Label("Claim type:")
#Html.DropDownListFor(m => m.modelClaim.ClaimType, new List<SelectListItem>
{
new SelectListItem{ Text="Legal", Value = "Legal" },
new SelectListItem{ Text="Immigration", Value = "Immigration" },
new SelectListItem{ Text="Housing", Value = "Housing" }
})
</div>
<div id="divClaimStatus" style="padding: 5px;">
#foreach(var item in Model.LinkerStatusOfClaim)
{
#Html.Label("Claim status:")
#Html.DropDownListFor(m => m.LinkerStatusOfClaim[0].ClaimStatusID, new SelectList(Model.modelClaimStatus, "ClaimStatusID", "ClaimStatus"))
#Html.LabelFor(m => m.LinkerStatusOfClaim[0].Notes)
#Html.TextAreaFor(m => m.LinkerStatusOfClaim[0].Notes)
#Html.LabelFor(m => m.LinkerStatusOfClaim[0].StartDate)
#Html.TextBoxFor(m => m.LinkerStatusOfClaim[0].StartDate, new { #id = "datepicker", #Value = DateTime.Now, #readonly = true, Style = "background:#cccccc;" })
<br />
#Html.ValidationMessageFor(model => model.LinkerStatusOfClaim[0].StartDate)
<br />
}
<input type="submit" value="Add another status to this claim..." name="action:add"/>
<input type="submit" value="Delete status." name="action:remove"/>
#* #Ajax.ActionLink("Add another status to this claim...", "AddClaim", "Client", new AjaxOptions { HttpMethod = "POST"})*#
</div>
}
</div>
I have one button for adding to the collection of claims and another to remove one from the collection.
ClientController
public ActionResult Index()
{
var Model = new modelPersonClaim();
// Add one item to model collection by default
LinkerStatusOfClaim LinkerStatusOfClaim = new LinkerStatusOfClaim();
Model.LinkerStatusOfClaim.Add(LinkerStatusOfClaim);
DataLayer.RepositoryClient RC = new RepositoryClient();
Model.isValidModel = true;
RC.GetClaimTypes(Model, PersonTypes.NewPerson.ToString());
return View(Model);
}
[HttpPost]
public ActionResult P_NewPersonForm(modelPersonClaim Model)
{
DataLayer.RepositoryClient RC = new RepositoryClient();
RC.GetClaimTypes(Model, PersonTypes.NewPerson.ToString());
Model.isValidModel = ModelState.IsValid;
if (ModelState.IsValid)
{
RC.CreatePerson(Model);
Model.SuccessfulInsert = true;
Model.InsertString = "Person data has been successfully inserted into the database.";
if (Model.modelClaim.ClaimMade)
{
RC.CreateClaim(Model);
}
}
else
{
Model.SuccessfulInsert = false;
Model.InsertString = "Person data could not be inserted into the database. Missing key fields.";
}
return View("Index", Model);
}
[AttributeUsage(AttributeTargets.Method, AllowMultiple=false, Inherited = true)]
public class MultiButtonAttribute : ActionNameSelectorAttribute
{
public string Name { get; set; }
public string Argument { get; set; }
public override bool IsValidName(ControllerContext controllerContext, string actionName, MethodInfo methodInfo)
{
var isValidName = false;
var keyValue = string.Format("{0}:{1}", Name, Argument);
var value = controllerContext.Controller.ValueProvider.GetValue(keyValue);
if (value != null)
{
controllerContext.Controller.ControllerContext.RouteData.Values[Name] = Argument;
isValidName = true;
}
return isValidName;
}
}
[HttpPost]
[MultiButtonAttribute(Name = "action", Argument = "Add another status to this claim...")]
public ActionResult AddClaimStatus(modelPersonClaim Model)
{
Model.LinkerStatusOfClaim.Insert(Model.LinkerStatusOfClaim.Count, new LinkerStatusOfClaim());
return View("Index", Model);
}
[HttpPost]
[MultiButtonAttribute(Name = "action", Argument = "Delete status.")]
public ActionResult RemoveClaimStatus(modelPersonClaim Model)
{
// Can't remove IF only 1
if (Model.LinkerStatusOfClaim.Count == 1)
{
}
else
{
Model.LinkerStatusOfClaim.RemoveAt(Model.LinkerStatusOfClaim.Count);
}
return View("Index", Model);
}
When I click one the buttons it hits the public override bool IsValidName twice. Once for each button. But then because the action name is always index, it goes to the index method and not one of the button methods.
Does anyone have any ideas how to fix this?
Something is wrong with this part:
var keyValue = string.Format("{0}:{1}", Name, Argument);
var value = controllerContext.Controller.ValueProvider.GetValue(keyValue);
Your attribute is this:
[MultiButtonAttribute(Name = "action", Argument = "Add another status to this claim...")]
So in that case keyValue will become: "action:Add another status to this claim..." while your HTML states: <input type="submit" value="Add another status to this claim..." name="action:add"/>, so I think Argument in your attribute should be add.