Pass JSON object list to action - javascript

I have a Model like this in my ASP.NET MVC 2 project,
public class HomeModel
{
public string Name { get; set; }
public int HomeCount { get; set; }
private List<string> _list;
public List<string> List
{
get
{
if (_list == null)
{
_list = new List<string>();
}
return _list;
}
set
{
_list = value;
}
}
private List<ChildModel> _children;
public List<ChildModel> Children
{
get
{
if (_children == null)
{
_children = new List<ChildModel>();
}
return _children;
}
set
{
_children = value;
}
}
}
public class ChildModel
{
public string Address { get; set; }
}
and the script as
var obj = new Object();
obj.Name = "MyName";
obj.HomeCount = 56;
obj.List = new Array();
obj.List[0] = "AAA";
obj.List[1] = "bbb";
var child = new Object();
child.Address = "ccc";
obj.Children = new Array();
obj.Children[0] = child;
var child2 = new Object();
child.Address = "ddd";
obj.Children[1] = child2;
jQuery.ajaxSettings.traditional = true
$.post('/Home/Test',obj, function (data) { });
My problem is even the string list is generated at the controller's action, the object list's count is 0. Can anyone tell how to do this?

When you submit an object as jQuery's ajax payload, it's converted to key/value pairs of data. If this were $.get instead of $.post for example, you'd wind up with
?name=MyName&etc.
This article should get you what you're looking for:
http://www.intelligrape.com/blog/2010/06/11/jquery-send-json-object-with-an-ajax-request/
I'd also recommend json/object literal notation here:
var obj = {
Name: "MyName",
HomeCount: 56,
List:["AAA","bbb"],
child:{
Address: "ccc",
Children:[
//etc
]
}
}
see json.org for specs, and jslint.com/jshint.com for validation.

Related

JSON data null in controller

I am working to send multiple email/SMS by selecting the checkbox. And When I am receiving in my javascript function it's getting with data. But when I pass it to action method record count shows but all data are null. Below is my code with screenshot here
Here it is my Model:
public class BulkEmailSendViewModel
{
public BulkEmailSendViewModel()
{
Candidates = new List<CandidateData>();
}
public List<CandidateData> Candidates { get; set; }
public string Body { get; set; }
public string Subject { get; set; }
}
public class CandidateData
{
public string Email { get; set; }
public string CandidateId { get; set; }
public string Phone { get; set; }
public string CandidateName { get; internal set; }
}
//Select all selected checkbox
$("#bulkAction").change(function () {
var ddlId = $("#bulkAction").val();//to get sms or email
var chk_arr = $('.checkCandidate:checkbox:checked');
var chklength = chk_arr.length;
var json = '';
$('.checkCandidate:checkbox:checked').each(function () {
if (this.checked) {
var Phone = $(this).attr("candidatePhone");
var CandidateId = $(this).attr("candidateId");
var Email = $(this).attr("candidatEmail");
var item = '{\"Phone\":\"' + Phone + '\","CandidateId\":\"' + CandidateId + '\",\"Email\":\"' + Email + '\",\"CandidateName\":\"\"},';
json += item;
}
});
json = "[" + json.substr(0, json.length - 1) + "]";
SendBulkEmail(json);
});
My Javascript:
function SendBulkEmail(jsonObj) {
alert(jsonObj);
if (jsonObj.length > 0) {
var send = "/Utility/Notifications/BulkEmail";
$(".modal-title").text("Send Email");
//var data = {
// Candidates: eval(jsonObj)
//};
$.get(send, { bulkEmailSendViewModel: eval(jsonObj) }, function (result) {
$("#C_modal_body").html("");
$("#C_modal_body").html(result);
});
}
else {
$.alert("Email not found for this candidate.");
// e.stopPropagation();
}
}
My Controller:
public PartialViewResult BulkEmail(List<CandidateData> bulkEmailSendViewModel)
{
BulkEmailSendViewModel bulkDetail = new BulkEmailSendViewModel();
return PartialView(bulkDetail);
}
Why my all values are null even I am getting in javascript function?
change your javascript codes to this:
$("#bulkAction").change(function () {
var ddlId = $("#bulkAction").val();//to get sms or email
var chk_arr = $('.checkCandidate:checkbox:checked');
var chklength = chk_arr.length;
var data = [];
$('.checkCandidate:checkbox:checked').each(function () {
if (this.checked) {
var Phone = $(this).attr("candidatePhone");
var CandidateId = $(this).attr("candidateId");
var Email = $(this).attr("candidatEmail");
var item = {Phone: Phone,
CandidateId: CandidateId,
Email : Email,
CandidateName : ""};
data.push(item);
}
});
SendBulkEmail(data);
});
and the SendBulkEmail to:
function SendBulkEmail(data) {
if (data.length > 0) {
var send = "/Utility/Notifications/BulkEmail";
$(".modal-title").text("Send Email");
//var data = {
// Candidates: eval(jsonObj)
//};
$.post(send, { bulkEmailSendViewModel: JSON.stringify(data) }, function (result) {
$("#C_modal_body").html("");
$("#C_modal_body").html(result);
});
}
else {
$.alert("Email not found for this candidate.");
// e.stopPropagation();
}
}
and finally:
[HttpPost]
public PartialViewResult BulkEmail(List<CandidateData> bulkEmailSendViewModel)
{
BulkEmailSendViewModel bulkDetail = new BulkEmailSendViewModel();
return PartialView(bulkDetail);
}
In your controller, I don't see any use of the bulkEmailSendViewModel input parameter.
Maybe, you could propagate the candidate list as follow:
public PartialViewResult BulkEmail(List<CandidateData> candidates)
{
BulkEmailSendViewModel bulkDetail=new BulkEmailSendViewModel();
bulkDetail.candidates = candidates;
return PartialView(bulkDetail);
}

