ajax call function with parameters in mvc - javascript

I am very new to this, what I am trying to do is use ajax to call a controller function from view, this is my controller.
public ActionResult EditSiteGetContact(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
using (var db = SiteUtil.NewDb)
{
var owner = db.Contacts.Include(o => o.Id).FirstOrDefault(o => o.Id == id);
if (owner == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var orgViewModel = OrgViewModel.ToViewModel(owner);
return View("Edit", orgViewModel);
}
}
and this is the view where I want to show the data
<div class="form-group" id="alanTest">
<label class="control-label col-md-2">Contact Person</label>
<div class="col-md-6 form-inline">
#Html.TextBoxFor(model => model.Owner.Name, new { #class = "form-control", style = "width:200px", type = "text" })
<img src="~/Images/help-icon.png" class="tooltips" id="ContactPerson_Tooltip" title="lol">
#Html.ValidationMessageFor(model => model.Owner.Name)
</div>
</div>
my ajax part:
$("#alanTest").ready(function(){
var alanURL = "#Url.Action("EditSiteGetContact","Org")";
var contactId = #Model.Org.ContactId;
$.ajax({
type:"POST",
url:alanURL,
data:{
id:contactId
},
success:function(data){
alert(data);
},
error: function(){
alert("error");
}
});
});
i got "error" message..

Add [HttpPost] attribute before EditSiteGetContact(int? id).
In the ajax function change
var contactId = #Model.Org.ContactId; to var contactId = "#Model.Org.ContactId";
Please see below code. It may help you.
$("#alanTest").ready(function(){
var alanURL = "#Url.Action("EditSiteGetContact","Org")";
var contactId = "#Model.Org.ContactId";
$.ajax({
type:"POST",
url:alanURL,
data:{
id:contactId
},
success:function(data){
alert(data);
},
error: function(){
alert("error");
}
});
});

Related

How to add Antiforgery protection to such asp.net-mvc application?

I have an old asp.net mvc project using JS. I need to add Cross-Site Request Forgery protection, but I don't know, how to implement it in my case.
Could somebody help me with this, please?
chtml-view:
#model WebGridResults<IndexingCollectionModel>
#{
ViewBag.Title = "Manage Collections";
Layout = "~/_Indexing.cshtml";
}
#section grid_options
{
<div class="km-grid-option-padding">
<ul class="inline pull-right">
<li>
<a id="kmid_removeSelected"
class="km-grid-option remove"
href="#Url.Action("DeleteSelected", "Indexing", new { Area = "Admin" })"
data-target="km_grid_body"
data-redirect="#Url.Action("ManageCollections", "Indexing", new { Area = "Admin" })"
data-actiontype="submit_selected"
data-message="Do you want to continue?"><i class="icon-remove"></i> Remove Selected</a>
</li>
</ul>
</div>
}
JS-part:
$("[data-actiontype='submit_selected']").bind("click",
function () {
var $this = $(this);
var message = $this.data("message");
KM.Ajax.ShowConfirmation({ title: "Warning", message: message }, function () {
var url = $this.attr("href");
var redirect = $this.data("redirect");
var targetId = $this.data("target");
var selected = [];
var SelectedItemsIds = GetSelectedItemsIds();
$.each(SelectedItemsIds, function (Key, Item) {
selected.push({ name: "selected", value: Item });
});
//THIS PART WAS ADDED BY ME *********
var token = $("input[name='__RequestVerificationToken']").val();
if(token !== undefined && token !== "")
selected.push({name: "__RequestVerificationToken", value: token});
//*****************
$.ajax({
type: "POST",
url: url,
data: selected,
success: function (result) {
if (typeof (result) == "object") {
var json = result || {};
if (json.Success) {
var $target = $("#" + targetId);
if( settings.fullPageLoad === true )
{
location.reload();
}
else
{
$target.load( redirect, function()
{
if( settings.reloadCallback )
{
settings.reloadCallback();
}
} );
}
}
}
},
dataType: "json",
traditional: true
});
});
return false;
});
Controller:
[HttpPost]
[ValidateAntiForgeryToken()]
public ActionResult DeleteSelected(Guid[] selected)
{
try
{
_presenter.Delete(selected);
return Json(new { Success = true });
}
catch (Exception ex)
{
ModelState.AddModelError(ErrorRemoveSelected, ex.Message);
var errors = ModelState.ParseErrors();
return Json(new { Success = false, Errors = errors });
}
}
I've tried to add to request data (it is my part of code) in JS-function:
var token = $("input[name='__RequestVerificationToken']").val();
if(token !== undefined && token !== "")
selected.push({name: "__RequestVerificationToken", value: token});
Also I've added [ValidateAntiForgeryToken()] to controller method.
And it works, but only one time. When I try to perform the same action on the same page - it doesn't work.
What am I doing wrong?
Thank you in advanced!

