I have a javascript method onRowSelected wchich gets rowid. How to pass the rowid in certain action of a controller with HttpGet?
function onRowSelected(rowid, status) {
alert('This row has id: ' + rowid);
//url: #Action.Url("Action","Controller")
//post:"GET"
// Something like this?
}
If your controller action expects an id query string parameter:
var url = '#Url.Action("Action", "Controller")?id=' + rowid;
or if you want to pass it as part of the route you could use replace:
var url = '#Url.Action("Action", "Controller", new { id = "_id_" })'
.replace('_id_', rowid);
yet another possibility if you are going to send an AJAX request is to pass it as part of the POST body:
$.ajax({
url: '#Url.Action("Action", "Controller")',
type: 'POST',
data: { id: rowid },
success: function(result) {
}
});
or as a query string parameter if you are using GET:
$.ajax({
url: '#Url.Action("Action", "Controller")',
type: 'GET',
data: { id: rowid },
success: function(result) {
}
});
All those suppose that your controller action takes an id parameter of course:
public ActionResult Action(string id)
{
...
}
So as you can see many ways to achieve the same goal.
The method by Darin will work fine and perfectly.
I would suggest one more way for Razor view to use model value using #Html.actionlink in jsp
var URLvalue='#Html.ActionLink("UserString", "action", new { routeValueName1 = "__value1__", routeValueName2="__value2__" }, htmlAttributes: new { #class = "btn btn-default", #role = "button" })'
.replace('__value1__', Model.somevalue).replace('__value2__', Model.somevalue);
you can use URLvalue where ever you want to in jsp or jquery.
Related
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.
I am retrieving controller name from a javascript function as a string, and need to pass controller name in Url.Action. Any suggestion would be helpful.
var controllerName = "MyController";
var id=1;
#Url.Action("LoadAction","'"+ controllerName +"'")?id=' + id
// Here i am unable to pass controllerName, defined using javascript.
Thanks.
If you want to send data from a js script to a C# controller, then you can use a Jquery-ajax call instead of #Url.Action, if I'm not mistaken, you can't even use #Url.Action on a js source code.
const sendId = () => {
const controllerName = 'MyController';
const id = 1;
$.ajax({
contentType: 'application/json',
data: { myId: id },
url: `${controllerName}/methodName`, //template string
type: 'POST',
success: function (data) {
//...
},
failed: function () {
//...
}
});
}
I'm working on ASP.NET MVC project , I want to get location dropdown selected value and according to that i need to load values to City dropdown , i implemented following code and location dropdown onselect event call the javascript function and javascript function call the controller method but when executing controller method locationId is null ,and i debug javascript and locationID is there till the this line data: JSON.stringify({ locationId: +locationId }), after that javascript returns error.but controller method get hit but locationId null
code for dropddowns
<div class="row">
<div class="col-sm-4">
#Localizer["Locations"]
<select id="locationDropDown" class="selectpicker form-control" asp-for="selectedLocation" onchange="getCityList()">
<option value="0"><None></option>
#foreach (var item in Model.LocationList)
{
<option value="#item.Id">#item.Name</option>
}
</select>
</div>
</div>
<div class="row">
<div class="col-sm-4">
#Localizer["KioskGroup"]
<select id="cityDropDown" class="selectpicker form-control">
<option>---Select City---</option>
</select>
</div>
</div>
Javascript code
function getCityList()
{
debugger;
var locationId = $("#locationDropDown").val();
console.log(locationId)
$.ajax({
url: '/Kiosk/GetZoneListBYlocationID',
type: 'POST',
datatype: 'application/json',
contentType: 'application/json',
data: JSON.stringify({ locationId: +locationId }),
success: function (result) {
$("#cityDropDown").html("");
$("#cityDropDown").append
($('<option></option>').val(null).html("---Select City---"));
$.each($.parseJSON(result), function (i, zone)
{ $("#cityDropDown").append($('<option></option>').val(zone.Id).html(zone.Name)) })
},
error: function(){alert("Whooaaa! Something went wrong..")},
});
controller method
public ActionResult GetZoneListBYlocationID(string locationID)
{
List<Zone> lstZone = new List<Zone>();
long locationId = long.Parse(locationID);
var zones = _zoneRepository.GetZonesByLocationId(locationId);
return Json(JsonConvert.SerializeObject(zones));
}
Your current code is sending the json string {"locationId":101} in the request body because you specified the contentType as application/json. This is useful when you want to send an object with multiple properties and your action method parameter is a DTO/POCO class type. Model binder will be reading from the request body and map it to the parameter.
In your case, all you are sending is a single value. So do not send the JSON string. simply create a js object and use that as the data attribute value. Also remove the contentType: application/json as we are not sending a complex js object as json string.
Also application/json is not a valid option for the dataType property. You may use json. But jQuery is smart enough to guess the value needed here from the response headers coming back from server. So you may remove it.
function getCityList() {
var locationId = $("#locationDropDown").val();
$.ajax({
url: '/Kiosk/GetZoneListBYlocationID',
type: 'POST',
data: { locationID: locationId },
success: function (result) {
console.log(result);
// populate dropdown
},
error: function () { alert("Whooaaa! Something went wrong..") },
});
}
Now this data will be send in Form Data as locationID=101 with Content-Type header value as application/x-www-form-urlencoded and will be properly mapped to your action method parameter.
You should use the correct types. In your action method, you are using string as your parameter and later trying to convert it to long. Why not use long as the parameter type ? Also if zones variable is a list of Zone object, you can pass that directly to the Json method. No need to create a string version in between.
public ActionResult GetZoneListBYlocationID(long locationId)
{
var zones = _zoneRepository.GetZonesByLocationId(locationId);
return Json(zones);
}
Why you are stringify the data.Below one should work without stringify
data: { locationId: +locationId },
I was facing the same problem. and after that, I have tried below solution.
Hope it will help you.
ajax call is as follows:
$.ajax({
type: 'POST',
url: "/Account/GetCities",
dataType: 'json',
data: { id: $("#StateID").val() },
success: function (states) {
$.each(states, function (i, state) {
$("#CityID").append('<option value="' + state.Value + '">' + state.Text + '</option>');
});
},
error: function (ex) {
alert('Failed to retrieve cities.' + ex);
}
});
The controller code is as follows:
public List<CityModel> GetCities(int id)
{
//your code
}
You can do in your application like this:
function getCityList()
{
var locationId = $("#locationDropDown").val();
console.log(locationId)
$.ajax({
url: '/Kiosk/GetZoneListBYlocationID',
type: 'POST',
dataType: 'json',
data: { locationId: locationId },
success: function (result) {
$("#cityDropDown").html("");
$("#cityDropDown").append
($('<option></option>').val(null).html("---Select City---"));
$.each($.parseJSON(result), function (i, zone)
{ $("#cityDropDown").append($('<option></option>').val(zone.Id).html(zone.Name)) })
},
error: function(){alert("Whooaaa! Something went wrong..")},
});
}
And your controller will be same as you have done.
I am trying to be familiar with ASP MVC by working on simple MVC project.
But there is a problem I can't figure out.
On certain event, AJAX request is sent to one action taking IDictionary type parameter.
But the received parameter contains controller name, action name and language instead of data specified in Jquery AJAX call.
Please take a look at below code.
RouterConfig
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Language",
url: "{lang}/{controller}/{action}/{id}",
defaults: new {controller = "Login", action="Index", id=UrlParameter.Optional},
constraints: new {lang = #"en|fr"}
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Login", action = "Index", id = UrlParameter.Optional, lang = "en" }
);
}
Action
public ActionResult ApproveUsers(IDictionary<string, string> CheckedUsers)
{
return View();
}
JQuery
$('#confirmModal #action').click(function () {
var cb = {};
var data = {};
$("input:checkbox:checked").each(function () {
var key = $(this).attr('value');
var val = $(this).closest('tr').next().find('table').attr('id');
cb[key] = val;
});
$.ajax({
type: "POST",
url: '/AdminHome/ApproveUsers',
dataType: "html",
contentType: 'application/json',
data : JSON.stringify(cb),
success: function (result) {
alert("success");
},
error: function(result) {
alert("failed");
}
});
});
So when button is clicked all the checked checkbox data are sent to ApproveUsers action as keyvaluepair.
But no matter what the cb object in Jquery contains, the IDictionary parameter in ApproveUsers action only is like below
[0] {[ contoller, AdminHome ]}
[1] {[ action, ApproveUsers ]}
[2] {[ lang, en]}
This seems like there is something wrong with RouteConfig. But I don't know why.
I would really appreciate if anyone can help me know why and fix this issue.
Thanks,
I found what's wrong with my code.
I was missing the parameter name in AJAX call so parameter biding failed.
As Steve said, code should be like below.
data : JSON.stringify(CheckedUsers:cb)
I managed to retrieve a dynamic element ID from inside a foreach and send it to a controller this way:
#using (Html.BeginForm("DeleteConfirmed", "Gifts", FormMethod.Post, new { #class = "form-content", id = "formDiv" }))
{
foreach (var item in Model.productList)
{
<input type="button" value="Delete" onclick="DeleteButtonClicked(this)" data-assigned-id="#item.ID" />
}
}
and here's the relevant script, pointing to the controller's ActionResult method in charge for item deletion:
function DeleteButtonClicked(elem) {
var itemID = $(elem).data('assigned-id');
if (confirm('sure?')) {
window.location.href = "/Gifts/DeleteConfirmed/" + itemID;
}}
Now, this works just fine, as itemID is correctly retrieved.
As I would like to add a #Html.AntiForgeryToken() to the form, the idea is to change the MVC controller's Actionmethod into a JsonResult adding a little Ajax to the script, allowing me to pass both itemID and token.
Something like:
function DeleteButtonClicked(elem) {
event.preventDefault();
var form = $('#formDiv');
var token = $('input[name="__RequestVerificationToken"]', form).val();
var itemID = $(elem).data('assigned-id');
if (confirm('sure?')) {
$.ajax({
type: 'POST',
datatype: 'json',
url: '#Url.Action("DeleteConfirmed", "Gifts")',
data: {
__RequestVerificationToken: token,
id: itemID
},
cache: false,
success: function (data) { window.location.href = "/Gifts/UserProfile?userID=" + data; },
error: function (data) { window.location.href = '#Url.Action("InternalServerError", "Error")'; }
});
}
dynamic }Some
but I have no idea on how to add the 'event' to the element (this => elem) in <input type="button" value="Delete" onclick="DeleteButtonClicked(this)" data-assigned-id="#item.ID" /> that I am using to identify the item inside the foreach loop, in order to pass it to the script.
Above script obviously fails as there's no 'event' (provided this would end to be the only mistake, which I'm not sure at all).
Some help is needed. Thanks in advance for your time and consideration.
What you want to do is use jQuery to create an event handler:
$('input[type="button"]').on('click', function(event) {
event.preventDefault();
var form = $('#formDiv');
var token = $('input[name="__RequestVerificationToken"]', form).val();
var itemID = $(this).data('assigned-id');
if (confirm('sure?')) {
$.ajax({
type: 'POST',
datatype: 'json',
url: '#Url.Action("DeleteConfirmed", "Gifts")',
data: {
__RequestVerificationToken: token,
id: itemID
},
cache: false,
success: function (data) { window.location.href = "/Gifts/UserProfile?userID=" + data; },
error: function (data) { window.location.href = '#Url.Action("InternalServerError", "Error")'; }
});
}
});
Just make sure you render this script after your buttons are rendered. Preferably using the $(document).onReady technique.
Try the 'on' event handler attachment (http://api.jquery.com/on/). The outer function is shorthand for DOM ready.
$(function() {
$('.some-container').on('click', '.delete-btn', DeleteButtonClicked);
})