Pass ID via Html.BeginForm and Ajax.ActionLink - c#

I'm currently trying to find out what´s the MVC-way to solve the following problem:
I have a table (index view) based on a model and my first row has a button to change one cell of this row. When the button is pressed a popup is shown (via Ajax.ActionLink), which asks for an additional comment. The popup view is realised with a Partial View and a Html.BeginForm. After adding a comment and clicking the submit button the updated index view is shown.
At the moment I calculate the id of the first-row item before the updated index view is shown, because I don't know how to pass this id via the Ajax.ActionLink at first and the Html.BeginForm afterwards.
The whole process looks like this:
Ajax.ActionLink in Index View:
#Ajax.ActionLink("Update", "Update", null,
new AjaxOptions { HttpMethod = "GET", UpdateTargetId = "result", InsertionMode = InsertionMode.Replace, OnSuccess = "openPopup()" },
new { #class = "btn btn-info"})
Update Partial View:
#using (Html.BeginForm("Index"))
{
<div class="form-group">
<h4>Title</h4>
<p>Comment here:</p>
<textarea type="text" class="form-control" name="comment" id="comment" required></textarea>
</div>
<input type="submit" value="Update" class="btn btn-info" />
}
ActionResults in Controller
[HttpGet]
public PartialViewResult Update()
{
return PartialView();
}
[HttpPost]
public async Task<ActionResult> Index(string comment)
{
//Here I calculate the ID, which represents the first row
//I would like to have this ID as a paramter, additional to comment
int maxID = dbContext.db.Max(m => m.pmc_id);
db x= dbContext.db.Where(m => m.pmc_id == maxID).FirstOrDefault();
//...Update database etc.
return RedirectToAction("Index");
}
Any help is appreciated!

first pass the Id to view with for example viewbag or some view model in here I chose ViewBag
[HttpPost]
public async Task<ActionResult> Index(string comment)
{
//Here I calculate the ID, which represents the first row
//I would like to have this ID as a paramter, additional to comment
int maxID = dbContext.db.Max(m => m.pmc_id);
db x= dbContext.db.Where(m => m.pmc_id == maxID).FirstOrDefault();
//...Update database etc.
ViewBag.CurrentId = calculatedId;//saved Id to pass to View
return RedirectToAction("Index");
}
lets add into the view the Id
#using (Html.BeginForm("Index"))
{
<input type="hidden" value="#ViewBag.CurrentId" name="Id"/>
<div class="form-group">
<h4>Title</h4>
<p>Comment here:</p>
<textarea type="text" class="form-control" name="comment" id="comment" required></textarea>
</div>
<input type="submit" value="Update" class="btn btn-info" />
}
now lets get the Id parameter with mvc parser
[HttpGet]
public PartialViewResult Update(int Id)//here is your id
{
return PartialView();
}

Related

attribute information not being found

When the button is pressed it states that the model is invalid as fields are empty.
when looking at the model all fields are empty or null. anyone know how to solve this issue, thanks
Home Controller
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> createOrderLine(Product models)
{
if (ModelState.IsValid)
{
db.OrderLines.Add(new OrderLine
{
productId = models.productId,
productColour = models.productColour,
productDescription = models.productDescription,
productName = models.productName,
productPrice = models.productPrice,
productStock = models.productStock,
//QuantityOrdered = quantityOrdered
});
db.SaveChanges();
return RedirectToAction("Index", "OrderLines");
}
else return RedirectToAction("Index", "Home");
}
Home Index - Displays the product information to the screen
#foreach (var product in Model)
{
using (Html.BeginForm("createOrderLine", "Home", FormMethod.Post, new {
#class = "form-horizontal", role = "form" }))
{
<div class="row">
<div class="blog col-md-6">
<div>
<h1>Product Name</h1>
<h2>#product.productName</h2>
<div>
<h3>Product Description</h3>
<h6><i>#product.productDescription</i></h6>
<br />
<h3>Product Price</h3>
<td>#product.productPrice </td>
<br />
<h1>Product colour</h1>
<td>#product.productColour</td>
<div></div>
<br />
<br />
#Html.AntiForgeryToken()
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" class="btn btn-buy" value="Add to cart" onclick="btnbuy_Click" />
</div>
</div>
</div>
</div>
<br />
</div>
</div>
}
}
the problem is that none of your field are linked to the model they only display it so to fix this
you can simply add a hiddenfor field that links the product id in your page like so for each of your product :
#Html.HiddenFor(product.Id)
then fill the rest of the informations you need with the id that is gonna be passed to your controller as a parameter
exemple :
public ActionResult createorderline(Product ProductToAdd)
{
// add your product or do your treatment
}
I do not quite understand what are you trying to do, but Louis is right. If you are trying to pass values back, you have to #Html.EditorFor() or some other ways to pass back information to the server.
You could also use #Html.HiddenFor(product.Id) then inside your Actionmethod call the database to get the rest of the info regarding your product or you could use JQuery as well.
In this case I would only use the #Html.HiddenFor(product.Id) and have a static helper method that will map your orderline class from the DB.
public static Product GetProductById(int productId){
return db.Products.FirstOrDefault(x => x.Id == productId);
}
But again you could just add the FirstOrDefault() line inside your controller as you not mapping from a ViewModel to a business Model.

MVC ActionLink goes to Get Action Controller Instead of Post Controller with the same name

I have a MVC ActionLink which goes to a controller action called Register.
I have two Register actions, one which is marked with HttpGet and the other with HttpPost, however when I attempt to post to this action it goes to the GET Register method and not the POST action.
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
#Html.ActionLink("Register", "Register", "Home", new { #class = "btn btn-default" }, new { onclick = "RegisterLoader()" })
</div>
</div>
Here is the script
function RegisterLoader() {
var url = '#Url.Action("Register", "Home", new { FormMethod.Post })';
$("#divLoading").show();
$.post(url, null,
function (data) {
$("#PID")[0].innerHTML = data;
$("#divLoading").hide();
});
}
And my controller looks like this.
[HttpGet]
[AllowAnonymous]
public ActionResult Register()
{
var towns = new List<string> { "Alberton", "Bedfordview", "Benoni", "Boksburg", "Brakpan", "Edenvale", "Germiston", "Kempton Park", "Nigel", "Springs" };
//var townOptions = new SelectList(towns);
ViewBag.Town = new SelectList(towns); //townOptions;
return View();
}
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Register(RegisterViewModel model)
The problem in js, it firstly handle onclick event, creates ajax POST request and then change page location to the address, defined at href with GET request.
To prevent relocation, you should return false from js method:
function RegisterLoader() {
var url = '#Url.Action("Register", "Home",new { FormMethod.Post})';
$("#divLoading").show();
$.post(url, null,
function (data) {
$("#PID")[0].innerHTML = data;
$("#divLoading").hide();
});
return false;
}
It will prevent calling to href.
However, if you want to perform synchronous POST request, you should change ActionLink to <input type="submit" /> and wrap the whole form with form tag as following (in razor syntax):
#using(Html.BeginForm("Register", "Home", FormMethod.Post))
{
#*another form tags*#
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Register" />
</div>
</div>
}
P.S. FormMethod.Post in Url.Action is useless, it renders in the string "/Home/Register?Post=Post"

POST data to controller with ASP.NET MVC

I am using ASP.NET MVC with C# and pure bootstrap. One of my views contains a label, text input box, and a submit button:
#{
ViewBag.Title = "BinSearch";
Layout = "~/Views/Shared/_LayoutSearch.cshtml";
}
<h2>BinConfig Search</h2>
#using (Html.BeginForm("FiEdit", "EditConfigController"))
{
<div class="form-group">
<label for="issuerKey">Issuer Key</label>
<input type="text" name="key" />
<input type="submit" class="btn btn-default" value="Search" />
</div>
}
When I click the "submit" button, I would like to transfer the data to a controller, EditConfigController to this method:
[HttpPost]
public ActionResult FiEdit(int key)
{
return View(new IssuerKey().Key = key);
}
Which then is supposed to create a new view where I can edit data based off the key provided. This is the FiEdit view:
#model BinFiClient.Models.IssuerKey
#{
ViewBag.Title = "FiEdit";
Layout = "~/Views/Shared/_LayoutEdit.cshtml";
}
<h2>FiEdit</h2>
However, when I click the "submit" button, I receive a 404 error, and the URL path looks like this:
http://localhost:58725/EditConfigController/FiEdit
Which is actually the path to the method in the controller that I posted above.
What I need is basically a way to POST data to another controller. How can I accomplish this?
Edit:
Now I am receiving the error:
The model item passed into the dictionary is of type 'System.Int32', but this dictionary requires a model item of type 'BinFiClient.Models.IssuerKey'.
Try replacing your code with the following:
#using (Html.BeginForm("FiEdit", "EditConfig", FormMethod.Post))
{
<div class="form-group">
<label for="issuerKey">Issuer Key</label>
<input type="text" name="key" />
<input type="submit" class="btn btn-default" value="Search" />
</div>
}
This will POST the parameter key to the EditConfig controller.
If you'd like to post to the action TestEdit in another controller, say the TestController, your code should be changed to the following:
#using (Html.BeginForm("TestEdit", "Test", FormMethod.Post))
...
To resolve the "model item passed into the dictionary" error, change your POST to be this:
[HttpPost]
public ActionResult FiEdit(int key)
{
return View(new IssuerKey() { Key = key });
}
ou can try with:
#using (Html.BeginForm(("FiEdit", "EditConfigController", FormMethod.Post,
new { enctype = "multipart/form-data" })))
{
<div class="form-group">
<label for="issuerKey">Issuer Key</label>
<input type="text" name="key" />
<input type="submit" class="btn btn-default" value="Search" />
</div>
}