How to load Images to Kendo grid

I am uploading image to the network folder which is not inside the project. Uploading images works 100%. The challenge is to read those image back to the grid, i am struggling to read all the images to Kendo grid.
**Question : How can i read images from network folder to Kendo grid **
This is what i have tried,
Reading Folder Url from the config
string Filelocation = System.Configuration.ConfigurationManager.AppSettings["Home.Settings"];
Model
public class SettingsModel
{
[DataType(DataType.Upload)]
public HttpPostedFileBase UploadImage { get; set; }
public string ImageUrl { get; set; }
}
Uploading Controller
[HttpPost]
[CustomAuthorize]
public ActionResult SaveBackgroundImage(SettingsModel model)
{
try
{
string backgroundImg = "";
string ImageName = "";
if (model.UploadImage != null)
{
backgroundImg = Path.GetFileName(model.UploadImage.FileName);
string e = Path.GetExtension(backgroundImg);
if (model.UploadImage != null)
{
ImageName = Path.Combine(Filelocation, backgroundImg);
model.UploadImage.SaveAs(ImageName);
model.ImageUrl = Url.Content(Path.Combine(Filelocation, ImageName)); // saving the Image url,wanted to try to read url
}
}
return View("BackgroundImage", model);
}
catch (Exception ex)
{
return Json(new { result = false, errormsg = "Error: " + ex.Message });
}
}
I got this url after saving:
\\0.0.0.000\Main\HomeSettings\BackgroundImage\20170802_174049.jpg
View
#using (Ajax.BeginForm("SaveBackgroundImage", "BackgroundSettings", new AjaxOptions { HttpMethod = "Post" }, new { #class = "form-horizontal", role = "form", enctype = "multipart/form-data" }))
{
<div class="form-group">
<label class="control-label col-sm-2" for="txtfrom">Upload Image:</label>
<div class="col-md-4">
#Html.TextBoxFor(m => m.UploadImage, new { type = "file", #id = "id_fileUploadImage", #class = "form-control input-sm", required = "required", #accept = ".jpg,.png,.gif" })
</div>
<br /><br />
<div class="col-sm-10 col-sm-offset-2">
<button class="btn btn-primary " id="btnSaveFile" name="submit" type="submit">Upload Image</button>
</div>
</div>
#(Html.Kendo().Grid<TTAF.Portal.Parts.Web.Models.SettingsModel>()
.Name("Grid")
.Columns(columns =>
{
columns.Bound(c => c.ImageUrl).ClientTemplate("<img src='" + Url.Content(Model.ImageUrl) + "#=ImageUrl#' alt='#=Name #' Title='#=Name #' height='62' width='62'/>");
//Error here: {"Object reference not set to an instance of an object."}
})
.Pageable(pageable => pageable
.Refresh(true))
.Scrollable()
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(1)
.ServerOperation(false) //No post back
.Read(read => read.Action("", ""))))
}
Script
$(document).ready(function () {
window.addEventListener("submit", function (e) {
var form = e.target;
if (form.getAttribute("enctype") === "multipart/form-data") {
if (form.dataset.ajax) {
e.preventDefault();
e.stopImmediatePropagation();
var xhr = new XMLHttpRequest();
xhr.open(form.method, form.action);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
var obj = JSON.parse(xhr.responseText)
if (obj.result == true) {
var ObjResults =
{
UploadImage: obj.UploadImage
}
alert(obj.UploadImage);
$.ajax({
url: '#Url.Action("SaveBackgroundImage", "BackgroundSettings")',
data: ObjResults,
type: "Post",
crossDomain: true,
async: true,
cache: true,
success: function (data) {
if (data.result == true) {
alert("Image Uploaded");
}
else {
alert("Error Occured");
}
}
});
}
else {;
}
}
};
xhr.send(new FormData(form));
}
}
}, true);
});

