I have a question in using CryptoObfuscator or RedGate SmartAssembly to obfuscate Asp Mvc Assemblies :
It seems when you use one of these tools to obfuscate assemblies, then they will rename properties of classes, right?
so I think because of this operation we will lose access to some of the values in JSON format that would comes from server during serialization ( I mean that because of renaming the properties we cant parse JSON object in JS correctly)
If this is true, so how can we prevent loosing parseJSON operation in JS?
Let me include more details :
consider this class structure
public class MyClass
{
public string FName{get;set;}
. . .
}
//SampleController :
public JsonResult GetJson()
{
return Json(new MyClass{FName = "Alex"});
}
Now in ClientSide :
$.ajax({
url: "/Sample/GetJson",
context: document.body
}).success(function(data) {
//this is my problem : can I access to FName or Not?
var fname = jQuery.parseJSON(data).FName;
});
Basically Obfuscators DO NOT change return value's Property's names.
But if some obfuscator does so... you can Simply accomplish this by using following in your ajax call:
$.ajax({
url: "/Sample/GetJson",
dataType: "json"
success: function(data) {
var transformedData = {fname:arguments[0], somethingElse:arguments[1]};
//or
var fname = arguments[0];
//do the rest here...
}
});
You can also use [DoNotObfuscate] attribute in "smart assembly"
By using this, you can prevent json results from being obfuscated at all (on server side).
Also there should be some (other/same) strategies for other obfuscators.
I personally use CryptoObfuscator and it has some options to prevent (what/where) ever you'd like from being obfuscated.
Related
I am pulling an XML template from the database and then using this template in my view (DYMO labels).
My issue is that when I use #Html.Raw, even with quotes around it, it only reads the first line as "Text" and after the line break reads the rest of the XML file as code on the page.
Picture below:
1
The first line appears fine, but starting with <DesktopLabel Version the XML is rendered as not plain text inside quotes.
Here is my current behind the scenes code:
var labelXml = '#Html.Raw(Model.XML)';
I need the entirety of the string stored in quotes ("", ''). Any help?
you need to encode the xml
#Html.Raw(Html.Encode(Model.XML))
I was able to resolve this issue using a JSON AJAX controller action call. Code and explanation below in case anyone ever needs help on this:
try {
var _size = "#Model.size";
$.ajax({
data: { size: _size},
type: "POST",
url: "/Unit/GetXMLFile/",
success: function (data) {
var labelD = dymo.label.framework.openLabelXml(data);
labelD.print(printerName);
},
error: function (response) {
alert("error" + response.responseText);
}
});
}
catch(err) {
alert("Couldn't load label");
return;
}
Because we are directly injecting the XML string into our DYMO framework we prevent any chance of encoding the <> characters as < and >.
I believe that the root issue came from attempting to transfer XML strings from Viewmodel > Javascript. Even attempting to store the XML in the viewmodel and store as plain text once inside the view did not work.
The only method that worked was the AJAX direct controller action that keeps XMLs format without any conversion.
Here is my controller action:
[HttpPost]
public JsonResult GetXMLFile(string size)
{
string XML = "";
if (size == "Small")
{
XML = db.UnitLabels.Where(x => x.Size == "Small").Select(x => x.LabelXML).FirstOrDefault();
}
else
{
XML = db.UnitLabels.Where(x => x.Size == "Large").Select(x => x.LabelXML).FirstOrDefault();
}
return Json(XML, JsonRequestBehavior.AllowGet);
}
I know that this question has been asked several times, but none of the previous solutions helped me out with my problem (that seems a pretty simple one actually).
I just want to send a Json object to a Post method that I created in a controller class.
Here's the interesting portion of my controller class:
[Route("api/[controller]")]
public class CodeController : Controller
{
[HttpPost]
public void Post([FromBody] InfoNegozio value)
{
return;
}
}
I kept it simple as I just want the value to be set properly.
Here's the class InfoNegozio:
public class InfoNegozio
{
public int IdNegozio { get; set; }
public string NomeNegozio { get; set; }
public int AttesaStimata { get; set; }
public DateTime UltimoAggiornamento { get; set; }
}
This is the code used to send data to this API:
var myData = { "IdNegozio": idNegozio, "AttesaStimata": tempoAttesa };
$.ajax({
url: "api/Code",
type: "POST",
contentType: "application/json",
dataType: "json",
data: JSON.stringify(myData)
});
The JQuery code just call the webapi controller, the value field is a not null InfoNegozio object, but the field IdNegozio and AttesaStimata are always 0.
I could ask that I'm using a controller in a Razor Page project, and I had to add this line of code in the Startup.Configure method in order to make it work (with "it" I meant the other webapi GET methods).
app.UseEndpoints(endpoints => { endpoints.MapControllers(); });
Any Idea?
Edited
Using postman I figured out what the difference is between a wroking call and a not working one.
The posting this json with postman is works:
{
"IdNegozio": 1,
"AttesaStimata": 36
}
Unfortunately, with jquery, using JSON.stringify, I get this (note the double quote on the values):
{
"IdNegozio": "1",
"AttesaStimata": "36"
}
And this don't work!
Are Json stringify incompatible with .net core Web Api? Is it possible there isn't a clean approach to make those 2 libraries work together?
Edited 2
I ended up building the json manually, forcing jquery to sent "my version", so my js code is now looking:
var myData = '{ "IdNegozio": '+idNegozio+', "AttesaStimata": '+tempoAttesa+' }';
$.ajax({
url: "api/Code",
type: "POST",
contentType: "application/json",
dataType: "json",
data: myData
});
Anyway I don't like this solution as it seems I'm not using the right way to build the json object, so any smarter solution would be much appreciated.
Creating an answer so we don't have a million comments on your post. This is a ASP.NET Core 3.1 Web API project, correct ? If so, try making these couple of changes and see if that fixes the issue.
Inherit from ControllerBase rather than the full Controller class. Also add the [ApiController] attribute to your CodeController class. Then for your Post action, remove the [FromBody] attribute from your InfoNegozio parameter. Like this :
[Route("api/[controller]")]
[ApiController]
public class CodeController : ControllerBase
{
[HttpPost]
public IActionResult Post(InfoNegozio value)
{
return Ok(value);
}
}
See if that fixes anything. Something is getting screwed up during model binding, which leads me to believe that your JSON Serialization configuration is messed up. If you can post your Startup.cs, then we can see if there may be a configuration error. I just opened up a .NET Core 3.1 Web API project and tested one of my controllers and it works as expected. So give that a shot and see if maybe that fixes it. These items will affect how the controller is configured, so if it is an API controller, handling standard API requests (application/json) then it should be configured as such. You can read the specifics on the ASP.NET Core 3.1 docs but having this setup properly as an API Controller is going to make sure your JSON requests are properly serialized. Right now you have it set up like an MVC controller which is likely why you're running into issues.
Edit: Also, consider returning an IActionResult from your controller action. Might make testing easier as you can actually receive a response that will help you find the error. Then simply just change return; to return Ok(); Updated code sample to reflect this.
If you want to write like the first way you provided, you can use parseInt to ensure that int type data is passed.
Try this codeļ¼
var myData = { "IdNegozio": parseInt(idNegozio), "AttesaStimata": parseInt(tempoAttesa) };
$.ajax({
url: "api/Code",
type: "POST",
contentType: "application/json",
dataType: "json",
data: JSON.stringify(myData)
});
There is also another choice (if you used core 3.x version):
Install Microsoft.AspNetCore.Mvc.NewtonsoftJson -Version 3.x
library
Add services.AddControllersWithViews().AddNewtonsoftJson(); in
ConfigureServices in startup.cs.
After these two steps, you can use the json format you used at the beginning.
var myData = { "IdNegozio": idNegozio, "AttesaStimata": tempoAttesa };
$.ajax({
url: "api/ApiCode",
type: "POST",
contentType: "application/json",
dataType: "json",
data: JSON.stringify(myData)
});
I can successfully make a jQuery Ajax call into my C# Controller and receive back an XML string, but I need to in turn gather some Portfolio dates and package them up into a JSON object so I can send them back into another C# Controller.
If it's a C# issue, then I apologize if I'm in the wrong forum...however I'd like to pass my JSON object into the server side controller ..
Here's what I'm trying to do:
var nodeDatesJson = {"nodedates": // CREATE JSON OBJECT OF DATE STRINGS
{ "date": 01/20/2012,
"date": "01/21/2012" } };
getTradeContribs(thisPfId, nodeDatesJson.nodedates.date);
Now call the next js function:
function getTradeContribs(pfid, nodedates) {
//alert(nodedates);
$.ajax({ // GET TRADE CONTRIBS FROM SERVER !!
url: "/Portfolios/getTradeContribs?portfolioId=" + pfid + "&nodedates=" + nodedates,
type: "GET", // or "PUT"
dataType: "json",
async: true,
success: parseTradeContribs,
error: function (error) {
alert("failed in opening Trade Contribs file !!!");
}
});
}
function parseTradeContribs(data) {
alert("In parseTradeContribs..." );
$(data).find("Trade").each(function(){
$(".TradeContrib").append($(this).text());
})
}
and my C# controller is trying to read in the "nodedates" JSON object, but HOW do I read it in ?
public string getTradeContribs(string portfolioId, **string nodedates**)
{
// Build Portfolio Select request here !
RequestBuilder rzrRequest = new RequestBuilder();
// REQUEST FOR CONTRIBUTIONS !
// ... more code here..
xmlResponse.LoadXml(contribResponse);
string jsonTest = #" {""nodedates"": ""date"":""01/01/2012""}";
//return xmlResponse.OuterXml; // WORKS FINE
return "<Trade><TradeId>1234</TradeId></Trade>"; // RETURN TEST XML STR
}
thank you in advance...
Bob
The best way to receive a list of dates in a MVC action is to bind to a collection. What this means is that you should put your dates and other attributes in a form with the following naming convention:
<input type="hidden" name="dates" value="2012-1-20" />
<input type="hidden" name="dates" value="2012-1-21" />
Then you should serialize this form (look into jquery's docs for this) and post its data to your action, which will be something along the lines of:
public ActionResult getTradeContribs(string portfolioId, IList<DateTime> dates) {
// Do your work here
}
You should really take a look into MVC Model binding and collection binding as well:
Model binding to a list
Model binding objects
Also, if I may, your javascript object has two properties with the same name, which is probably not what you mean. If you want to have multiple dates stored somewhere in a object, you should use an array:
var nodeDatesJson = {"nodedates":
[ "01/20/2012", "01/21/2012" ] };
Sorry, but I didn't understand your doubt very well...but here it goes:
Maybe you should pass the json, well-formatted, as a string and use some C# parser.
This way you can get a object in server-side as same as the Json object in javascript.
=]
Currently, the following code works as intended but if I add an echo such as "LANG: en" anywhere in the code (let's say in the bootstrap), the following code won't work anymore and I get this ajax request response :
<br/>LANG : en{"response":true,"id":13}
(the ajax response contains the echo + json array ) and therefore I'm not able to print the id (it will print : undefined when i will try to access to data.id).
My question is : How can I print my debug info and still manage to perform ajax requests ?
Here is my code in the controller :
public function init()
{
$this->_helper->ajaxContext->addActionContext('retrievecategories', 'json')->initContext();
}
public function retrievecategoriesAction()
{
$this->_helper->layout()->disableLayout();
$this->_helper->viewRenderer->setNoRender(true);
if ($this->getRequest()->isXmlHttpRequest()) {
if (isset($_POST['id']))
$id = $_POST['id'];
$id+=1;
echo json_encode(array('response' => true, 'id' => $id));
}
}
My js code :
jQuery(function(){
var obj = {"id":12};
jQuery.ajax({
url: '/search/retrievecategories?json',
type: 'post',
data: obj,
dataType: 'json',
success: function(data){
var id = data.id;
alert(id);
},
error: function(data){
var id = data.id;
alert(id);
}
});
});
I hope I was clear enough. Thank you for your time !
If you echo anything but the JSON object, the JQuery parser will fail because the response is no longer a valid JSON. you could make a custom parser which interprets the response text and takes away the debug info leaving the JSON object, or you can include the debug info in the array you encode.
json_encode(array('data'=>'data','debug'=>'debug info'))
Then you detect if the debug field is present and after a console.log() or alert() you delete it form the object.
I would strongly recommend that you read about firePHP. It uses the same console that Firebug uses to display debug information from your php code. It is really simple to use with the Zend_Log.
I need to get Json data from a C# web service.
I know there are several questions based on this, trust me I have read through quite a few but only to confuse me further.
This is what I have done :
In my web service I have included : [System.Web.Script.Services.ScriptService] for the class & [ScriptMethod(ResponseFormat = ResponseFormat.Json, UseHttpGet = true)] for the method
I have also used a JavaScriptSerializer() to convert my data to a string
I am calling this service using $.getJSON()
If I don't use that I get an Cross domain reference error.
To do this I had to setup m service to get the callback function name
so I am passing this.Context.Request["callback"] + serialized Json Data;
But in the output I get it wrapped in
< string xmlns="http://XYZ...">
The data within the tags is in the format I need
I also tried setting content type using : $.ajaxSetup({ scriptCharset: "utf-8" , contentType: "application/json; charset=utf-8"});
But still no success.
Addded later: I accepted frenchie's anwser beacuse I know it is the correct approach but I stil cud not get it to work... I just put the webservice & website in the same domain & used xml, I know it wasnt the best way, but I had spent 2 days on it & could not afford to waste more.
Use this:
var JsonString = ....;
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "YourWebServiceName.asmx/yourmethodname",
data: "{'TheData':'" + JsonString + "'}",
dataType: "json",
success: function (msg) {
var data = msg.hasOwnProperty("d") ? msg.d : msg;
OnSucessCallBack(data);
},
error: function (xhr, status, error) {
alert(xhr.statusText);
}
});
function OnSuccessCallData(DataFromServer) {
// your handler for success
}
and then on the server side, in the code behind file that's auto-generated in your AppCode folder, you write something like this:
using System.Web.Services;
using System.Web.Script.Serialization;
[System.Web.Script.Services.ScriptService]
public class YourWebServiceName : System.Web.Services.WebService
{
[WebMethod]
public string yourmethodname(string TheData)
{
JavascriptSerializer YourSerializer = new JavascriptSerializer();
// custom serializer if you need one
YourSerializer.RegisterConverters(new JavascriptConverter [] { new YourCustomConverter() });
//deserialization
TheData.Deserialize(TheData);
//serialization
TheData.Serialize(TheData);
}
}
If you don't use a custom converter, the properties between the json string and the c# class definition of your server-side object must match for the deserialization to work. For the serialization, if you don't have a custom converter, the json string will include every property of your c# class. You can add [ScriptIgnore] just before a property definition in your c# class and that property will be ignored by the serializer if you don't specify a custom converter.