How to build a javascript function as an object in C#?

I want to build an object in C# like this.
public JsonResult GetMyObject(){
var MyObject =
new
{
Myfunction = "function (params) {
var res = params[0].seriesName + ' ' + params[0].name;
res += '<br/> Start : ' + params[0].value[0] + ' Max : ' + params[0].value[3];
res += '<br/> End : ' + params[0].value[1] + ' Min : ' + params[0].value[2];
return res;
}",
Element1 = "Test Element",
Element2 = 123
};
return Json(MyObject);
}
But when I return the json object to javascript, the "Myfunction" element in MyObject is just a string, not a javascript function.
How can I build a javascript function as an object in C#?
If you want return object, better you can create a class, populate and send class as return item, it will send you JSON format.
public class MyFucntion
{
public string SeriesName { get; set; }
public string Start { get; set; }
public string End { get; set; }
public string Max { get; set; }
public string Min { get; set; }
}
public class MyObject {
public MyFucntion myFun { get; set; }
public string Element1 { get; set; }
public string Element2 { get; set; }
}
public JsonResult GetMyObject()
{
var fun = new MyFucntion
{
SeriesName =params[0].name,
Max = params[0].value[3],
Min = params[0].value[2],
Start =params[0].value[0],
End = params[0].value[1]
};
var obj = new MyObject {
myFun = fun,
Element1 ="ElE",
Element2 = "ELE2"
};
return JSON(obj);
}
If you are using asp.net website you can use web Mehtod and you need to change the code.
[System.Web.Services.WebMethod]
public static MyObject GetMyObject()
{
var fun = new MyFucntion
{
SeriesName =params[0].name,
Max = params[0].value[3],
Min = params[0].value[2],
Start =params[0].value[0],
End = params[0].value[1]
};
var obj = new MyObject {
myFun = fun,
Element1 ="ElE",
Element2 = "ELE2"
};
return obj;
}

Converting JSON object into C# list

