I have a view, where I'm calling an ActionResult method, but putting a breakpoint in the method tells me it's not being called.
<div>
<ul class="list-group">
#foreach (var item in Model)
{
<li class="list-group-item">
<h4>Slide ID: #item.SlideId</h4>
<p><i>Received: #item.TimeStamp</i></p>
<div class="row">
<div class="col-md-4">
<h4>#Html.ActionLink("View details", "Well", new {slideid = item.SlideId})</h4>
<img src="#Url.Action("Index", "Images", new {id = item.SlideId})"/> //This is where I want to call the method
</div>
</div>
</li>
}
</ul>
And here's the method:
public class ImagesController : Controller
{
// GET: Images
public ActionResult Index(string id)
{
byte[] imageData = new byte[0];
string cs = "Data Source=" + "some path";
using (SQLiteConnection con = new SQLiteConnection(cs))
{
string stm = "SELECT LastImage FROM Well WHERE SlideId = " + "'" + id + "'";
con.Open();
using (SQLiteCommand cmd = new SQLiteCommand(stm, con))
{
using (SQLiteDataReader rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
imageData = Serialize(rdr["LastImage"]);
}
rdr.Close();
}
}
con.Close();
}
return File(imageData, "image/png");
}
public static byte[] Serialize(object obj)
{
var binaryFormatter = new BinaryFormatter();
var ms = new MemoryStream();
binaryFormatter.Serialize(ms, obj);
return ms.ToArray();
}
}
What I'm trying to achieve with this code is to load in an image from the database into the view. Any hints as to what I'm doing wrong?
Now with RouteConfig:
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 }
);
}
}
When you write <img src="#Url.Action("Index", "Images", new {id = item.SlideId})"/> you don't call the action but the route url. The result is a string, for example localhost:8080/images/index/abcd123456 so, if you want to call the action, you need to use #Html.Action("Index", "Images", new {id = item.SlideId}). Note #Html.Action instead of #Url.Action
I think instead of opening and closing a db connection for each image, a better approach would be to gather all the information to render that page and send it in the model of the view you posted. Say it's called Index action of HomeController. It would look like something like this:
public class HomeController : Controller
{
public ActionResult Index(string id)
{
var listOfItems = new List<SomeClass>();
string cs = "Data Source=" + "some path";
using (SQLiteConnection con = new SQLiteConnection(cs))
{
string stm = "SELECT SlideId, TimeStamp, LastImage FROM Well";
con.Open();
using (SQLiteCommand cmd = new SQLiteCommand(stm, con))
{
using (SQLiteDataReader rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
var someItem = new SomeClass()
{
SlideId = rdr["SlideId"],
ImageData = Serialize(rdr["LastImage"]),
TimeStamp = rdr["TimeStamp"]
};
listOfItems.Add(someItem);
}
rdr.Close();
}
}
con.Close();
}
return View(listOfItems);
}
}
Of course if there are too many items you should always consider paging and limit the number of items in the list to cut down the response times.
Related
I have a button that's supposed to run a SQL query.
<button class="btn btn-info mt-3"asp-controller="MessageCenter" asp-action="Markmessage">Mark</button>
there is no forms or any sort of thing that I can use a post method for. here is the function that I'm trying to call(this is in my controller by the way).
public void Markmessage()
{
Messagelookupinfo messagelookup = new Messagelookupinfo();
SqlConnection sql = new SqlConnection();
SqlConnection sqlcon = new SqlConnection("data source");
sqlcon.Open();
SqlCommand sqlcom = new SqlCommand("update messages set messagestatus='MARKED' where messageid=" + messagelookup.Messageid, sqlcon);
sqlcom.ExecuteNonQuery();
sqlcon.Close();
RedirectToAction("Messagelookup", "Messageid=" + messagelookup.Messageid);
}
There is no feedback/confirmation for the user just straight up run the query and reload the page.
How do I achieve this?
I made a simple example, you can refer to it.
View (Messagelookup.cshtml):
#{
ViewData["Title"] = "Messagelookup";
}
<h1>Messagelookup</h1>
<div>
<label>MessageId:</label>
<h2>#ViewBag.MessageId</h2>
</div>
<a class="btn btn-info mt-3" asp-controller="MessageCenter" asp-action="Markmessage" asp-route-messageid="2">Mark</a>
Controller:
public class MessageCenterController : Controller
{
public IActionResult Messagelookup(int? Messageid)
{
ViewBag.Messageid = Messageid;
return View();
}
public IActionResult Markmessage(int? messageid)
{
return RedirectToAction("Messagelookup", new { Messageid = messageid });
}
}
Result:
I am trying to connect to SQL Server from the Web API and return a result set as JSON. But my code shown here is not working as expected. I am trying to return the entire query response as a JSON:
[HttpGet]
public HttpResponseMessage Getdetails(string ROOM)
{
string commandText = "SELECT * from [TDB].[dbo].[results_vw] where ROOM = #ROOM_Data";
string connStr = ConfigurationManager.ConnectionStrings["TDBConnection"].ConnectionString;
var jsonResult = new StringBuilder();
using (SqlConnection connection = new SqlConnection(connStr))
{
SqlCommand command = new SqlCommand(commandText, connection);
command.Parameters.Add("#ROOM_Data", SqlDbType.VarChar);
command.Parameters["#ROOM_Data"].Value = ROOM;
connection.Open();
var reader = command.ExecuteReader();
if (!reader.HasRows)
{
jsonResult.Append("[]");
}
else
{
while (reader.Read())
{
jsonResult.Append(reader.GetValue(0).ToString());
}
}
var response = new HttpResponseMessage(System.Net.HttpStatusCode.OK);
response.Content = new StringContent(jsonResult.ToString());
connection.Close();
return response;
}
}
This code returns this result:
333838362692368203368203368203362692368203359544362692368203362692368203362692368203368203
Where I am expecting the JSON as
{"data":
[
{"R_ID":"368203","ROOM":"K2"},
{"R_ID":"368203","ROOM":"K2"}
]}
Now I created a model class called DatabaseResult to store the response but I am not sure how I can store the result in to the model class in the controller
public class DatabaseResult
{
public int r_id { get; set; }
public string room { get; set; }
}
The current result is because you are only return the the value from the first column of each row and adding it to the string builder.
Create a new instance of the model and populate it using the values from the reader for each row.
[HttpGet]
public IHttpActionResult Getdetails(string ROOM) {
string commandText = "SELECT * from [TDB].[dbo].[results_vw] where ROOM = #ROOM_Data";
string connStr = ConfigurationManager.ConnectionStrings["TDBConnection"].ConnectionString;
var jsonResult = new StringBuilder();
using (SqlConnection connection = new SqlConnection(connStr)) {
using (SqlCommand command = new SqlCommand(commandText, connection)) {
command.Parameters.Add("#ROOM_Data", SqlDbType.VarChar);
command.Parameters["#ROOM_Data"].Value = ROOM;
connection.Open();
List<DatabaseResult> records = new List<DatabaseResult>();
using (var reader = command.ExecuteReader()) {
while (reader.Read()) {
var row = new DatabaseResult {
r_id = (int)reader["r_id"],
room = (string)reader["room"],
//...other properties.
};
records.Add(row);
}
return Ok(records);
}
}
}
}
The above uses the column names as the indexer to get the values from the reader.
I created web API using dotNet. It work but i got a little problem.
This is my controller
WaybillDataAccessLayer objway = new WaybillDataAccessLayer();
public IEnumerable<Waybill> Get(string id_wb)
{
List<Waybill> lstWaybill = new List<Waybill>();
lstWaybill = objway.GetWaybill(id_wb).ToList();
return lstWaybill;
}
and my Models(WaybillDataAccessLayer)
public IEnumerable<Waybill> GetWaybill(String id_wb)
{
List<Waybill> lswaybill = new List<Waybill>();
using (SqlConnection con = new SqlConnection(connectionString))
{
SqlCommand cmd = new SqlCommand("spGetWaybill", con); //Stored procedure on database
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#waybill", id_wb);
con.Open();
SqlDataReader rdr = cmd.ExecuteReader();
while (rdr.Read()) //foreach
{
Waybill wb = new Waybill();
wb.waybill = rdr["waybill"].ToString();
wb.deskripsi = rdr["deskripsi"].ToString();
wb.tanggal = rdr["tanggal"].ToString();
wb.pengirim = rdr["pengirim"].ToString();
wb.lokasi = rdr["lokasi"].ToString();
wb.penerima = rdr["penerima"].ToString();
lswaybill.Add(wb);
}
con.Close();
}
return lswaybill;
}
when i run this API,the output will be like this
[
{
"waybill": "00000093",
"deskripsi": "SPARE PARTS",
"tanggal": "19990727",
"pengirim": "JIEP",
"lokasi": "HO",
"penerima": "JKHO"
}
]
My Question is
how to remove that [] ?
how to add another information like
{
"status" : "sucess",
"data" { }
}
Thankyou for your help.
You're returning a list of WayBill objects. If you don't want the resulting JSON to be an array, then you need to just return a single WayBill, not a List. And if you want to wrap that in more data, then create a type to represent that information, populate an instance of it, and return it.
Since you're retrieving these objects by ID, I'm assuming there should be only one WayBill for any given ID. Thus you can simplify your data access layer.
public Waybill GetWaybill(String id_wb)
{
using (SqlConnection con = new SqlConnection(connectionString))
using (SqlCommand cmd = new SqlCommand("spGetWaybill", con))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#waybill", id_wb);
con.Open();
SqlDataReader rdr = cmd.ExecuteReader();
rdr.Read();
Waybill wb = new Waybill();
wb.waybill = rdr["waybill"].ToString();
wb.deskripsi = rdr["deskripsi"].ToString();
wb.tanggal = rdr["tanggal"].ToString();
wb.pengirim = rdr["pengirim"].ToString();
wb.lokasi = rdr["lokasi"].ToString();
wb.penerima = rdr["penerima"].ToString();
return wb;
}
}
And add the type to wrap your response:
class GetWayBillResponse()
{
public string Status { get; set;}
public WayBill WayBill { get; set; }
}
Note that adding a status here isn't really all that helpful if you're seeing the object, you can assume it was successful. Also, the API would have responded with an HTTP 200 OK status code. So it's really superfluous.
Now your controller becomes:
WaybillDataAccessLayer objway = new WaybillDataAccessLayer();
public GetWayBillResponse Get(string id_wb)
{
GetWayBillResponse response = new GetWayBillResponse();
response.Status = "Success";
response.WayBill = objway.GetWaybill(id_wb);
return response;
}
Note that you can simplify your data access even further. You're manually assigning the result columns to the WayBill object. That's repetitive and boring. If you use an Object Relational Mapper such as Dapper, you can remove a lot of that boiler plate code.
Here's what it'd look like using Dapper:
public Waybill GetWaybill(String id_wb)
{
using (SqlConnection con = new SqlConnection(connectionString))
{
return con.QuerySingle<WayBill>("spGetWaybill", new { waybill = id_web }, commandType: CommandType.StoredProcedure);
}
}
I want to fill data in excel and download that excel..
Following is the code..
public void DownloadExcel(int acid, int GroupId)
{
// Working Code
#region DownloadExcel
// string sConnectionString = ConfigurationManager.ConnectionStrings["TrainingMVCContext"].ConnectionString;
string sConnectionString = string.Empty;
LoginUserDetails objLoginUserDetails = (LoginUserDetails)InsiderTrading.Common.Common.GetSessionValue((string)ConstEnum.SessionValue.UserDetails);
sConnectionString = objLoginUserDetails.CompanyDBConnectionString;
SqlConnection con = new SqlConnection(sConnectionString);
SqlCommand cmd = new SqlCommand();
con.Open();
DataTable dt = new DataTable();
cmd = new SqlCommand("st_tra_NSEDownloadGroupWiseExcel", con);
cmd.Parameters.AddWithValue("#GroupId", GroupId);
cmd.CommandType = CommandType.StoredProcedure;
SqlDataAdapter adp = new SqlDataAdapter(cmd);
// ds = new DataSet();
adp.Fill(dt);
Microsoft.Office.Interop.Excel.Range oRng;
Microsoft.Office.Interop.Excel.Workbook mWorkBook;
Microsoft.Office.Interop.Excel.Sheets mWorkSheets;
Microsoft.Office.Interop.Excel.Worksheet mWSheet1;
Microsoft.Office.Interop.Excel.Application oXL;
object misValue = System.Reflection.Missing.Value;
string directory = ConfigurationManager.AppSettings["Document"];
string path = "Z:\\For Excel Demo\\Application\\InsiderTrading\\Document" + "\\" + "Stock Exchange Submission.xlsx";
oXL = new Microsoft.Office.Interop.Excel.Application();
oXL.Visible = true;
oXL.DisplayAlerts = false;
mWorkBook = oXL.Workbooks.Open(path, 0, false, 5, "", "", false, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "", true, false, 0, true, false, false);
mWorkSheets = mWorkBook.Worksheets;
mWSheet1 = (Microsoft.Office.Interop.Excel.Worksheet)mWorkSheets.get_Item("Sheet1");
Microsoft.Office.Interop.Excel.Range range = mWSheet1.UsedRange;
for (var row = 4; row <= dt.Rows.Count; row++)
{
for (var col = 0; col < dt.Columns.Count; col++)
{
mWSheet1.Cells[row + 1, col + 1].Value = dt.Rows[row - 1][col];
}
}
string Filename = "Testing.xlsx";
string pathTosave = (Path.Combine(directory, Filename));
mWorkBook.SaveAs(pathTosave);
using (var memoryStream = new MemoryStream())
{
HttpContext.Response.Clear();
HttpContext.Response.Charset = "";
HttpContext.Response.ContentType = "application/vnd.ms-excel";
HttpContext.Response.AddHeader("Content-Disposition", "inline;filename=" + pathTosave);
System.Text.StringBuilder strHTMLContent = new System.Text.StringBuilder();
//strHTMLContent.Append(LetterHTMLContent);
HttpContext.Response.Write(strHTMLContent);
HttpContext.Response.End();
HttpContext.Response.Flush();
}
mWorkBook.Close();
mWSheet1 = null;
mWorkBook = null;
oXL.Quit();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
#endregion DownloadExcel
}
but it gives the error For line
mWorkBook = oXL.Workbooks.Open(path, 0, false, 5, "", "", false, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "", true, false, 0, true, false, false);
error msg as follows--
An exception of type 'System.Runtime.InteropServices.COMException' occurred in InsiderTrading.dll but was not handled in user code
How can i do that..Plz help
Why dont you use a library, "LinqToExcell" to do all the plumbing?
https://www.codeproject.com/Articles/659643/Csharp-Query-Excel-and-CSV-Files-Using-LinqToExcel
Just upload the file using the following code in your controller. Note, you will need to save the file in your application because browsers do not allow you to access the location of your uploaded file (security purposes):
#region ImportExcell
public ActionResult ImportExcel()
{
return View();
}
[HttpPost]
public ActionResult ImportExcel(HttpPostedFileBase upload, FormCollection fc)
{
var v = System.Web.HttpContext.Current.Request.Files["upload"];
string contentType = upload.ContentType;
FileInfo fInfo = new FileInfo(upload.FileName);
//I am only allowing this kind of excel file. I got this from HttpPostedFileBase during debuging and checking content
if (!contentType.Contains(#"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"))
{
ModelState.AddModelError("", string.Format("This is not a valid file. This is '{0}'", contentType));
return View();
}
var fileName = upload.FileName;
//This is my temporary saving spot in my application
var filePathSaveTo = Server.MapPath(#"/Upload/ExcelFile");
string savedFileName = Path.Combine(filePathSaveTo, fileName);
//Now we need to save the file in a temp spot so we can access it later
upload.SaveAs(savedFileName);
try
{
string returnMsg = _fileDocDAL.LoadFromExcel(savedFileName);
ModelState.AddModelError("", string.Format("Done! " + returnMsg));
}
catch (Exception e)
{
string error = AliKuli.Utilities.ExceptionNS.ErrorMsgClass.GetInnerException(e);
ModelState.AddModelError("", string.Format(error));
}
return View();
}
#endregion
And your view....
#model ModelsClassLibrary.Models.Documents.FilesNS.FilesDocImportVM
#using (Html.BeginForm("ImportExcel", "FileDocs", null, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="panel panel-info">
<div class="panel-heading">
Required Fields
</div>
<div class="panel-body">
<div class="form-group">
#Html.Label("Excel File", new { #class = "control-label col-md-2" })
<div class="col-md-10">
<input type="file" multiple="multiple" name="upload" id="front" />
</div>
</div>
<div class="form-group">
<div class="col-md-10">
<input type="submit" value="Upload" class="btn btn-success" /> |
#Html.ActionLink("Back to List", "Index")
</div>
</div>
</div>
</div>
</div>
}
My model is as below, but you need to make your model just like the data in the excel sheet. This is all explained in the documentation for LinqToExcell
namespace ModelsClassLibrary.Models.Documents.FilesNS
{
//[NotMapped]
public class FilesDocImportVM
{
public FilesDocImportVM()
{
FileId = -1;
}
#region Files
/// <summary>
/// The file number's ID
/// </summary>
public int FileId { get; set; }
/// <summary>
/// This is the file number that the user sees.
/// </summary>
public string FileNo { get; set; }
/// <summary>
/// This is the name of the file
/// </summary>
public string Description { get; set; }
/// <summary>
/// This is the parent's ID. 0 means no ID
/// </summary>
public int ParentId { get; set; }
#endregion
public int GetFileNumberFromOldFileNumber()
{
if (FileNo.IsNullOrEmpty() || FileId == -1 || Description.IsNullOrEmpty())
throw new Exception(string.Format("Proper Data not received. Record is {0}.FilesDocImportVM.GetFileNumberFromOldFileNumber ", this.ToString()));
return new FileDoc().GetFileNumberFromOldFileNumber(FileNo);
}
public void SelfErrorCheck()
{
if(FileId == -1 || FileNo.IsNullOrEmpty() || Description.IsNullOrEmpty())
throw new Exception(string.Format("Proper Data not received. Record is {0}. FilesDocImportVM.SelfErrorCheck", this.ToString()));
}
#region Category
/// <summary>
/// This is the categories ID
/// </summary>
public int CategoryId { get; set; }
/// <summary>
/// This is the name of the category
/// </summary>
public string CategoryName { get; set; }
#endregion
public override string ToString()
{
return string.Format("FileId: {0}, FileNo: {1}, Description: {2}, ParentId: {3}, CategoryId: {4}, CategoryName: {5}",
FileId,
FileNo,
Description,
ParentId,
CategoryId,
CategoryName);
}
}
}
The uploading code is pretty simple... this is the code that is used
public string LoadFromExcel(string excelFileName)
{
int noOfFiles = 0;
//*** NOTE - The line below is the code to import from Excel. I have wrapped it a bit to make it simple... the wrapper is below. The code after this line is just for fixing and checking the data.
var excelFile = AliKuli.Utilities.ExcellUtility.ImportFromExcelWithHeader(excelFileName, "AliKuliFiles");
if (excelFile.IsNullOrEmpty())
throw new Exception(string.Format("Utility Class failed to load. FileDocsDAL.LoadFromExcel"));
string totalFilesMsg = string.Format("Total Orignal Files: {0}", excelFile.Count());
var dataArray = excelFile.OrderBy(x => x.FileId).ToList();
if (dataArray.IsNullOrEmpty())
throw new Exception(string.Format("Data array failed to load. FileDocsDAL.LoadFromExcel"));
CheckTheData(dataArray);
//first make the categories
User theUser = Get_User();
string temp = "";
if (noOfFiles == 324)
temp = "Found";
CreateCategories(dataArray, theUser);
CreateAndSaveFile(ref noOfFiles, dataArray, theUser);
//now add the parents
SaveTheParents();
totalFilesMsg += " Counted: " + noOfFiles;
//CreateFileWithCategory(dataArray, admin);
return totalFilesMsg;
}
This is the wrapper code I wrote to wrap the LinqToExcel
public static class ExcellUtility
{
/// <summary>
/// This will read in the excel file such that it will stringify the cols of each row.
/// Example. If there are 3 cols, the the first 3 entries will be for col 0, then 1, then Col 2,
/// then... the 4th entry will again be col1
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
public static List<FilesDocImportVM> ImportFromExcelWithHeader(string excelFileName, string sheetName)
{
ExcelUtilityClass euc;
ExcelQueryFactory excel;
MakeExcelUtilityClass(excelFileName, out euc, out excel);
//This creates a IQueriable<FilesDocImportVM>
var data = from c in excel.Worksheet<FilesDocImportVM>(sheetName) select c;
var colNames = excel.GetColumnNames(sheetName).ToArray();
var datalist = data.ToList();
return datalist;
}
private static void MakeExcelUtilityClass(string excelFileName, out ExcelUtilityClass euc, out ExcelQueryFactory excel)
{
if (excelFileName.IsNullOrEmpty())
throw new Exception("No Excel File Name Passed");
euc = new ExcelUtilityClass();
excel = new ExcelQueryFactory(excelFileName);
}
}
}
Looks more complicated than it is... the uploading part was easy - just about one line of code after writing a the wrapper.
Good luck.
I want to access data and show in label ajax page methods but data is not displaying.
PageMethods.GetDataFromDB(OnSucceeded, OnFailed);
//}
function OnSucceeded(result, userContext, methodName) {
var jsonData = eval(result.d);
$get('Label1').innerHTML = jsonData.FirstName;
}
[WebMethod]
public static string GetDataFromDB()
{
System.Collections.Generic.Dictionary<string, string> DictionaryGetPerson = new Dictionary<string, string>();
using (OracleConnection con = new OracleConnection("server=xe; uid=system; pwd=;"))
{
string Command = "Select * from tblSavePerson"; //selecting Top 1 Row in Oracle
OracleCommand cmd = new OracleCommand(Command, con);
con.Open();
OracleDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
DictionaryGetPerson.Add("FirstName",dr["FirstName"].ToString());
}
}
JavaScriptSerializer js = new JavaScriptSerializer();
return js.Serialize(DictionaryGetPerson).ToString();
}
table has only one row.
Since you have given the tags as jQuery and jQuery Ajax I am deviating a little from the solution.
Do these things
1.Wrap your WebMethod in a try-catch block. try-catch are there for a reason.
[WebMethod]
public static string GetDataFromDB()
{
try
{
System.Collections.Generic.Dictionary<string, string> DictionaryGetPerson = new Dictionary<string, string>();
using (OracleConnection con = new OracleConnection("server=xe; uid=system; pwd=;"))
{
string Command = "Select * from tblSavePerson"; //selecting Top 1 Row in Oracle
OracleCommand cmd = new OracleCommand(Command, con);
con.Open();
OracleDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
DictionaryGetPerson.Add("FirstName", dr["FirstName"].ToString());
}
}
JavaScriptSerializer js = new JavaScriptSerializer();
return js.Serialize(DictionaryGetPerson).ToString();
}
catch (Exception exception)
{
//Elmah.ErrorSignal.FromCurrentContext().Raise(exception);
throw new Exception(exception.Message);
}
}
Please note that this Dictionary will fail with Duplicate Key error if you have more than one row. If there are no errors lets move to step 2.
2.Do not use PageMethods.GetDataFromDB. It very ancient. Using jQuery one can consume ASP.NET Ajax Page Methods directly. Call Page method like this.
function LoadNames() {
$.ajax({
contentType: "application/json;",
data: "{}",
type: "POST",
url: 'Test1.aspx/GetDataFromDB',
success: function (msg) {
OnSucceeded(msg);
},
error: function (xhr, status, error) {
//alert("error");
//OnFailed(a, b, c);
}
});
}
function OnSucceeded(dict) {
var jsonData = dict.hasOwnProperty("d") ? dict.d : dict;
var json = $.parseJSON(jsonData);
alert(json.FirstName);
}
Also, don't eval(result.d) when we have $.parseJSON in jQuery.
Hope this helps.