What I want is to protect my developer key while making an Ajax call to a cross-domain. Before I would just go straight to the url and plug in my key. Like this
$.ajax({
url: "https://na.api.pvp.net/api/lol/na/v2.3/team/TEAM-ID?api_key=mykey",
type: "GET",
data: {},
success: function (json) {
console.log(json);
console.log(json[teamID].name);
console.log(json[teamID].fullId);
console.log(json[teamID].roster.ownerId);
console.log(json[teamID].tag);
},
error: function (error) {}
});
This would give me the following Object, which I could easily parse out.
However, as mentioned, any person could easily grab my key during this process. So I decided to move this action to my Controller (yes I know there shouldn't be business logic here, but it is more secure and this is a quick process).
So what I am doing now is running my Javascript, which calls the Controller for a Json return.
Javascript
$.ajax({
url: "/Competitive/teamLookUp",
type: "POST",
data: "ID=" + teamID,
success: function (json) {
console.log(json);
},
error: function(error) {
}
});
And my Controller takes that in and attempts to return the JSON.
[HttpPost]
public ActionResult teamLookUp(string ID)
{
HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create("https://na.api.pvp.net/api/lol/na/v2.3/team/" + ID + "?api_key=myKey");
myReq.ContentType = "application/json";
var response = (HttpWebResponse)myReq.GetResponse();
string text;
using (var sr = new StreamReader(response.GetResponseStream()))
{
text = sr.ReadToEnd();
}
return Json(new { json = text });
}
However during this processs I return a string that is not a JSON object, thus cannot be parsed by my script.
It returns the entire json as one long string.
At this point I tried to add the following to my Controller.
var json2 = JsonConvert.DeserializeObject(text);
return Json(new { json = json2 });
But all that returned was some empty Object.
I have been trial and error'ing, searching, and guessing for the past 4 hours. I have no idea what to try anymore. I just want my Controller to pass back an Object that can be readable again like this. (Or at least some sort of formatted json object)
$.ajax({
url: "/Competitive/teamLookUp",
type: "POST",
data: "ID=" + teamID,
success: function (json) {
console.log(json);
console.log(json[teamID].name);
console.log(json[teamID].fullId);
console.log(json[teamID].roster.ownerId);
console.log(json[teamID].tag);
},
error: function (error) {}
});
Your method doesn't appear to need to be a POST as it is just getting data rather than modifying it. Therefore you could set it to be a GET instead.
Example
[HttpGet]
public JsonResult teamLookUp(string ID)
{
// Your code
return Json(text, JsonRequestBehavior.AllowGet);
}
Here's an excerpt from your code:
[HttpPost]
public ActionResult teamLookUp(string ID)
{
HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create("https://na.api.pvp.net/api/lol/na/v2.3/team/" + ID + "?api_key=myKey");
myReq.ContentType = "application/json";
// here's how to set response content type:
Response.ContentType = "application/json"; // that's all
var response = (HttpWebResponse)myReq.GetResponse();
string text;
using (var sr = new StreamReader(response.GetResponseStream()))
{
text = sr.ReadToEnd();
}
return Json(new { json = text }); // HERE'S THE ERRING LINE
}
Based on the response you received, I could understand that text already contains you desired JSON.
Now replace return Json(new { json = text }); with Json(text); and that should fix it.
To answer your question in the comments, here's how you can read the response data:
$.ajax({
url: "/Competitive/teamLookUp",
type: "POST",
data: "ID=" + teamID,
dataType: "json", // type of data you're expecting from response
success: function (json) {
console.log(json);
console.log(json[teamID].name);
console.log(json[teamID].fullId);
console.log(json[teamID].roster.ownerId);
console.log(json[teamID].tag);
},
error: function (error) {}
});
I think the problem lies where you say return Json(new {json = text;}). That's telling the json serializer to dump all your data into a property in the json obect called 'json', which is what you're seeing in the response.
Try return Json(text) instead.
Ending up using WebClient
[HttpPost]
public ActionResult teamLookUp(string ID)
{
string text = "";
try
{
using (var webClient = new System.Net.WebClient())
{
webClient.Encoding = Encoding.UTF8;
var json2 = webClient.DownloadString("https://na.api.pvp.net/api/lol/na/v2.3/team/" + ID + "?api_key=myKey");
return Json(json2);
}
}
catch (Exception e)
{
text = "error";
}
return Json(new { json = text });
}
And I parsed it like normal,
$.ajax({
url: "/Competitive/teamLookUp",
type: "POST",
data: "ID=" + ID,
dataType: "json",
success: function (resp) {
if (resp["json"] == "error") {
// error reaching server
} else {
// successfully reached server
}
json = JSON && JSON.parse(resp) || $.parseJSON(resp);
var userID = ID;
teamName = json[userID].name;
teamID = json[userID].fullId;
teamCPT = json[userID].roster.ownerId;
teamTag = json[userID].tag;
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
// error
}
});
I was having the same issue as the original poster: the ReadToEnd() call result escapes special characters and thus doesn't look like JSON to the receiving end, but then I saw a similar question answered here and thought others reading this might find it helpful as well.
To summarize: Deserializing in the Controller which the original poster tried was key, but also as others have pointed out, the return doesn't need the new {} call.
So pieced together:
using (var sr = new StreamReader(endpointResponse.GetResponseStream())) {
var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
var jsonObject = serializer.DeserializeObject(sr.ReadToEnd());
return Json(jsonObject, JsonRequestBehavior.AllowGet);
}
Related
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
I have an ajax POST call to my wcf service. It was working fine when I was returning a string (json payload) but as soon as I switched to returning an 'HttpResponseMessage' object it started giving me the ERR_CONNECTION_RESET. Same payload returned with the exception of now I want to return proper responses like 200 and 404's.
Here is the ajax call:
function Login (cred) {
$.ajax({
type: "POST",
url: ServerConfig.Server + ServerConfig.Service + "/login/",
// The key needs to match your method's input parameter (case-sensitive).
data: JSON.stringify(cred),
contentType: "application/json",
dataType: "json",
crossDomain: true,
beforeSend: function(xhr) {
xhr.setRequestHeader("Access-Control-Allow-Origin", "*");
},
error: loginFailed,
success: loginSuccess
});
}
and here is the my wcf method:
public HttpResponseMessage Login(string username, string password)
{
repository = new DbRepository();
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.BadRequest);
var res = string.Empty;
var user = repository.Login(username, password);
if (null != user)
{
res = JsonConvert.SerializeObject(user);
response = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StringContent(res)
};
}
else
{
return response;
}
return response;
}
I have confirmed that by switching back to string works as expected. Can someone shed some light on what might be going on?
Thanks.
EDIT: Here is what my 'cred' object looks like and how it was created:
$('.signin').on("click", function () {
var user = $('.username').val();
var pass = $('.password').val();
var cred = { "username": user, "password": pass };
Login(cred);
});
The JSON.stringify(cred) looks like this:
{"username":"Test1234","password":"TestPassword!"}
Hey guys Its a simple question but want to stop ajax return object contains d.
I asp.net web form
$.ajax({
type: "POST",
url: myurl,
data: JSON.stringify({value:"1"}),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (result) {
//alert("i am in success");
console.log(result);
},
failure: function (response) {
console.log("I am in failure");
}
});
and
in .cs file
[WebMethod]
public static string getSpareParts(string value)
{
List<data> spareParts;
using (var db = new WaltonCrmEntities())
{
spareParts = db.SpareParts.Select(x => new data
{
id = x.ItemID,
text = x.ItemName
}).ToList();
}
JavaScriptSerializer js = new JavaScriptSerializer();
return js.Serialize(spareParts);
//return spareParts;
}
when result is return it will contain result in result.d but i want to stop this d thing .Simply result should be the result. Can anybody solve this.
There's not much you could do about this. That's the way ASP.NET WebMethods always serialize the response. The reason why Microsoft decided to wrap the response in this .d property is to protect against this particular JSON hijacking vulnerability. Of course you could always check in your success callback whether this property is present or not:
success: function (result) {
var data = result.hasOwnProperty('d') ? result.d : result;
console.log(data);
}
Also I would very strongly recommend against writing plumbing code in your WebMethod (like serialization stuff) and just return the proper object and let the infrastructure care about serialization:
[WebMethod]
public static List<data> getSpareParts(string value)
{
using (var db = new WaltonCrmEntities())
{
return db.SpareParts.Select(x => new data
{
id = x.ItemID,
text = x.ItemName
}).ToList();
}
}
Now inside your success callback you can directly work with this collection without the need to additionally JSON.parse it:
success: function (result) {
var data = result.hasOwnProperty('d') ? result.d : result;
for (var i = 0; i < data.length; i++) {
console.log('id: ' + data[i].id + ', text: ' + data[i].text);
}
}
I have a controller action like this (very simplified):
[HttpPost]
public JsonResult Submit()
{
Response.StatusCode = Convert.ToInt32(HttpStatusCode.BadRequest);
return new JsonResult
{
ContentEncoding = Encoding.Default,
ContentType = "application/json",
Data = new {error = "xxxxxxxxxx"}
};
}
The point is just that I want to return json, but the result in the browser is string.
Here is the property from the returned object:
To use this now, I have to do something like JSON.Parse, and I don't really want that. The controller action should just return json by itself.
I have previously seen a responseJSON property on the result object from the ajax request in JavaScript.
EDIT:
I'm using the jQuery form plugin, so technically it is that who makes the request.
Here is the code where I initialize the jQuery Form Plugin:
function initializeAjaxForm() {
var feedback = document.getElementById('feedback');
$('#upload-form').ajaxForm({
url: '/xxxx/Submit',
type: 'POST',
beforeSubmit: handleBeforeSubmit,
beforeSerialize: handlePreSerialize,
success: function (data) {
stopLoadingGif();
feedback.innerHTML = 'Yay!';
console.log(data);
},
error: function (data) {
debugger;
console.log(data);
stopLoadingGif();
feedback.innerHTML = 'Nay!';
}
});
}
Here is the request in the browser:
EDIT 2:
Here is the response headers:
EDIT3:
This only seems to be a problem in the error handler.
return JSON object not JSONResult like this:
return Json(new { error = "xxxxxxxxxx"},JsonRequestBehavior.AllowGet);
Have a look at this article
Hello and many thanks for you help! I'm new to Web Programming.
I have an Ajax call to a controller in ASP .NET MVC.
When response received I try to get multiple information from the response and use it on my HTML.
$.ajax({
url: '#Url.Action("Function", "Controller")',
data: JSON.stringify({ Parameter: $(this).attr("id") }),
type: "POST",
contentType: "application/json",
timeout: 10000,
dataType: "json",
success: function (result) {
var result = result.d;
$("#textbox1").attr("value", result.attr1);
$("#textbox2").attr("value", result.attr2);
$("#textbox3").attr("value", result.attr3);
}
The Controller:
public class response
{
public string attr1;
public string attr2;
public string attr3;
}
[HttpPost]
public response Function(String Parameter)
{
response returnVal = new response();
returnVal.attr1 = "Dummy1";
returnVal.attr2 = "Dummy2";
returnVal.attr3 = "Dummy3";
return returnVal;
}
In the controller I receive the information but when the response should be parrsed nothing happen.
I guess an error occurs or I parse the data badly.
Thanks for your answers in advance!
Try changing your return type for the controller method to ActionResult (I have no idea what response is). Then change your return line to this:
return Json(returnVal, JsonRequestBehavior.AllowGet);
Have you tried
public JsonResult Function(String Parameter)
{
response returnVal = new response();
returnVal.attr1 = "Dummy1";
returnVal.attr2 = "Dummy2";
returnVal.attr3 = "Dummy3";
return Json(returnVal);
}