Before posting this question I tried other related posts but it didn't work out, so posting here.
I have got a Json stored in a hidden field that I am accessing in code behind file of my Mark-up page. I need to convert this Json into List and bind it to a grid, but while de-serializing it throws error saying "Unexpected error encountered while parsing values ''".
Script for getting data from grid and making a Json object.
function BeforeSorting() {
var list = UpdateDataSource();
$("#SortingField").val(list);
}
function UpdateDataSource() {
var list="";
var grid = $find("DetailsGrid");
var rows = grid.get_rows();
for(var i =0 ; i<rows.get_length();i++){
var name = rows.get_row(i).get_cellByColumnKey("Name").get_value();
var country = rows.get_row(i).get_cellByColumnKey("Country").get_value();
var gender = rows.get_row(i).get_cellByColumnKey("Gender").get_value();
var age = rows.get_row(i).get_cellByColumnKey("Age").get_value();
var uniqueKey = rows.get_row(i).get_cellByColumnKey("UniqueKey").get_value();
list = list + '{"Name":"' + name + '", "Country":"' + country + '", "Gender":"' + gender + '", "Age":' + age + ', "UniqueKey":' + uniqueKey + '},';
}
list = "["+list.substr(0, list.length - 1)+"]";
return JSON.parse(list);
}
The model class:
public class Details
{
public string Name { get; set; }
public string Gender { get; set; }
public string Country { get; set; }
public int UniqueKey { get; set; }
public int Age { get; set; }
}
The code for de-serializing the json and retrieving data as a list of the model class.
protected void DetailsGrid_ColumnSorted(object sender, Infragistics.Web.UI.GridControls.SortingEventArgs e)
{
var dataSource = SortingField.Value;
List<Details> result = (List<Details>)Newtonsoft.Json.JsonConvert.DeserializeObject(dataSource, typeof(List<Details>));
DetailsGrid.DataSource = result;
DetailsGrid.DataBind();
}
The json string as obtained:
"[{"Name":"Jerry", "Country":"U.S.A.", "Gender":"Male", "Age":20, "UniqueKey":1},{"Name":"Tom", "Country":"U.K", "Gender":"Male", "Age":10, "UniqueKey":2},{"Name":"George", "Country":"Gremany", "Gender":"Male", "Age":38, "UniqueKey":3},{"Name":"Kate", "Country":"France", "Gender":"Female", "Age":40, "UniqueKey":4},{"Name":"Jenny", "Country":"Poland", "Gender":"Female", "Age":25, "UniqueKey":5}]"
create list as an array and add items as JavaScript objects and then convert it to JSON using JSON.stringify
function UpdateDataSource() {
var grid = $find("DetailsGrid");
var rows = grid.get_rows();
var list = [];
for(var i =0 ; i < rows.get_length(); i++){
var item = {
Name : rows.get_row(i).get_cellByColumnKey("Name").get_value(),
Country : rows.get_row(i).get_cellByColumnKey("Country").get_value(),
Gender : rows.get_row(i).get_cellByColumnKey("Gender").get_value(),
Age : rows.get_row(i).get_cellByColumnKey("Age").get_value(),
UniqueKey : rows.get_row(i).get_cellByColumnKey("UniqueKey").get_value()
};
list.push(item);
}
return JSON.stringify(list);
}
The code for de-serializing the json and retrieving data as a list of the model class can be refactored to
protected void DetailsGrid_ColumnSorted(object sender, Infragistics.Web.UI.GridControls.SortingEventArgs e) {
var dataSource = SortingField.Value;
var result = Newtonsoft.Json.JsonConvert.DeserializeObject<List<Details>>(dataSource);
DetailsGrid.DataSource = result;
DetailsGrid.DataBind();
}
UPDATE as suggested by #Adnreas should produce the same result.
function UpdateDataSource() {
var grid = $find("DetailsGrid");
var rows = grid.get_rows();
var list = rows.map(function(row) {
return {
Name: row.get_cellByColumnKey("Name").get_value(),
Country: row.get_cellByColumnKey("Country").get_value(),
Gender: row.get_cellByColumnKey("Gender").get_value(),
Age: row.get_cellByColumnKey("Age").get_value(),
UniqueKey: row.get_cellByColumnKey("UniqueKey").get_value()
};
});
return JSON.stringify(list);
}
I think this will do
protected void DetailsGrid_ColumnSorted(object sender, Infragistics.Web.UI.GridControls.SortingEventArgs e)
{
var dataSource = SortingField.Value;
List<Details> result = Newtonsoft.Json.JsonConvert.DeserializeObject<List<Details>>(dataSource);
DetailsGrid.DataSource = result;
DetailsGrid.DataBind();
}

