.net Core Using razor function in Javascript - javascript

Hi i got to use c# code in js. My js and .cshtml page are separeted . I wrote a function in .cshtml page and gotta call it in .js file.
In Js file
DataList.forEach(function (item) {
...
var users = GetUsers(item.AssignedUsers);
It goes here
Index.cshtml
<script>
function GetUsers(userIdList) {
//it logs it, i can get theese values from here
console.log("userIdList");
console.log(userIdList);
#{ // but in here it says userIdList does not exist in current content
//also tryed this.userIdList
var users = userIdList.Split(",");
foreach (var item in users)
{
var user = _Manager.FindByIdAsync(item.UserId).Result;
}
}
}
</script>

You can pass list from ajax to controller action,and action return a list you want.
Here is a demo:
<button onclick="sendData()">
send
</button>
<script>
function sendData() {
//here is a sample list
var list = [];
var user1 = {};
user1.Id = 1;
user1.Name = "u1";
list.push(user1);
var user2 = {};
user2.Id = 2;
user2.Name = "u2";
list.push(user2);
$.ajax({
type: "POST",
url: '#Url.Action("SendData", "Test")',
contentType: "application/json",
data: JSON.stringify(list),
}).done(function (data) {
console.log(data);
//the data is you want
});
}
</script>
action:
public List<User> SendData([FromBody]List<User> list) {
//you can do something and return a list you want here
return list;
}
User:
public class User {
public int Id { get; set; }
public string Name { get; set; }
}
result:

Related

fetching an Object from Action Item and displaying on View without Page refresh Using Ajax and Javascript

public class vendorData
{
public int VCode { get; set; }
public string currency { get; set; }
}
[HttpGet]
public IActionResult OnGetVendorCode(string VendorName)
{
var VendorMaster = _context.VendorMaster.ToList();
var VendorCodes = from O in VendorMaster where O.CompanyID == Company && O.VendorName == VendorName select O.VendorCode;
var currency= from O in VendorMaster where O.CompanyID == Company && O.VendorName == VendorName select O.Currency;
vendorData vendorData = new vendorData();
vendorData.VCode = VendorCodes.FirstOrDefault();
vendorData.currency = currency.FirstOrDefault();
return new JsonResult(vendorData);
}
function GetPOVendorCode(ID) {
$.ajax(
{
data: { VendorName: ID },
url: '/Purchase/POGenerals/Create/?handler=VendorCode',
type: 'GET',
success: function (data) {
const myJSON = JSON.stringify(data);
alert(myJSON.VCode);
}
});
}
How can I access each object item through my Ajax call? and save it in a variable so that I could use that on my page? Is there any other better way? I am using ASP razor pages and trying to update other text boxes of the purchase order when I select the vendor name
The response data is the correct object so that no need use JSON.stringify(data);.
Also the response data is camel case format.
In summary, just use data.vCode to get the value.

passing an array from ajax call to controller, array empty in controller

Can anyone suggest what I need to change here?
I'm getting classes from elements that contain the class 'changed', the classes I get contain id's that I want to pass to the controller method.
When I look in the network tab I can see the data I want in the payload, it looks like this:
{"list":["GroupId-1","SubGroupId-2","changed"]}
but when I put a breakpoint on the controller the list is null.
This is the class I'm expecting in the controller method:
public class MemberGroups
{
public string GroupId { get; set; }
public string SubGrouId { get; set; }
public string Status { get; set; }
}
javascript for the save
function Savechanges() {
var spans = document.getElementsByClassName("changed");
var list = [];
$.each(spans,
function (key, value) {
$.each(value.classList,
function (key, value) {
list.push(value);
});
});
var dataToPost = JSON.stringify({ list: list });
$.ajax({
url: "/umbraco/Api/OrganisationMemberGroupsDashboardApi/UpdateMemberToGroup",
data: JSON.stringify({ list }),
type: "POST",
contentType: "application/json; charset=utf-8", // specify the content type
})
.done(function (data) {
});
}
controller
public string UpdateMemberToGroup( List<MemberGroups> list)
{
// save records
}
The spans are created dynamically and added to a treeview. When they are dragged and dropped all classes are removed then the 'changed' class is added along with the id classes so I only pass the ones I need to to the controller
var s = document.createElement('span');
s.classList.add('node-facility');
s.classList.add('ui-droppable');
s.classList.add('GroupId-' + value.GroupId);
s.classList.add('SubGroupId-0');
s.id=('GroupId-' + value.GroupId);
s.appendChild(document.createTextNode(value.GroupName));
This variant was tested using postman body json -
["GroupId-1","SubGroupId-2","changed"]
Change your ajax data to this:
data: list,
and your controller action:
public string UpdateMemberToGroup([FromBody] []string list)
{
var memberGroups = new MemberGroups
{
GroupId =list[0],
SubGrouId =list[1],
Status =list[2]
};
// save records
}
This variant was tested in postman using
{"GroupId":"GroupId-1","SubGroupId": "SubGroupId-2", "Status":"changed"}
you can put the code in javascript:
var data={GroupId:list[0],SubGroupId:list[1], Status:list[2]}
......
....
data:data,
.....
your controler action in this case:
public string UpdateMemberToGroup([FromBody] MemberGroups memberGroups)
{
// save records
}
And I don't know what version MVC you use , but for some versions instead of [FromBody] better to use [FromForm] or don't use anything at all.

ASP.Net MVC: How could i pass js array to mvc action by #Url.Action()

We know that we can pass js variable value to mvc action but how could i pass js array to mvc action ?
So my question is how could i pass js array to mvc action by #Url.Action() ?
please see my sample code
[HttpPost]
public ActionResult DoSomething(string id, string deptno, list<PdfInputs> PdfInputs)
{
// Some magic code here...
}
var id = "10";
var deptno = "C001";
var PdfInputs = [];
for(inti=0;i<=totalbol-1;i++)
{
var PdfInput = {
firstName: "John",
lastName: "Doe",
age: 46
};
}
PdfInputs.push(BOLPdfInput);
location.href = '#Url.Action("DoSomething", "Customer")?id=' + id + '&deptno=' + deptno;
my mvc action will download pdf at client and that is why i use
location.href = '#Url.Action("DoSomething", "Customer")?id=' + id + '&deptno=' + deptno;
please guide me.
Actually you can pass JSON string from array with #Url.Action() helper using query string parameter like this:
<script>
$(function() {
var id = "10";
var deptno = "C001";
var PdfInputs = [];
for (var i = 0; i < totalbol; i++)
{
PdfInputs.push({
firstName: "John",
lastName: "Doe",
age: 46
});
}
location.href = '#Url.Action("DoSomething", "Customer")?id=' + id + '&deptno=' + deptno + '&PdfInputs=' + JSON.stringify(PdfInputs);
})
</script>
However I strongly discourage this practice because passed JSON string may exceeds query string limit if the array has large amount of data. Additionally, you cannot use #Url.Action() helper for action method marked with [HttpPost] attribute (it only works for GET method), hence I recommend to use jQuery.ajax() to pass PdfInputs array as List<PdfInputs> & TempData/Session state variable to store file contents, then download PDF file using HttpGet controller action as provided below:
jQuery
<script>
$(function() {
var id = "10";
var deptno = "C001";
var PdfInputs = [];
for (var i = 0; i < totalbol; i++)
{
PdfInputs.push({
firstName: "John",
lastName: "Doe",
age: 46
});
}
$('#buttonid').click(function () {
$.ajax({
type: 'POST',
url: '#Url.Action("DoSomething", "Customer")',
// traditional: true,
data: $.param({ id: id, deptno: deptno, pdfInputs: PdfInputs }, true),
success: function (result) {
location.href = '#Url.Action("Download", "ControllerName")?id=' + id;
},
error: function (err) {
// error handling
}
});
});
})
</script>
Controller (DoSomething Action)
[HttpPost]
public ActionResult DoSomething(string id, string deptno, List<PdfInputs> pdfInputs)
{
// Some magic code here...
// Save file to TempData or Session state
byte[] fileContent = fileStreamInstance.ToArray();
TempData["FileToDownload"] = fileContent;
return Json("Success");
}
Controller (Download Action)
[HttpGet]
public ActionResult Download(string id)
{
string fileName = "yourfilename.pdf";
// other code here
if (TempData["FileToDownload"] != null)
{
byte[] content = TempData["FileToDownload"] as byte[];
return File(content, "application/pdf", fileName);
}
else
{
return new EmptyResult();
}
}
Click on this fiddle https://dotnetfiddle.net/RRwK1K
View
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Tut123</title>
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script type="text/javascript">
$(function () {
$("#theButton").click(function () {
var id = "10";
var deptno = "C001";
var PdfInputs = [];
var i;
for (i = 0; i <= 3; i++) {
PdfInputs.push({
firstName: "John",
lastName: "Doe",
age: 46
});
}
var json = JSON.stringify(PdfInputs);
location.href = '#Url.Action("theActionPassArray", "Home")?json=' + json;
})
})
</script>
</head>
<body>
<input type="button" id="theButton" value="Go" />
#*credit to https://stackoverflow.com/questions/15112055/passing-dynamic-javascript-values-using-url-action*#
#if (ViewBag.Data != null)
{
<span>The data sent to the server was:</span>#ViewBag.Data
}
</body>
</html>
Controller
public class PassArray
{
public string firstName { get; set; }
public string lasttName { get; set; }
public string age { get; set; }
}
public class HomeController : Controller
{
public ActionResult theActionPassArray(string json)
{
/turn json passed value into array
//You need to get NewtonSoft.JSON
PassArray[] arr = JsonConvert.DeserializeObject<PassArray[]>(json);
//put breakpoint here
ViewBag.Data = json;
return View("Tut123"); }
public ActionResult Tut123()
{
return View();
}

How can I prevent passing in multiple parameters to controller?

Right now I have a form that contains 6 security questions and 6 security answers. I've been trying to refactor my code and I'm running into an interesting situation that I'm not sure on how to proceed.
Here's my view:
var RequestSecurityQuestions_Submit = function () {
ValidationAttribute.BlankValue(true);
var form = $('form#RequestSecurityQuestions');
$.validator.unobtrusive.parse(form);
var d = $('form#RequestSecurityQuestions').serialize();
SecurityQuestionsValid = true;
var inputs = $('form#RequestSecurityQuestions').find('input[data-val]');
$.each(inputs, function (index) {
var input = inputs[index];
if (!$(input).valid()) {
SecurityQuestionsValid = false;
}
});
var dataObject = {}, dropdowns = $("input.customdropdownlist");
for (var i = 0; i < 6; i++) {
dataObject['question' + i] = $(dropdowns[i]).data("kendoDropDownList").value()
}
for (var i = 1; i < 7; i++) {
dataObject['answer' + i] = $('#idAnswer' + i).val();
}
var dataToPass = JSON.stringify(dataObject);
if (SecurityQuestionsValid) {
$.ajax({
url: Url.getFullUrl('Account/RequestSecurityQuestions_Submit'),
type: 'Post',
data: { securityInfo: dataToPass },
dataType: 'json',
cache: false,
success: function (data) {
//Next Dialog
},
error: AjaxLog.HandleAjaxCallFail
});
}
return SecurityQuestionsValid;
}
I get a dataObject which contains all the values from my view and I want to pass it to the controller.
Currently this works:
[AllowAnonymous]
[HttpPost]
public ActionResult RequestSecurityQuestions_Submit(string answer1, string answer2, string answer3, string answer4, string answer5, string answer6, string question1, string question2, string question3, string question4, string question5, string question6)
{
SecurityQuestions securityQuestions = new SecurityQuestions();
if (!string.IsNullOrEmpty(answer1))
{
securityQuestions.ChallengeA1 = answer1;
}
if (!string.IsNullOrEmpty(answer2))
{
securityQuestions.ChallengeA2 = answer2;
}
if (!string.IsNullOrEmpty(answer3))
{
securityQuestions.ChallengeA3 = answer3;
}
//etc....
}
However, I am passing in 12 parameters to my controller which sounds like a no-no to me. Is there another way to pass in my data from my view to my controller without having to pass in 12 parameters?
EDIT:
New controller attempt:
/*Problem: securityInfo array looks like: ""{\"question0\":\"2\",\"question1\":\"3\",\"question2\":\"4\",\"question3\":\"5‌​\",\"question4\":\"7\",\"question5\":\"1\",\"answer1\":\"fgfg\",\"answer2\":\"fgf‌​gf\",\"answer3\":\"fgfg\",\"answer4\":\"fgfgfg\",\"answer5\":\"fgfg\",\"answer6\"‌​:\"fggf\"}"" */
[AllowAnonymous]
[HttpPost]
public ActionResult RequestSecurityQuestions_Submit(string[] securityInfo)
{
SecurityQuestions securityQuestions = new SecurityQuestions();
}
There are multiple ways to achieve this of course, the following is one of them. A better one would be to restructure your code as per other answers/comments.
// Creating your array
var dataObject = [],
dropdowns = $("input.customdropdownlist");
//Populate your array. [0-5] will be questions and [6-11] will be answers .
for (var i = 0; i < 6; i++) {
if (i < 6){
dataObject[i] = $(dropdowns[i]).data("kendoDropDownList").value()
}
else {
var d = i - 5;
dataObject[i] = $('#idAnswer' + d).val();
}
}
// Your AJAX call with contentType
$.ajax({
url: Url.getFullUrl('Account/RequestSecurityQuestions_Submit'),
type: 'Post',
data: JSON.Stringify(dataObject), //Change data format to JSON array, will be received as array in backend
contentType: "application/json",
cache: false,
success: function (data) {
//Next Dialog
},
error: AjaxLog.HandleAjaxCallFail
});
And simply receive the array in your backend
public ActionResult RequestSecurityQuestions_Submit(List<String> data)
{
//Your code here
}
Mate, Well, I don't understand why you have N parameters which has the same type of data--- that's really where the class should come for.
Short Answer will be you can create a Model which contains these parameters, then on your controller, just RequestSecurityQuestions_Submit(Model postedModel)
then access your parameters inside like postedModel.parameter1 ... In you ajax call , it looks like
$.ajax({
url: Url.getFullUrl('Account/RequestSecurityQuestions_Submit'),
type: 'Post',
data: {parameter1:'',parameter2:''...},
cache: false,
success: function (data) {
//Next Dialog
},
Multiple parameter(n>3) on any function is bad in theory and practice,
You can simplify all this by correctly using a model, binding to a model and posting back you model.
View models
public class SecurityAnswerVM
{
[Required(ErrorMessage="Please select a question")]
[Display(Name = "Question")]
public int? QuestionID { get; set; }
[Required(ErrorMessage = "Please enter an answer")]
public string Answer { get; set; }
}
public class SecurityLoginVM
{
public SelectList QuestionList { get; set; }
public List<SecurityAnswerVM> SelectedQuestions { get; set; }
}
Controller
[HttpGet]
public ActionResult Index()
{
SecurityLoginVM model = new SecurityLoginVM();
// Populate SelectedQuestions and QuestionList from the database
return View(model);
}
[HttpPost]
public ActionResult Index(SecurityLoginVM model)
{
// model.SelectedQuestions contains the 6 objects containing the QuestionID and the users Answer
....
}
EditorTemplate (/Views/Shared/EditorTemplates/SecurityAnswerVM.cshtml)
#model yourAssembly.SecurityAnswerVM
#Html.LabelFor(m => m.QuestionID)
#Html.DropDownListFor(m => m.QuestionID, (SelectList)ViewData["options"], "Please select", new { #class = "question" })
#Html.ValidationMessageFor(m => m.QuestionID)
#Html.LabelFor(m => m.Answer)
#Html.TextAreaFor(m => m.Answer)
#Html.ValidationMessageFor(m => m.Answer)
Main view
#model yourAssembly.SecurityLoginVM
#using(Html.BeginForm())
{
#Html.EditorFor(m => m.SelectedQuestions, new { options = Model.QuestionList })
<button id="save type="submit">Save</button> // or type="button" is posting via ajax
}
And if you want to use ajax to post the data
var url = '#Url.Action("Index")';
$('#save').click(function() {
$.post(url, $('form').serialize(), function(data) {
// Next Dialog
});
});
Far less code, strongly typed model binding, client and server side validation and all the other beneficial features of using MVC!
Why not doing something like this -
public class QA {
public int QId {get;set;}
public string Answer {get;set;}
}
[AllowAnonymous]
[HttpPost]
public ActionResult RequestSecurityQuestions_Submit(QA[] answers)
{
for (var qa in answers){
//do what ever you like
}
}
and then in js -
// Creating your array
var dataObject = [],
var dropdowns = $("input.customdropdownlist");
for (var i = 0; i < 6; i++) {
dataObject[i] = {
'QId': $(dropdowns[i]).data("kendoDropDownList").value(),
'Answer': dataObject[i] = $('#idAnswer' + i).val();
};
}
$.ajax({
url: Url.getFullUrl('Account/RequestSecurityQuestions_Submit'),
type: 'Post',
data: JSON.stringify(dataObject),
contentType: "application/json",
cache: false,
success: function (data) {
},
error: function(data){
}
});

Loop thru form to fill json object for post

I have a shopping cart and want to post it to my login window so I can proceed to checkout after authentication. But before this can be achieved, I am using a webservice call on shoppingcart window load, so I can get a hash of my cart items and secure the communication between us. How can I serialize all my cart items in the data object so I can send it to my webserver?
This is what I am trying so far, but it isn't working...
$(document).ready(function () {
getCartHashCode();
});
function getCartHashCode() {
var url = 'home/GetHashRequest';
var data = new Array();
//put all items from the cart on the data object
for (i = 1; i <= $('.product-name').length; i++) {
//setting up json parameter names
var CART_NAME = 'CART_'+i+'_NAME';
var CART_PRICE = 'CART_'+i+'_PRICE';
var obj = { CART_NAME: $('input[name=Cart['+i+'].Name').val(),
CART_PRICE: $('input[name=Cart['+i+'].Price').val() }
data.push(obj);
}
$.ajax({
type: 'POST',
url: url,
data: data,
success: function (hash) {
alert("It worked! Hash = " + hash.toString());
}
});
EDIT
Follow up after ferrants' comment: I took it off, and really did go to the server! Thanks
The problem is how do I get the items I posted on the server side?
I have a item domain class defined as this:
public class Item
{
public string Name { get; set; }
public int UnitPrice { get; set; }
}
and my controller action is this:
public string GetHashRequest(List<Item> cart)
{
GetSecureHashPOCORequest hashRequest = new GetSecureHashPOCORequest();
}

Categories

Resources