Jquery JSON and C# : Reading JSON reply from C# HttpHandler - c#

I am having some trouble figuring out to read the JSON returned from my HttpHandler.
The data being returned is this (according to Firebug):
[{"ID":2,"Name":"Fred Johnson","PhoneNumber":"444-444-4444","Notes":"Note Data","Representative":1,"StreetNumber":76547,"StreetName":"Juniper St.","City":"Burbank"}]
HttpHandler Code
public class RequestHandler : IHttpHandler
{
public RequestHandler()
{ }
public bool IsReusable
{
get { return false; }
}
public void ProcessRequest(HttpContext context)
{
var thisID = Convert.ToInt32(context.Request["Id"]);
List<WW.Data.Customer> thisCustomer = WW.Business.Customer.getCustomerByID(thisID);
JavaScriptSerializer javaScriptSerializer = new JavaScriptSerializer();
string lookedUpCustomer = javaScriptSerializer.Serialize(thisCustomer);
context.Response.ContentType = "text/html";
context.Response.Write(lookedUpCustomer);
}
}
JQUERY CODE
<script type="text/javascript">
function sendData() {
alert("start");
var thisID = $("#Text1").val()
var arr = { ID: thisID};
$.ajax(
{
url: "jsonpost.ww",
type: "POST",
data: arr,
dataType: 'json',
async: true,
success: function (data) {
$("#Text2").val = data.Name;
$("#Text3").val = data.StreetNumber;
$("#Text4").val = data.StreetName;
$("#Text5").val = data.City;
$("#Text6").val = data.PhoneNumber;
}
}
);
alert("end");
}
</script>
So basically, I am having trouble reading that JSON string data when it is returned on success. Anyone see anything that would cause this?
Any help is appreciated.
Thanks,
CSS

The json response which you are getting should be in ():
$("#Text2").val(data.Name);
$("#Text3").val(data.StreetNumber);
$("#Text4").val(data.StreetName);
$("#Text5").val(data.City);
$("#Text6").val(data.PhoneNumber);
This is the correct way of assigning values to inputs.

Your JSON is formatted such that the object you need is the first element of an array. So in your success callback, instead of doing data.name, you need to do data[0].name.

Related

Send array of files from Jquery ajax to controller action

I am able to pass single file as System.Web.HttpPostedFileBase but when i pass same as array of files i am getting null in controller's action.
I've tried sending array of files.
HTML:
<input type="file" id="Attachment1">
<input type="file" id="Attachment2">
<input type="file" id="Attachment3">
<input type="file" id="Attachment4">
<input type="file" id="Attachment5">
Javascript:
var FileData = [];
$('input').each(function () {
var type = $(this).attr("type");
if (type == "file") {
FileData.push($(this).get(0).files[0]);
}
});
var Data = new FormData();
Data.append("Attachments", FileData);
if (url != '') {
$.ajax({
url: url,
data: Data,
type: "POST",
contentType: false,
processData: false,
success: function (data) {
alert("Saved successfully");
}
});
}
Controller:
public ActionResult InsertDetails(System.Web.HttpPostedFileBase[] Attachments)
{
return Json(new { Success = false });
}
Need to get array of files. Thanks in advance.
Thanks for the effort guys. I found the solution. I just need to keep append files for same key "Attachments". Now i am able to get as array of HttpPostedFileBase.
var Data = new FormData();
$('input').each(function () {
var type = $(this).attr("type");
if (type == "file") {
var FileData = $(this).get(0).files[0]);
Data.append("Attachments", FileData);
}
});
Try It:
var Files = new FormData();
$('input').each(function () {
var type = $(this).attr("type");
if (type == "file") {
Files .append("Attachment"+$(this).attr("id"), $(this).get(0).files[0]);
}
});
if (url != '') {
$.ajax({
url: url,
data: Files ,
type: "POST",
contentType: false,
processData: false,
success: function (data) {
alert("Saved successfully");
}
});
}
This is how I used to post array data from javascript to mvc controller, this is going to be a little bit lengthy but I've explained each line with comment, I hope this may help you
javascript:
var formData = new FormData(); //declare formData
var arrayData = []; //declare array and push/append your data to it.
var name="abc";
arrayData.push(name);
//setting ArrayData to Json Object
var AllData = {
getUserData: arrayData
};
//appending Json Object to formdata with the key "mydata"
formData.append("mydata", JSON.stringify(AllData));
//sending formdata through ajax request
$.ajax({
type: "POST",
url: yourURLHere,
processData: false,
contentType: false,
data: formData,
cache: false,
success: function (data) {
//your program logic here
}
});
Controller:
public async Task<HttpResponseMessage> SaveResponse()
{
//receiving json data from the key "mydata" we set earlier
var getData = HttpContext.Current.Request.Params["mydata"];
//deserialize json object (you will need Newtonsoft.Json library)
var model = JsonConvert.DeserializeObject<MyModel>(getData);
//you will get all of your data in model variable
//do what you want to do with that data
}
and here is the model class
public class MyModel
{
//**dataList** will receive array data sent from javascript
public List<MyModel> dataList = new List<MyModel>();
//Remember, whatever your push to array in javascript, should be declared here.
public string name {get;set;}
}