Generating array of arrays

I have a Web-API method that is returning JSON and I want the array structure to look like this:
[ [123, 1.1], [222, 3.9] ]
My Web API controller is returning JSON in the following format:
[{"CreatedDate":1314736440,"Reading":20.0}, "CreatedDate":1314779640,"Reading":7.9}]
Web API Controller:
[HttpGet]
public HttpResponseMessage AllJson()
{
using (var ctx = new SomeContext())
{
var records = ctx.DataX.ToList();
var dtos = Mapper.Map<...>(records);
return new HttpResponseMessage
{
StatusCode = HttpStatusCode.OK,
Content = new StringContent(JsonConvert.SerializeObject(dtos), Encoding.UTF8, "application/json")
};
}
}
DTO
public class DtoModel
{
public int CreatedDate { get; set; }
public double Reading { get; set; }
}
Sample Javascipt:
var seriesData = [];
$.getJSON("api/xxx/AllJson ", function (data) {
$.each(data, function (key, val) {
seriesData.push(val.CreatedDate.toString() + " ," + val.Reading.toString());
console.log(val.CreatedDate + " ," + val.Reading);
});
});
You need to create an a single array containing many arrays of length 2.
See this code:
$.getJSON("api/xxx/AllJson")
.done(function (data) {
var processedJson = new Array();
$.map(data, function (obj, i) {
processedJson.push([obj.CreatedDate, obj.Reading]);
});
FunctionToDoSomethingWithYourDataStructure(processedJson);
});
I think this might solve your problem..
structure wise, this should look like [[a,b],[c,d]];
var createSeriesData = function(){
seriesData = [];
JSON_obj = JSON.parse('[{"CreatedDate":1314736440,"Reading":20.0},{"CreatedDate":1314779640,"Reading":7.9}]');
for(var key in JSON_obj){
if(JSON_obj.hasOwnProperty(key)){
seriesData[key] = [];
seriesData[key].push(JSON_obj[key].CreatedDate.toString());
seriesData[key].push(JSON_obj[key].Reading.toString());
}
}
console.log(seriesData);
}

Refresh page 5 times every half second, then append querystring to url using javascript or JQuery