Jquery Ajax call does not call Asp.net mvc controller action method

I have two drop-downs State and City.According to State selected city should be loaded.So I use State drop-down change event to call ajax method to populate City drop-down.
HTML
<div class="row">
<div class="col-sm-6 ">
<div class="form-group">
<label>State</label>
#Html.DropDownListFor(m => m.State, Model.States, "Please select a State", new { #class = "form-control" })
</div>
</div>
</div>
<div class="row">
<div class="col-sm-6 ">
<div class="form-group">
<label>Cities</label>
#Html.DropDownListFor(m => m.CityRegisterScreen, new SelectList(string.Empty, "Id", "Name"), "Please select a city", new { #class = "form-control" })
</div>
</div>
</div>
JavaScript
This Contains Jquery and Javascript Code.
$(document).ready(function () {
$("#State").on("change", function () { // whenever a selection is made
$("#CityRegisterScreen").empty();
var id = $("#State").val();
$.ajax({
type: 'GET', // we are calling json method
url: '#Url.Action("GetCitiesByDistrict", "Account")',
dataType: 'json',
contentType: 'application/json; charset=utf-8',
data: { id: id },
success: function (cities) {
$.each(cities, function (i, city) {
$("#CityRegisterScreen").append('<option value="' + city.value + '">' +
city.Text + '</option>');
});
},
error: function (ex) {
alert('Failed to retrieve cities.' + ex);
}
});
return false;
});
});
Controller
This is the controller action method which returns Json
public JsonResult GetCitiesByDistrict(int id)
{
List<SelectListItem> cities = new List<SelectListItem>();
var city = new List<City>();
using (ApplicationDbContext context = new ApplicationDbContext())
{
city = context.Cities.Where(e => e.DistrictId == id).ToList();
}
return Json(new SelectList(city, "Id", "Name"), JsonRequestBehavior.AllowGet);
}
Issue is when ajax method is called it doesn't call the Action method in controller.I double checked the URL and DataType it's all perfect.But Action method didn't get called.
It is silly!!! How did i miss this. Thank You #Rajshekar Reddy for your comment it guided me. I am missing [AllowAnonymous] attribute.
[AllowAnonymous]
public JsonResult GetCitiesByDistrict(int id)
{
List<SelectListItem> cities = new List<SelectListItem>();
var city = new List<City>();
using (ApplicationDbContext context = new ApplicationDbContext())
{
city = context.Cities.Where(e => e.DistrictId == id).ToList();
}
return Json(new SelectList(city, "Id", "Name"), JsonRequestBehavior.AllowGet);
}
This is a code for loading States according to selected country. Try this solution.
HTML
#Html.DropDownListFor(model => model.CustAddr_Country_ID, Model.Countries, "Select Country", htmlAttributes: new { #class = "disableInput", #id = "ddlstate", #onchange = "javascript:GetCity(this.value);" })
#Html.DropDownListFor(model => model.CustAddr_State_ID, ViewBag.CustAddr_State_ID as SelectList, "Select State", htmlAttributes: new { #class = "disableInput"})
Script
function GetCity(_stateId) {
$("#CustAddr_State_ID").empty().trigger('change');
var newOption = new Option("Select State", 0, true, true);
$("#CustAddr_State_ID").append(newOption).trigger('change');
if (_stateId != null && _stateId != "") {
var url = "/Ajax/GetCityByStaeId/";
$.ajax({
url: url,
data: { stateid: _stateId },
cache: false,
type: "POST",
success: function (data) {
for (var x = 0; x < data.length; x++) {
var newOption = new Option(data[x].Text, data[x].Value, true, true);
$("#CustAddr_State_ID").append(newOption).trigger('change');
}
$('#CustAddr_State_ID').val('0').trigger('change');
},
error: function (reponse) {
//alert("error : " + reponse);
}
});
}
}
Controller
[HttpPost]
public ActionResult GetCityByStaeId(int stateid)
{
List<State> objcity = new List<State>();
objcity = _state.GetState().Where(m => m.State_Country_ID == stateid).ToList();
SelectList obgcity = new SelectList(objcity, "State_ID", "State_Name", 0);
return Json(obgcity);
}