Fancytree not loading with ajax request

I'm having a problem with fancytree.
I have an aspx page, with a webmethod on the codebehind.
I was trying to initialize the tree with an ajax call, but for some reason it looks the ajax call isn't getting there.
This is my javascript code to initialize the tree:
<script type="text/javascript">
$(function () {
var DT = $.ui.fancytree;
var tree = "";
$.ui.fancytree.debug("Using fancytree " + $.ui.fancytree.version);
/* Load tree from Ajax JSON
*/
$("#tree2").fancytree({
source: {
url: "tree.aspx/getTreeData"
}
});
});
</script>
and this is my codebehind webmethod:
namespace TreeGen
{
public partial class tree : System.Web.UI.Page
{
[WebMethod]
[ScriptMethod(UseHttpGet = true, ResponseFormat = ResponseFormat.Json, XmlSerializeString = false)]
public static List<Curso> getTreeData()
{
JavaScriptSerializer TheSerializer = new JavaScriptSerializer();
CourseSerializer course = new CourseSerializer();
course.children = new List<Curso>()
{
new Curso(){
key = "1",
title = "aaaa",
}
};
List<CourseSerializer> courses = new List<CourseSerializer>() { course };
string TheJson = TheSerializer.Serialize(course.children);
Console.WriteLine(TheJson);
return course.children;
}
}
}
What am i doing wrong?
I tried to make a ajax request to the webmethod and i am able to retrieve the json string.
But when i use the fancytree i can't populate the tree!
Thanks in advance!
Regards!
For anyone interested...
The ajax requests made by fancytree are all "GET" requests by default.
I added the ajax options as shown below, and the issue is now solved.
$('#tree2').fancytree({
ajax: { type: "POST", contentType: "application/json" },
source: {
url: "/tree.aspx/getTreeData"
}
});
Regards!

asmx round trip json