I need to write some JavaScript or jQuery that refreshes a page, 5 times only, every 0.5 secs then once that is done append a querystring variable (?refreshed=yes) to the url using javascript or JQuery.
At present I have only been able to refresh once after 0.5 secs and append the ?refreshed=yes querystring. Can someone please point me in the right direction, many thanks in advance for any replies.
<script>
window.onload = function () {
if (!window.location.search) {
setTimeout("window.location+='?refreshed=yes';", 500);
}
}
</script>
C# code -
using LinkChex.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text.RegularExpressions;
using System.Threading;
using System.Web;
namespace LinkChex.Base
{
public class WebSpider
{
const int LIMIT = 10;
string[] invalidTypes = { ".zip", ".doc", ".css", ".pdf", ".xls", ".txt", ".js", ".ico" };
public List<LinkModels> Links;
public bool foundMatch = false;
public bool IsRunning { get; set; }
public bool IsDone { get; set; }
public int totLinks { get; set; }
public WebSpider()
{
this.Links = new List<LinkModels>();
}
public void Execute(string url)
{
this.Links.Clear();
this.Links.Add(new LinkModels() { Status = HttpStatusCode.OK, NavigateUrl = url });
this.IsRunning = true;
WaitCallback item = delegate(object state) { this.FindLinks((UrlState)state); };
ThreadPool.QueueUserWorkItem(item, new UrlState() { Url = url, Level = 0 });
this.totLinks = Links.Count();
}
public void FindLinks(UrlState state)
{
try
{
string html = new WebClient().DownloadString(state.Url);
MatchCollection matches = Regex.Matches(html, "href[ ]*=[ ]*['|\"][^\"'\r\n]*['|\"]");
foreach (Match match in matches)
{
string value = match.Value;
value = Regex.Replace(value, "(href[ ]*=[ ]*')|(href[ ]*=[ ]*\")", string.Empty);
if (value.EndsWith("\"") || value.EndsWith("'"))
value = value.Remove(value.Length - 1, 1);
if (!Regex.Match(value, #"\((.*)\)").Success)
{
if (!value.Contains("http:"))
{
Uri baseUri = new Uri(state.Url);
Uri absoluteUri = new Uri(baseUri, value);
value = absoluteUri.ToString();
}
if (this.Links.Exists(x => x.NavigateUrl.Equals(value))) continue;
try
{
bool validLink = true;
foreach (string invalidType in invalidTypes)
{
string v = value.ToLower();
if (v.EndsWith(invalidType) || v.Contains(string.Format("{0}?", invalidType)))
{
validLink = false;
break;
}
}
if (validLink)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(value);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
//add the OK link to the List object
//COMMENTED TO FILTER OUT OK LINKS
// this.Links.Add(new LinkModels() { Status = response.StatusCode, NavigateUrl = value });
if (response.StatusCode == HttpStatusCode.OK && state.Level < LIMIT)
{
WaitCallback item = delegate(object s) { FindLinks((UrlState)s); };
ThreadPool.QueueUserWorkItem(item, new UrlState() { Url = value, Level = state.Level + 1 });
}
}
}
catch
{
//add the ExpectationFailed link/s to the List object
this.Links.Add(new LinkModels(){ Status = HttpStatusCode.ExpectationFailed, NavigateUrl = value});
// this.IsDone = true;
}
}
}
}
catch
{
///
/// If downloading times out, just ignore...
///
}
}
}
}
controller class -
public WebSpider WebSpider
{
get { return (WebSpider)(Session["webSpider"] ?? (Session["webSpider"] = new WebSpider())); }
}
[AcceptVerbs(HttpVerbs.Get | HttpVerbs.Post)]
public ActionResult Details(string refreshed, int id = 0)
{
LinkModels lm = new LinkModels();
Domain domain = db.Domains.Find(id);
if (domain == null)
{
return HttpNotFound();
}
else
{
if (!this.WebSpider.IsRunning)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(domain.DomainDesc);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
if (response.StatusCode == HttpStatusCode.OK)
this.WebSpider.Execute(domain.DomainDesc);
}
if (!this.WebSpider.IsRunning)
{
lm.SpiderRunning = this.WebSpider.IsRunning;
}
}
//remove duplicates from list object
var distinctList = this.WebSpider.Links.GroupBy(x => x.NavigateUrl)
.Select(g => g.First())
.ToList();
//only send email if page has been refreshed, NOT on initial load
if (Request["refreshed"] == "yes")
{
SendCertificate(domain.UserProfiles.UserName, domain.UserProfiles.UserEmail, domain.DomainDesc, distinctList);
}
return View(distinctList);
}
In query string add one more parameter like refresh=X and in your function parse this parameter.
The other option is for example use local storage for storing this data.
You can try something like:
var l = document.location,
m = l.search.match(/counter=(\d+)/),
counter = parseInt(m&&m[1]) || 0;
if (counter<5)
setTimeout(function() {
l.href = l.origin+l.pathname+"?counter="+(++counter);
},500);

Categories

Resources