I am trying to pass ID parameter from a view to a controller on a click delete link available on a selected row.
Simplified View Layout
#using (Html.BeginForm("#", "Schedule", FormMethod.Post, htmlAttributes: new { #class = "floating-labels" }))
{
#Html.AntiForgeryToken()
Delete
}
JavaScript
<script type="text/javascript">
function DeleteSchedule(id) {
if (confirm('Are you sure you want to delete this Schedule?')) {
$.ajax({
type: "POST",
url: '#Url.Action("Delete", "Schedule", new { id = "id" })',
contentType: "application/json",
data: { id },
async: true,
cache: false,
success: function (result) { success(result); }
});
}
return false;
}
function success(result) {
$("#ScheduleList").html(result);
}
</script>
Controller
namespace Controllers
{
public class ScheduleController
{
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Delete(int id)
{
//do stuff
}
}
}
But on the click of a delete link I get below error and code does not hit controller action.
I am not able to figure out what mistake I am making...
Here is my locally tested implementation that is working.
ScheduleController class:
public class ScheduleController : Controller
{
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Delete(int id)
{
return Ok(id);
}
}
Page that sends the post request:
#Html.AntiForgeryToken()
Delete
<div id="ScheduleList"></div>
<script>
function DeleteSchedule(id) {
if (confirm('Are you sure you want to delete this Schedule?')) {
var uri = '/Schedule/Delete?id=' + id;
var tokenElement = document.getElementsByName('__RequestVerificationToken')[0];
var data = {
__RequestVerificationToken: tokenElement.value
}
$.ajax({
type: "POST",
url: uri,
data: data,
success: function (result) {
success(result);
}
});
}
return false;
}
function success(result) {
$("#ScheduleList").html(result);
}
</script>
The page does nothing but render the html, and the javascript handles the actual Ajax post. What I believe you were missing is the Validation token in your request.
It is because you are not actullay posting the form pass it correctly and add _token in the ajax data list and value for that token will come from #Html.AntiforgeryToken()
reading the error the request is most probably send correctly and there is an internal server error as mentioned in the 500 respond so please check the code that is inside the controller
Try this, you are accesing a javascript variable on c# code, and you cant do that.
If correct, please mark as answer.
function DeleteSchedule(id) {
if (confirm('Are you sure you want to delete this Schedule?')) {
var url = '#Url.Action("Delete", "Schedule")?id=' + id;
$.ajax({
type: "POST",
url: url,
contentType: "application/json",
data: { id },
async: true,
cache: false,
success: function (result) { success(result); }
});
}
return false;
}
I think none of the answers above solve the issue. First of all I would replace your target url:
url: '#Url.Action("Delete", "Schedule", new { id = "id" })',
with
url: '#Url.Action("Delete", "Schedule", new { id = actualIdVariable })',
(replace "id" with the actual id variable from the model you're passing to the view).
Note how your browser response is telling you that the url you're posting to is Schedule/Delete/id. That said, I'm not sure you even need the routeValues in this case (the new { id = ...} parameter). this is a POST action, and action parameters wouldn't come from route unless specified by by attribute routing (i.e. [Route("~/Schedule/Delete/{id}")] attribute on your action).
I think your post action is failing because it is trying to parse the "id" string as an int.
Second, I would change the data property of the ajax call and include the anti forgery token. Just because the anchor element you're binding the click event to, is inside the form with #Html.AntiforgeryToken() doesn't mean the generated token will be posted in the ajax request. You're not actually submitting/posting the form, you're just clicking a button.
it should be something like
data: {
'id': id,
'__RequestVerificationToken': $('[name="__RequestVerificationToken"]').val()
}
try this, it solve the error on routing (different url Action) and the parameter on the controller:
JavaScript
<script type="text/javascript">
function DeleteSchedule(id) {
if (confirm('Are you sure you want to delete this Schedule?')) {
$.ajax({
type: "POST",
url: '#Url.Action("Delete", "Schedule")',
data: "id=" + id ,
async: true,
cache: false,
success: function (result) { success(result); }
});
}
return false;
}
function success(result) {
$("#ScheduleList").html(result);
}
</script>
Controller:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Delete(string id)
{
//do stuff
}
Nicola.
Related
I am currently learning asp.net core 3 and I can't find any help regarding this issue that I have.
I have a form that submits a value with a POST request. But I want the same button to have a GET request that populates another field with a .ajax / xmlhttprequest. But I want the POST method to be executed first and then the GET method. Is it possible to do it? I've tried doing it but I got stuck.
These are the methods inside my controller.
[HttpGet]
public async Task<IActionResult> GetConvertedAmount()
{
var rate = await _db.ExchangeRates.Where(x => x.Name.Equals(_tM.Currency)).ToListAsync();
_tM.convertToCurrency(rate[0].Rate);
var amount = _tM.Amount;
return Json(amount);
}
[HttpPost]
public ActionResult CalculateExchangeRatio(int amount_give, string type_to_give)
{
_tM.Amount = amount_give;
_tM.Currency = type_to_give;
return Ok();
}
And this is my JS script
$('#calculateButton').on("click", function () {
$.ajax({
url: "/trade/getconvertedamount",
type: "get",
success: function (amount) {
console.log(amount);
alert(amount);
}
});
})
You can use the $.ajax 'done' chaining to complete the entire process:
$('#calculateButton').on("click", function () {
$.ajax({
url: "/trade/calculateexchangeratio",
data: { amount_give: 9.99, type_to_give: 'blahblah' },
type: "post"
})
.done(function(){
$.ajax({
url: "/trade/getconvertedamount",
type: "get"
})
.done(function (amount) { console.log(amount); alert(amount); });
});
})
You can add the similar to the end of the POST method implementation return RedirectToAction("CalculateExchangeRatio", new { amount_give = 1, type_to_give = 2 });
So your POST method will be called first and it will call the GET method.
Here is the documenttation.
I'm trying to POST an INT with Ajax to my MVC controller.
The script debugging confirms that my variable is an INT with a value (for example 8 and not a string "8"). All lines of code are executed and
I recive my Alert error message.
I've got a breakpoint inside of my Action in the controller but I never get that far. I get a notice in my Action that a request failed, but it only say
"POST Order/Delete". My Controller name is OrderController and Action name is Delete.
My JavaScript:
//Delete order
$(".deleteOrder").on("click", function () {
var id = parseInt($(this).attr("id"));
if (id !== null) {
$.ajax({
url: "/Order/Delete",
method: "POST",
contentType: "application/JSON;odata=verbose",
data: id ,
success: function (result) {
alert("Ok")
},
error: function (error) {
alert("Fail");
}
});
}
});
My MVC Action
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Delete(int id)
{
List<OrderRow> lstOrderRow = new List<OrderRow>();
lstOrderRow = db.OrderRows.Where(x => x.OrderId == id).ToList();
foreach(var row in lstOrderRow)
{
db.OrderRows.Remove(row);
}
Order order = new Order();
order = db.Orders.Find(id);
db.Orders.Remove(order);
db.SaveChanges();
return RedirectToAction("index");
}
You should either use the url like this by removing data field
url: "/Order/Delete/" + id,
or send the id in data as below
data: {id: id},
This works for me:data: JSON.stringify({ id: id})
dataType: "json",
contentType: 'application/json; charset=utf-8',
I have a table that will use is populated by javascript when another table option is clicked. All of this works no problem, when I add the delete button to the table the onClick event fires but this isn't ever called in asp.net.
function DeleteLink(id) {
$.ajax({
url: '/PublicPages/LinkDelete/',
data:{ id:id }
});
}
please tell me where I've gone wrong.
I have tried
function DeleteLink(id) {
$.ajax({
url: '/PublicPages/LinkDelete/' + id
}
as well
UPDATE:
[HttpPost]
public async Task<IActionResult> LinkDelete(Guid id)
{
var pageId = _linkDataProvider.FindById(id).PublicPage.Id;
_linkDataProvider.Delete(id);
var page = await _pageDataProvider.FindById(pageId);
var viewModel = _pageDataProvider.ConvertToViewModel(page);
return View("Details", viewModel);
}
UPDATE2
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Flooring}/{action=Index}/{id?}");
});
You should specify http method in ajax settings. Try to change your javascript like below:
function DeleteLink(id) {
$.ajax({
type = 'POST',
url: '/PublicPages/LinkDelete/' + id
});
}
Update
If you prefer to use data:{ id:id } then you would need to create a model class:
public class DeleteModel
{
public Guid Id{get;set;}
}
[HttpPost]
public async Task<IActionResult> LinkDelete([FromBody]DeleteModel model)
....
I am working on a website and would like to be able to update a field on a database table when a div is clicked. I found some example code right here on stack but for some reason it won't work, even though it was accepted. I am using C# ASP.NET MVC Razor.
My JavaScript function is as follows:
function toggleContent(id, instID) {
var doc = document.getElementsByClassName("messageContent")[id];
$(doc).slideToggle();
$.ajax({
type: 'POST',
url: "#Url.Content('/Messages/MarkSeen/')",
data: {
instanceID : instID
},
dataType: 'json'
});
}
And my JsonResult is as follows:
[HttpPost]
public JsonResult MarkSeen(int instanceID)
{
var markSeen = db.MessageInstances.First(mi => mi.MessageInstanceId == instanceID);
if (markSeen.RegisteredPerson.PersonId == CurrentUser.PersonId)
{
markSeen.Seen = true;
db.SaveChanges();
return Json(true);
}
return Json(false);
}
I'm not sure where your code fails, so I posted complete working code
If you are using the ApiController, please try the following updates to make your code works:
1. add route to WebApiConfig.cs
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
2. javascript
$.ajax({
type: "POST",
url: "#Url.Content("/api/lab/MarkSeen")",
data: { "instanceID": instID },
dataType: 'json',
success: function (data) { alert(data)},
error: function () { alert('error'); }
});
3. Add model to match the json from ajax request:
public class labModel
{
public int instanceID { get; set; }
}
4. Controller:
[System.Web.Mvc.HttpPost]
public JsonResult<bool> MarkSeen(labModel data)
{
return Json(true);
}
Sure this had been dealt with many times... but.. just cant see what im doing wrong!
This is a simple JS script that Posts data back to ApiController.
function WebCall(url,parameterObject, callBackFunction) {
this.callbackfunction = callBackFunction;
this.parameterObject = parameterObject;
this.url = url;
self = this;
this.GetData = function () {
//self = this;
$.ajax({
//dataType: "json",
type: "POST",
url: self.url,
data: JSON.stringify(self.parameterObject),
contentType: "application/json;charset=utf-8",
success: function (data) {
self.callbackfunction.call(this, data);
},//self.GotData,
error: function (xhRequest, ErrorText, thrownError)
{
alert("error : " + ErrorText)
},
complete: function () {},
})
}
}
The data being sent (parameterObject) is simply
var postData = {
clientId: id
}
The c# code in the controller is :
public class ClientPostObject
{
public string clientId;
}
public class ClientDetailController : ApiController
{
[HttpPost]
public ClientDetailWidgetData GetClient(ClientPostObject clientObject)
{
return new ClientModel().GetClientDetail(clientObject.clientId);
}
}
In Google chrome developer tools, the XHR is showinf 'form Data' as clientId:A0001 - so that looks ok?
No matter what I try (and I'be been through many suggestions on the web), the post data is not there.
Sure its something simple.... Thanks in advance.
Unless you're planning on using a full-on form to submit to this method at some other point, it doesn't really make sense to ask the model binder to attempt to bind to a complex type when you're just using one property. Change your method signature to:
[HttpPost]
public ClientDetailWidgetData GetClient(int clientId) // or whatever type clientId represents
{
return new ClientModel().GetClientDetail(clientId);
}
I'd also recommend adding Glimpse at some point (http://getglimpse.com/) so that you can see how the model binding and/or routing of your app works.
Try to ditch contentType and don't stringify data:
$.ajax({
type: "POST",
url: self.url,
data: self.parameterObject,
success: function (data) {...},
...
});