I am calling an asmx webservice which returns json (msg.d) that is consumed properly by knockout.js. When I attempt to return the identical json to asmx, I get error messages. Is there something obvious I'm missing? ... msg.d is a well formed object array.
calling storeGroupCategories(msg.d); returns webservice error ...
{"Message":"Invalid JSON primitive: Baby+Books."
calling storeGroupCategories(msg); returns webservice error ...
{"Message":"Invalid JSON primitive: d."
WebService
public class kbo_inexcludecategories : WebService
{
[WebMethod]
public List<Group> GetIncludeExcludeJson()
{
var Groups = new List<Group>();
ShopAssistGroupHandler.getInExCategories(Groups);
return Groups;
}
[WebMethod]
public GroupGuid StoreGroupCategories(List<InExCategory> inExCategories)
{
var inExString = JsonConvert.SerializeObject(inExCategories);
var returnGuid = DataHandler.SaveGroupJsonString(inExString);
return new GroupGuid(returnGuid);
}
}
Associated json ...
var _url = "kbo-inexcludecategories.asmx/";
var _method = "GetIncludeExcludeJson";
var _jsonData = "{}";
function storeGroupCategories(groupCategories) {
if(groupCategories != ""){
showProgressBar("Storing Group Categories");
getJsonData(_url, "StoreGroupCategories", groupCategories);
}
}
function getGroupMatrix() {
showProgressBar("Loading Group Categories");
getJsonData(_url, _method, _jsonData);
}
function getJsonData(url, method, jsonData) {
var myUrl = url + method;
$.ajax({
type: "POST",
url: myUrl,
data: jsonData,
contentType: "application/json; charset=utf-8",
dataType: "json",
async: false, //blocks window close
success: onSuccess,
error: onError
});
}
function onSuccess(msg) {
// Hide the fake progress indicator graphic.
hideProgressBar("");
if(msg.d.hasOwnProperty("Guid")) {
saveGroupGuid(msg.d);
}
else {
storeGroupCategories(msg.d);
//showGroupAccordion(msg.d);
//OpenAdvancedDialog();
}
}
json sample ...
"{\"groups\":[{\"__type\":\"group\",\"id\":1488,\"name\":\"Baby Books\",\"categories\":
[{\"__type\":\"groupcategory\",\"id\":152,\"name\":\"Activity Books\",\"value\":\"Included\"},
{\"__type\":\"groupcategory\",\"id\":167,\"name\":\"Bedtime and Dreams\",\"value\":\"Excluded\"}
To begin with I think you need to pass your json in like this:
storeGroupCategories(msg.d)
But within this function you also need to create valid json parameters to the post, which would look like this:
getJsonData(_url, "StoreGroupCategories", "{ inExCategories: " + groupCategories + " }");
I would also change your signature to the following, so groups matches the argument you are passing across:
public GroupGuid StoreGroupCategories(List<InExCategory> groups)
If you put a break point in the web page method, you will see exactly what is coming across, and check that it is what you are expecting.

Complex type is getting null in a ApiController parameter

I don´t know why my parameter "ParametroFiltro Filtro" is getting null, the other parameters "page" and "pageSize" is getting OK.
public class ParametroFiltro
{
public string Codigo { get; set; }
public string Descricao { get; set; }
}
My ApiController Get method:
public PagedDataModel<ParametroDTO> Get(ParametroFiltro Filtro, int page, int pageSize)
My ajax call:
var fullUrl = "/api/" + self.Api;
$.ajax({
url: fullUrl,
type: 'GET',
dataType: 'json',
data: { Filtro: { Codigo: '_1', Descricao: 'TESTE' }, page: 1, pageSize: 10 },
success: function (result) {
alert(result.Data.length);
self.Parametros(result.Data);
}
});
You are trying to send a complex object with GET method. The reason this is failing is that GET method can't have a body and all the values are being encoded into the URL. You can make this work by using [FromUri], but first you need to change your client side code:
$.ajax({
url: fullUrl,
type: 'GET',
dataType: 'json',
data: { Codigo: '_1', Descricao: 'TESTE', page: 1, pageSize: 10 },
success: function (result) {
alert(result.Data.length);
self.Parametros(result.Data);
}
});
This way [FromUri] will be able to pick up your complex object properties directly from the URL if you change your action method like this:
public PagedDataModel<ParametroDTO> Get([FromUri]ParametroFiltro Filtro, int page, int pageSize)
Your previous approach would rather work with POST method which can have a body (but you would still need to use JSON.stringify() to format body as JSON).
Provide the contentType property when you make the ajax call. Use JSON.stringify method to build the JSON data to post. change the type to POST and MVC Model binding will bind the posted data to your class object.
var filter = { "Filtro": { "Codigo": "_1", "Descricao": "TESTE" },
"page": "1", "pageSize": "10" };
$.ajax({
url: fullUrl,
type: 'POST',
dataType: 'json',
contentType: 'application/json',
data: JSON.stringify(filter),
success: function (result) {
alert(result.Data.length);
self.Parametros(result.Data);
}
});
It's also possible to access POST variables via a Newtonsoft.Json.Linq JObject.
For example, this POST:
$.ajax({
type: 'POST',
url: 'URL',
data: { 'Note': note, 'Story': story },
dataType: 'text',
success: function (data) { }
});
Can be accessed in an APIController like so:
public void Update([FromBody]JObject data)
{
var Note = (String)data["Note"];
var Story = (String)data["Story"];
}
If you append json data to query string, and parse it later in web api side. you can parse complex object too. It's useful rather than post json object, espeicaly in some special httpget requirement case.
//javascript file
var data = { UserID: "10", UserName: "Long", AppInstanceID: "100", ProcessGUID: "BF1CC2EB-D9BD-45FD-BF87-939DD8FF9071" };
var request = JSON.stringify(data);
request = encodeURIComponent(request);
doAjaxGet("/ProductWebApi/api/Workflow/StartProcess?data=", request, function (result) {
window.console.log(result);
});
//webapi file:
[HttpGet]
public ResponseResult StartProcess()
{
dynamic queryJson = ParseHttpGetJson(Request.RequestUri.Query);
int appInstanceID = int.Parse(queryJson.AppInstanceID.Value);
Guid processGUID = Guid.Parse(queryJson.ProcessGUID.Value);
int userID = int.Parse(queryJson.UserID.Value);
string userName = queryJson.UserName.Value;
}
//utility function:
public static dynamic ParseHttpGetJson(string query)
{
if (!string.IsNullOrEmpty(query))
{
try
{
var json = query.Substring(7, query.Length - 7); //seperate ?data= characters
json = System.Web.HttpUtility.UrlDecode(json);
dynamic queryJson = JsonConvert.DeserializeObject<dynamic>(json);
return queryJson;
}
catch (System.Exception e)
{
throw new ApplicationException("can't deserialize object as wrong string content!", e);
}
}
else
{
return null;
}
}
In .NET Core, the HttpClient sets the transfer-encoding: chunked header by default. This can cause the .NET Web API controller parameters to be null.
To get around this, you'll need to set the ContentLength header explicitly:
var json = JsonConvert.SerializeObject(myObject);
var content = new StringContent(json, Encoding.UTF8, "application/json");
content.Headers.ContentLength = json.Length;
var response = await client.PostAsync("http://my-api.com", content);
SO answer if you already know the transfer-encoding header is the issue: How to disable Chunked Transfer Encoding in ASP.Net C# using HttpClient
Related bug which won't be fixed, which gives some insight into the problem: https://github.com/dotnet/runtime/issues/30283

Why is this jQuery ajax call to C# web method not working

Here is my JS:
function declassifyAjax(e) {
var items = getSelected();
var docIds = new Array();
items.each(get);
//get ids of QcItem/docId we are dealing with
function get(count, el) {
docIds[count] = $(el).parent().attr('id');
}
var dataObj = new Object();
dataObj.batchId = batchId;
dataObj.docIds = docIds;
var dataString = JSON.stringify(dataObj)
//make call to webservice to get html to recreate view showing
//pending declassification
$.ajax({
type: "POST",
url: applicationRoot + 'Models/BatchQC.asmx/declassify',
data: dataString,
contentType: "application/json; charset=utf-8",
success: function (data) {
if (ProcessWebMethodResult.processWebMethodResult(data) == true) {
declassifyProcess(data, e);
}
},
error: function (e) {
alert("Failed to Get declassification details");
}
});
}
And here is my Web Service:
//type to represent the input the declassify method
public class DeclassifyType
{
public int batchId;
public string[] docIds;
}
[WebMethod(EnableSession = true)]
public WebMethodResult declassify(DeclassifyType dataString)
{
}
Any and all help appreciated!
Debugging in Firebug shows that the variables dataObj, batchId, docIds and dataString are correct. There is something wrong with the way my Web Method signature is setup I think, because the Ajax is never fired off. When stepping through the .ajax method, it goes to error, not success.
Your web methods expects one parameter, the data object you already have, but you're passing multiple parameters since you're passing the object directly.
Instead, you need to have an object with one property, dataString, and that property's value should be your object, like this:
var dataString = JSON.stringify({ dataString: dataObj });
▲--should match--▼
public WebMethodResult declassify(DeclassifyType dataString)
Ah, I just fixed it,
just changed the signature to
[WebMethod(EnableSession = true)]
public WebMethodResult declassify(int batchId, string[] docIds)
{
}
Simple really. Thanks for checking my post!

Categories