Sending a value from a textbox on a View as a parameter to an action in a controller using ASP.NET MVC

I have an Index view - all that's on this View is a textbox and a submit button. I would like, when the user submits the form, for the value in the textbox to go to the controller I specify in my Form action. Here's the code for my Index view:
#using (Html.BeginForm("MovieDetails", "Home", FormMethod.Post))
{
<input type="text" class="typeahead-devs" id="movieName" />
<input type="submit" value="Create" name="Submit" />
}
When I click Submit, it takes me to the action MovieDetails:
[HttpPost]
public ActionResult MovieDetails(string movieName)
{
response = client.GetAsync(string.Format("api/sixfilm?movieName={0}", movieName)).Result;
if (response.IsSuccessStatusCode)
{
var actors = response.Content.ReadAsAsync<IEnumerable<Actor>>().Result;
return View(actors);
}
else
{
return RedirectToAction("Index");
}
}
But, movieName is null. Any ideas why movieName is null and how I can send a textbox's value over to an action?
You did not name your text input. Change
<input type="text" class="typeahead-devs" id="movieName" />
to
<input type="text" class="typeahead-devs" id="movieName" name="movieName" />

ASP.NET MVC Redirect

I work on one of my first ASP MVC-programs at the moment.
The program should show me a list of product, and with a link beneath the name of the product it should be possible to edit the product. No problem so far.
#model MVC3Demo.Product
#{
ViewBag.Title = "Edit";
}
<h2>Edit</h2>
#using (Html.BeginForm("Save", "Product"))
{
<div>
<input type="hidden" id="ID" name="ID" value="#Model.ID" />
ProduktID #Model.ID
</div>
<div>
Produktname <input id="Name" name="Name" type="text" value=#Model.Name />
</div>
<div>
Preis <input id="Price" name="Price" type="text" value=#Model.Price />
</div>
<div>
<input type="submit" value="Speichern"/>
</div>
}
Now I have written a Save action method that should update my data:
public ActionResult Save(Product p)
{
ProductRepository rep = new ProductRepository();
rep.Update(p);
return RedirectToAction("List");
}
The "List"-View is where I can see all products with the edit-link.
The problem is, that if I press the save-button, it redirects me to the old list, not to the updated one. I debugged my project and I´m sure that the update-method works correct and updates the product.
My List action is:
#model IEnumerable<MVC3Demo.Product>
#{
ViewBag.Title = "List";
}
<h2>List</h2>
<ul>
#foreach (MVC3Demo.Product p in Model)
{
<li>#p.Name #Html.ActionLink("bearbeiten", "Edit", "Product", p, null)</li> //new{ ID = p.id}
}
</ul>
Because you asked, here is the List Action:
public ActionResult List()
{
ProductRepository rep = new ProductRepository();
return View(rep.GetAll());
}
So where could be my mistake?
It looks like you're calling the update, but you're not actually submitting the transaction itself, does your repository have a SubmitChanges, AcceptChanges or Commit or something similar? As with DataTables, your changes won't actually take effect (save to the database) until you call AcceptChanges.
Try include an HttpPost attribute at Save controller method.
[HttpPost]
public ActionResult Save(Product p)
{
ProductRepository rep = new ProductRepository();
rep.Update(p);
return RedirectToAction("List");
}

Categories

Resources