I am developing an asp.net MVC web app in which I am using Linq to Sql for getting the results from database through jquery and ajax. My model has following code
public IEnumerable<string> getComments(long problemID)
{
var comment = from c in _objectModel.Comments
where c.ProblemID == problemID
select new { c.EmpID, c.CommentText, c.Time }.ToString();
return comment;
}
and my controller has following code
public string GetComments(string problemid)
{
List<string> collection = _discussionRepository.getComments(Convert.ToInt32(problemid)).ToList();
string comments = null;
foreach (string item in collection)
{
comments += item + "\n";
}
return comments;
}
and in my view contains
$("#btnPostComment").click(function () {
var strdata = {
problemID: $("#problemID").val(),
commentText: $("#_1").val(),
empID: $("#empID").val(),
agree: 0,
disagree: 0
};
$.ajax({
type: "POST",
url: "<%= Url.Action("PostComment", "Discussion") %>",
data: strdata,
error: function(msg){
alert("error" + msg);
},
success: function (msg) {
var id = { problemid : $("#problemID").val()};
$.ajax({
type: "GET",
url: "<%= Url.Action("GetComments", "Discussion") %>",
data: id,
error: function(msg){
alert("error2" + msg);
},
success: function (msg) {
$("#commentdiv").html(msg);
}
});
}
});
and I am getting the following result in my asp page
{ EmpID = 1, CommentText = sss, Time = 1/27/2012 2:20:49 AM } { EmpID = 1, CommentText = aaa, Time = 1/27/2012 2:46:07 AM } { EmpID = 1, CommentText = aaa, Time = 1/27/2012 2:50:23 AM } { EmpID = 1, CommentText = Munazza, Time = 1/27/2012 2:58:29 AM } { EmpID = 1, CommentText = Jawad, Time = 1/27/2012 3:00:51 AM } { EmpID = 1, CommentText = xx, Time = 1/28/2012 11:56:59 AM } { EmpID = 1, CommentText = ss, Time = 1/28/2012 12:35:00 PM }
I want to get the result without braces and without properties i.e 1 ss 1/27/2012
Regards
The problem is that you're calling ToString on the anonymous type. Does your existing Comment model class contain too much data? If not, you can just use:
public List<Comment> GetComments(long problemID)
{
return _objectModel.Comments.Where(c => c.ProblemID == problemID)
.ToList(); // Force evaluation
}
You'd then change your controller to convert this List<Comment> into AJAX which the Javascript could understand.
If you really only want strings without properties, you could just change your original code to:
public IEnumerable<string> GetComments(long problemID)
{
var query = from c in _objectModel.Comments
where c.ProblemID == problemID
select new { c.EmpID, c.CommentText, c.Time };
return query.AsEnumerable() // Do the rest locally
.Select(c => string.Format("{0} {1} {2"}, c.EmpID,
c.CommentText, c.Time));
}
You should also change your controller code to either use String.Join or a StringBuilder - as otherwise you're going to have an O(n2) problem due to repeated string concatenation...
Looking at your client-side code it seems you're expecting formatted html from the ajax call, but you're simply returing ToString (as Jon Skeet says).
If this is your intent then you should format the string into valid HTML, but it would be better to return the data in json format and turn it into HTML client-side.
Related
I have found that when converting my arrays to JSON, there are extra square brackets that are preventing the data from being parsed.
I make an AJAX call which prepares the data server side. The C# processes the data and turns it into an array of arrays for Google Charts to process.
It is all dynamic, so I have no idea how many arrays there will be, hence I cannot hardcode the arrays and I cannot loop the client side as the performance is shocking.
I don't think the JSON parser in the JavaScript is the issue, it is in the C# I have written.
I have added two JSON links, one is the output, the other is the expected output.
My C# is:
public List<object[]> CreateJsonMultiChartData(string serial, string guid, string datefrom, string dateto)
{
var serials = _context.RawData.Where(x => x.ProjectGuid == guid).Select(x => x.SerialNumber).Distinct().ToList();
var projectUid = guid;
var from = datefrom;
var to = dateto;
//Method to return data
var g = new GetChartDataSprocs(_context, _configuration);
List<object> chartData = new List<object>();
var arrays = new List<object[]>();
foreach (var s in serials)
{
var data = g.GetChartDataFromSqlServer(s, projectUid, from, to);
foreach (var item in data)
{
var year = Convert.ToDateTime(item.ReadingDate).Year;
var month = Convert.ToDateTime(item.ReadingDate).Month;
var day = Convert.ToDateTime(item.ReadingDate).Day;
var hour = Convert.ToDateTime(item.ReadingDate).Hour;
var minute = Convert.ToDateTime(item.ReadingDate).Minute;
var second = Convert.ToDateTime(item.ReadingDate).Second;
var date = "new Date(" + year + "," + month + "," + day + "," + hour + "," + minute + "," + second + ")";
chartData.Add(
new ChartTestModel
{
ReadingDate = date,
ReadingValue = item.ReadingValue
});
};
arrays.Add(new[] { chartData });
}
return arrays;
}
My AJAX response is:
public JsonResult GetMultiChartData(string serial, string uid, string from, string to)
{
var dateFrom = Convert.ToDateTime(from).ToString("yyyy-MM-dd HH:mm:ss");
var dateTo = Convert.ToDateTime(to).AddMinutes(1).ToString("yyyy-MM-dd HH:mm:ss");
var g = new GetChartData(_context, _configuration);
var items = g.CreateJsonMultiChartData(serial, uid, dateFrom, dateTo);
//var dsItems = JsonConvert.DeserializeObject(items);
// return items;
return Json(JsonConvert.SerializeObject(items, Formatting.Indented));
}
My AJAX call is:
$.ajax({
url: 'ProjectCharts/GetMultiChartData',
datatype: 'json',
type: 'get',
async: false,
data: { section: section, uid: uid, from: from, to: to },
contentType: 'application/json; charset=utf-8',
success: function (d) {
parsedData = $.parseJSON(d);
var data = new google.visualization.arrayToDataTable([
{ label: 'Date', id: 'ReadingDate', type: 'date' }, // Use object notation to explicitly specify the data type.
{ label: 'Data', id: 'ReadingValue', type: 'number' }, [parsedData]]);
var chart = new google.visualization.LineChart(document.getElementById('chart'));
var options = multiLineChartOptions();
chart.draw(data, options);
},
error: function () {
alert("Error");
}
});
The output is at:
Current JSON Ouput
The expected output is:
Expected JSON Output
I am using the Google.DataTable wrapper by #zoranmax. I can get a single line chart to work fine. What I want to do is display multiple lines.
When I return the JSON to AJAX call to create the chart I am told that I have no columns in the table.
The C# return produces a list of string that is indexed, so for each series, there is a 0,1,2 etc.
Here is an example of the JSON output JSON Output, there are 20 of these arrays that are returned from the C# code in one hit to AJAX call.
As you can see the JSON validates, but it just won't work.
The AJAX call:
$.ajax({
url: 'ProjectCharts/GetMultiChartData',
datatype: 'json',
type: 'get',
async: false,
data: { section: section, uid: uid, from: from, to: to },
contentType: 'application/json; charset=utf-8',
success: function (d) {
parsedData = $.parseJSON(d);
console.log(parsedData);
var data = new google.visualization.DataTable(parsedData);
var chart = new google.visualization.LineChart(document.getElementById('chart'));
var options = multiLineChartOptions();
chart.draw(data, options);
},
error: function () {
alert("Error");
}
});
The C# part:
public string CreateJsonMultiChartDataTable(string serial, string guid, string datefrom, string dateto)
{
var serials = _context.LogTagRawData.Where(x => x.ProjectGuid == guid).Select(x => x.SerialNumber).Distinct().ToList();
var projectUid = guid;
var from = datefrom;
var to = dateto;
List<string> multiDt = new List<string>();
try
{
foreach (var s in serials)
{
var data = GetChartDataFromSqlServer(s, projectUid, from, to);
var dt = new Google.DataTable.Net.Wrapper.DataTable();
dt.AddColumn(new Google.DataTable.Net.Wrapper.Column(Google.DataTable.Net.Wrapper.ColumnType.Datetime, "Date", "Date"));
dt.AddColumn(new Google.DataTable.Net.Wrapper.Column(Google.DataTable.Net.Wrapper.ColumnType.Number, "Data", "Data"));
foreach (var item in data)
{
Google.DataTable.Net.Wrapper.Row r = dt.NewRow();
r.AddCellRange(new Google.DataTable.Net.Wrapper.Cell[]
{
new Google.DataTable.Net.Wrapper.Cell(Convert.ToDateTime(item.ReadingDate)),
new Google.DataTable.Net.Wrapper.Cell(item.ReadingValue)
});
dt.AddRow(r);
}
multiDt.Add(dt.GetJson());
}
}
catch (Exception ex)
{
var m = ex.Message;
}
var sb = new StringBuilder();
sb.Append("[");
foreach(var i in multiDt)
{
sb.Append("[");
sb.Append(i);
sb.Append("],");
}
sb.Append("]");
string xx = sb.ToString();
int yy = xx.LastIndexOf(',');
xx = xx.Remove(yy, 1);
return xx;
}
JSON call from AJAX
public JsonResult GetMultiChartData(string serial, string uid, string from, string to)
{
var dateFrom = Convert.ToDateTime(from).ToString("yyyy-MM-dd HH:mm:ss");
var dateTo = Convert.ToDateTime(to).AddMinutes(1).ToString("yyyy-MM-dd HH:mm:ss");
var g = new GetChartData(_context, _configuration);
var items = g.CreateJsonMultiChartDataTable(serial, uid, dateFrom, dateTo);
var deserialisedJsonData = JsonConvert.DeserializeObject(items);
return Json(JsonConvert.SerializeObject(deserialisedJsonData, Formatting.Indented));
}
I have created a following model
public class myModel
{
public int ID;
public string Name;
public int[] days;
}
Then I created an action in a controller
[HttpPost]
public ActionResult myCtrlAction(myModel thisModel)
{
if (ModelState.IsValid)
{
return Json(thisModel);
}
else
{
string errorMessage = "<div class=\"validation-summary-errors\">"
+ "The following errors occurred:<ul>";
foreach (var key in ModelState.Keys)
{
var error = ModelState[key].Errors.FirstOrDefault();
if (error != null)
{
errorMessage += "<li class=\"field-validation-error\">"
+ error.ErrorMessage + "</li>";
}
}
errorMessage += "</ul>";
return Json(new myModel { Name = errorMessage }); //just for now
}
}
In my javascript I send the data using jQuery.post() as
$("#myBtn").click(function () {
var mydata = {
ID: $("#inputID").val(),
Name: $("#inputName").val(),
Days: $("#selectDays").select2("val")
}
var url = 'myController/myCtrlAction'; //definitly it was writtern as #Url.Action
$.post(url, mydata, function(data) { alert(data); //which shows [object object]
}, 'json');
});
Now On request when I debug in Chrome I saw in headers as
Form Data
ID: 5
Name: SomeName
Days[]: 6
Days[]: 5
In Response I got json format of my model as
{ID: "0", Name: "null", Days: "null"} it means my model state is valid but why its not having the values?
Any body has any idea. what I did wrong or do I miss something?
I think your model's data is not set thus you get null values on Chrome.
If your javascript does not have a typo (and that you only made a typo when creating the question, then try this in your method myCtrlAction;
First try create getters and setters for your fields in myModel. Then;
replace;
errorMessage += "</ul>";
return Json(new myModel { Name = errorMessage }); //just for now
with this;
myModel myMODTest= new myModel();
myMODTest.setID(1111);
myMODTest.setName("testName");
myMODTest.setDays({1,2,3});
return Json(myMODTest); //just for now
See if you get on your browser the following;
{ID: "1111", Name: "testName", Days: "{1,2,3}"}
I do this following:
1: JavaScript: When clicking the button: Serialize the form-data and send it to the Controller:
function ajaxSubmitEditSupplierQuote() {
var formData = $("#SupplierQuoteEditForm").serializeArray();
$.ajax({
type: "POST",
url: '#Url.Action("Edit", "SupplierQuote")',
data: formData,
dataType: "json",
cache: false,
success: function (data1) {
// Here I create then a new Url-string.
// Simple access your Json Data, as you have named it in the return of the Controller-Action.
var strUrl = "/Equipment/" + data1.target.toString();
// ...
//
// ...
}
});
}
2: Controller-Action with custom Json return
[HttpPost]
public ActionResult Edit(SupplierQuoteDto supplierQuoteDto)
{
// ........... code
if (_userContext.EquipmentAction.ClickedAction == ActionType.Create)
return Json(new { target = "Create" });
else if (_userContext.EquipmentAction.ClickedAction == ActionType.Edit)
return Json(new { target = "Edit" });
else
return new EmptyResult();
}
3: Alternatively if you want to catch also the EmptyResult() then in the JavaScript, check simply in the
success: function (data1) {
if (data1.toString() == "") {
// .... alert
}
else {
/// .... go on with coding
}
}
check your javascript code where you do the post. You have a typo: '.' instead of ',':
$.post(url, mydata, function(data) { alert(data); }, 'json');
I have a WebMethod being called from ajax, trying to iterate through the returned data. The data being returned is "{ BusinessTypeID = 2 }". I'm trying to figure out how to just get the value 2?
//Function called from ajax
[System.Web.Services.WebMethod]
public static string[] GetTerminalBusinessTypes(string terminalID)
{
DataClassesDataContext db = new DataClassesDataContext();
List<string> results = new List<string>();
try
{
var terminalBusinessTypes = (from bt in db.BusinessTypes
join obt in db.OxygenateBlenderBusinessTypes on bt.BusinessTypeID equals obt.BusinessTypeID
where obt.OxygenateBlenderID == Convert.ToInt32(terminalID)
select new
{
bt.BusinessTypeID
}).ToList();
for (int i = 0; i < terminalBusinessTypes.Count(); i++)
{
results.Add(terminalBusinessTypes[i].ToString());
}
}
catch (Exception ex)
{
}
return results.ToArray();
}
The ajax function:
function PopulateTerminalBusinessTypes(terminalID) {
$.ajax({
type: "POST",
url: "OxygenateBlenderCertificationApplication.aspx/GetTerminalBusinessTypes",
data: "{'terminalID':" + terminalID + "}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
var targetValue = data.d;
var items = $('#cblTerminalBusinessType input:checkbox');
$.each(targetValue, function (key, targetValue) {
alert(data[index].BusinessTypeID);
});
}
})//end ajax
}
When your web service returns the json value, asp.net wraps in an object, with the key being d and the value being your json string. Review this link for more info.
You have to parse the value string into a json object. Using jQuery (v1.4.1 or higher):
jQuery.parseJSON(targetValue);
To be honest I cannot see where your "index" is defined.
Shouldn't the alert line read
$each(targetVale, function(key, item) {
// on second look, this wont work as you are converting toString()
alert(targetValue[key].BusinessTypeId)
// this should
alert(item)
});
You could also throw a debugger; line above the alert and see the values being traversed.
You may want to try returning a JSON string from C#:
public static **string** GetTerminalBusinessTypes(string terminalID)
...
var oSerializer = new System.Web.Script.Serialization.JavaScriptSerializer();
string sJSON = oSerializer.Serialize(results);
return sJSON;
Hi can anybody help me out from this.
I have an HTML page. This page contains Textboxes for FirstName,MiddleName, LastName, etc.
On button clcik of this HTML page i am calling a javascript function. Here i am getting all the HTML page contaols and its value using JQuery Serialization. Then passing this values to my WCF service hosted in server.
This service will parse this string into corresponding objects and save the values into the database.
So In HTMl page i written the Javascript function like below:
pmamml.ButtonClick = function() {
var formData = $("#form1").serializeArray();
var stringJson;
$.getJSON('ajax/test.json', function(formData) {
stringJson= JSON.stringify(formData)
});
//alert(stringJson);
$.ajax({
type: 'GET',
url: 'http://URL/Service.svc/Update?formData=' + JSON.stringify(formData),
error: pmamml.ajaxError,
success: function(msg) {
document.write(msg);
//alert(msg);
},
});},
And in WCF service i written:
[WebInvoke(Method = "GET", UriTemplate = "/Update?formData={formData}", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
public string Update(string formData)
{
// Here i am receiving formdata string as
// formData = "[{\"name\":\"FirstName\",\"value\":\"Pankaj\"},{\"name\":\"MiddleName\",\"value\":\" \"},{\"name\":\"LastName\",\"value\":\"KUMAR\"}]";
}
I wanna deserialize this string into List object or keyvaluepair or Dictionary any one of the above format.
So that i can save this value into database.
How can we do this. Thanks in advance.
The easiest way to do it would be to split it into an array using RegEx, matching \"([^\"]*).
update Given you are sending it to a web service, it should just be configured as Json to deserialize it automatically
The code below will give you your stringdata seperated into workeable pieces, as displayed below.
// new list
var l = new List<string>();
// original data
var s = "[{\"name\":\"FirstName\",\"value\":\"Raja\"},{\"name\":\"MiddleName\",\"value\":\"Raja \"},{\"name\":\"LastName\",\"value\":\"KUMAR\"}]";
// clean up and split in larger parts
var d = s.Substring(1, s.Length - 2).Replace("\\", "").Replace("\"", "").Replace("}", "").Split('{');
// Split in final entries and add to list
var sb = new char[2] { ',', ':' };
foreach (var r in d) { l.AddRange(r.Split(sb, StringSplitOptions.RemoveEmptyEntries));
// Contents of the List will be
name
FirstName
value
Raja
name
MiddleName
value
Raja
name
LastName
value
KUMAR
// The code is not very robust yet, e.g. you need to check your inputstring is not empty
yup i got the solution
This is my updated JQuery
pmamml.ButtonClick = function() {
$.fn.serializeObject = function() {
var o = {};
var a = this.serializeArray();
$.each(a, function() {
if (o[this.name] !== undefined) {
if (!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
} else {
o[this.name] = this.value || '';
}
});
return o;
};
var stringJson = JSON.stringify($('#form1').serializeObject());
var Userdata = "formData=" + stringJson;
$.ajax({
type: 'GET',
url: 'http://URL/Service.svc/Update?' + Userdata,
error: pmamml.ajaxError,
success: function(response, status, xhr) {
if (response = true) {
//alert(response);
alert("Data Updated Successfully");
}
}
});
}
In above method formData will pass the JSON string like below:
{ "FirstName":"Raja","MiddleName":"Raja","LastName":"Kumar"}.
And in my WCF Service, converted this JSON string to Object.
[WebInvoke(Method = "GET", UriTemplate = "/Update?formData={formData}", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
public bool Update(string formData)
{
var mlParser = new MLParser();
System.Web.Script.Serialization.JavaScriptSerializer s = new System.Web.Script.Serialization.JavaScriptSerializer();
var InfoList = s.Deserialize<Users>(formData);
return mlParser.Update(InfoList);
}
public class Users
{
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
}
This is working fine.
Thnak you all for your kind response.. :)