Show Json Data after pushing Enter instead of Click ob submit

I have a MVC view that by clicking on submit button it post Data using Ajax to the Controller. The controller return json result that is messages and I show them on the View. The problem is when I click on Submit button it working fine but when I push Enter after show the Thank you page again it post to the controller method and show a page with json Data as bellow: (I need to make the Enter work as pushing Submit as well)
{"status":"success","message":""}
This is my View:
#using (Html.BeginForm("forgotPassword", "Home", FormMethod.Post))
{
#Html.AntiForgeryToken()
<div>
<div>Email Address</div>
<div><input type="email" name="email" placeholder="example#email.com" id="email" class="forgot-password-textbox"></div>
<div><label id="Message" class="forgot-password-error-message"></label></div>
<div><input type="button" value="Submit" id="btn-reset-password" onclick="resetPasswordHandler()" class="orange-button forgot-password-button"></div>
</div>
}
This is my Controller Method:
[HttpPost]
[Route("forgotPassword")]
public async Task<JsonResult> ForgotPassword(ForgotPasswordRequest forgotPasswordRequest)
{
...
try
{
if (ModelState.IsValid)
{
if (!string.IsNullOrEmpty(forgotPasswordRequest.Email))
{
users = await authenticationService.GetUserByEmailAsync(forgotPasswordRequest.Email);
if (users.Any())
{
if(users.FirstOrDefault().StatusId == 2)
{
return Json(new { status = "error", message = Constants.MessageStrings.ForgotPasswordDisabledUser });
}
//New User without creating password
if (string.IsNullOrEmpty(users.FirstOrDefault().PasswordHash))
{
return Json(new { status = "error", message = Constants.MessageStrings.ForgotPasswordDisabledUser });
}
....
}
}
else
{
ModelState.AddModelError("", Constants.MessageStrings.NoUser);
return Json(new { status = "error", message = Constants.MessageStrings.NoUser });
}
}
}
else
{
.......
return Json(new { status = "error", message = Constants.MessageStrings.RequiredFields });
}
and this is my Ajax to call controller:
function resetPasswordHandler() {
var postResult = null;
var data = {
Email: document.getElementById('email').value
};
var path = "/forgotPassword";
var errorMessage = document.getElementById('Message');
$.ajax({
dataType: "text",
url: path,
data: data,
type: "POST",
cache: false,
success: function (result) {
postResult = $.parseJSON(result);
if (postResult.status == "success") {
$('#forgot').hide();
$('#forgot-thank-you').show();
return false;
}
else {
errorMessage.innerHTML = postResult.message;
}
},
error: function () {
errorMessage.innerHTML = "An error occured";
}
});
return false;
};
window.onkeydown = function () {
if (window.event.keyCode == '13') {
resetPasswordHandler();
}
}
return Json(new { status="success",message="what ever your msg"}, JsonRequestBehavior.AllowGet);
I would remove the click handler from the button, and handle the submit event of the relevant form.
You should give an id for easier targeting
#using (Html.BeginForm("forgotPassword", "Home", FormMethod.Post, new { id = "reset-form" }))
And simplify your script (since you are using jQuery) to
function resetPasswordHandler(event) {
var postResult = null,
data = {
Email: $('#email').val()
},
path = "/forgotPassword",
errorMessage = $('#Message');
event.preventDefault();
$.ajax({
dataType: "text",
url: path,
data: data,
type: "POST",
cache: false,
success: function(result) {
postResult = $.parseJSON(result);
if (postResult.status == "success") {
$('#forgot').hide();
$('#forgot-thank-you').show();
return;
} else {
errorMessage.html(postResult.message);
}
},
error: function() {
errorMessage.html("An error occured");
}
});
return false;
};
$('#reset-form').on('submit', resetPasswordHandler);

Cannot pass parameters from View to Controller via JavaScript

Although I manage to send the grid's selected row id to the controller, the url for opening action view cannot be built up (it is created /Controller/Action instead of /Controller/Action/id. So, when I try to open the view with /Controller/Action/id it is open, but it cannot be opened by button click as below.
View:
<input type="button" id="btn" name="name" value="send to Server!" />
<script>
$('#btn').click(function () {
var items = {};
var grid = $('#Grid').data('kendoGrid');
var selectedElements = grid.select();
var item = grid.dataItem(selectedElements[0]);
$.ajax({
type: "POST",
data: item.ID, //I obtained the id properly
url: '#Url.Action("CreateParticipant", "Training")',
success: function (result) {
//console.log(result);
}
})
})
</script>
Controller:
// GET: /Training/CreateParticipant/5
public ActionResult CreateParticipant(int? id)
{
Training training = repository.Trainings.FirstOrDefault(m => m.ID == id);
if (training == null)
{
return HttpNotFound();
}
var trainingParticipantViewModel = new TrainingParticipantViewModel(training);
return View(trainingParticipantViewModel);
}
Route.config:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
//defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
defaults: new { controller = "Multiplier", action = "Index", id = UrlParameter.Optional }
);
}
}
Is there another example as above to pass the parameters or is there any mistake on the code above? Thanks in advance.
Javascript
$('#btn').on("click",function () {
var items = {};
var grid = $('#Grid').data('kendoGrid');
var selectedElements = grid.select();
var item = grid.dataItem(selectedElements[0]);
$.ajax({
type: "GET",
data: item.ID, //I obtained the id properly
url: '#Url.Action("CreateParticipant", "Training")/'+item.ID,
datatype:'html',
success: function (result) {
alert(result)
}
})
})
Or use
$('#btn').on("click",function () {
var items = {};
var grid = $('#Grid').data('kendoGrid');
var selectedElements = grid.select();
var item = grid.dataItem(selectedElements[0]);
window.location.href= '#Url.Action("CreateParticipant", "Training")/'+item.ID;
});
Hope this helps.
.ToolBar(toolbar =>
{
toolbar.Template(#<text>
<div class="toolbar">
#(Html.Kendo().Button()
.Name("addbtn")
.Content("Add New")
.HtmlAttributes(new { type = "button", #class = "k-primary k-button k-button-icontext js-myKendoButton", #data_id = #Model.YourID, onclick = "onClick()" })
)
</div>
</text>);
})
And then you will grab the data-attribute with jQuery.
$('.js-myKendoButton').attr('data-id');
More here: How to use dashes in HTML-5 data-* attributes in ASP.NET MVC
<script>
$('#btn').on("click",function () {
var items = {};
var grid = $('#Grid').data('kendoGrid');
var selectedElements = grid.select();
var item = grid.dataItem(selectedElements[0]);
$.ajax({
type: "POST",
data: {ID : item.ID}, //I obtained the id properly
url: '#Url.Action("CreateParticipant", "Training")',
success: function (result) {
//console.log(result);
}
})
})
</script>
use this ,i hope this will be help you

Categories

Resources