JSON serialization - how to unquote a property value? - javascript

Given a class A ...
public class A {
public string Prop1 { get; set; }
public string Prop2 { get; set; }
}
string jsonString = JsonConvert.SerializeObject(
new A() {
Prop1 = "ABC",
Prop2 = "$.jqplot.DateAxisRenderer" }
);
jsonString contains...
"{
\"Prop1\":\"ABC\",
\"Prop2\":\"$.jqplot.DateAxisRenderer\"
}";
Question:
How can I unquote Prop2?
i.e. I want jsonString to contain...
"{
\"Prop1\":\"ABC\",
\"Prop2\":$.jqplot.DateAxisRenderer
}";
so that Prop2 is evaluated (on the client) as a reference and not a string

If you want to remove the quotes from Prop2, you can write a JSON.NET JsonConverter for the type and output the property value as 'raw'.
However (and this is important), your output will no longer be valid JSON.
If you're happy with this hybrid solution, some example code is as follows (assuming you've already referenced JSON.NET in your project):
namespace JsonRawTest
{
public class AConverter : JsonConverter
{
public override bool CanRead { get { return false; } }
public override bool CanWrite { get { return true; } }
public override object ReadJson(JsonReader reader, Type objectType,
object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override void WriteJson(JsonWriter writer, object value,
JsonSerializer serializer)
{
A obj = value as A;
writer.WriteStartObject();
writer.WritePropertyName("Prop1");
writer.WriteValue(obj.Prop1);
writer.WritePropertyName("Prop2");
writer.WriteRawValue(obj.Prop2);
writer.WriteEndObject();
}
public override bool CanConvert(Type objectType)
{
return typeof(A).IsAssignableFrom(objectType);
}
}
public class A
{
public string Prop1 { get; set; }
public string Prop2 { get; set; }
}
class Program
{
static void Main(string[] args)
{
var a = new A
{
Prop1 = "Some first value",
Prop2 = "$.jqplot.DateAxisRenderer"
};
string json = JsonConvert.SerializeObject(a,
new JsonConverter[] { new AConverter() });
...
}
}
}

You can pass it to the client as a string and then use the eval() function to parse the string like so:
var str = "alert('hello')";
eval(str); //This will execute the alert method.
var str2 = "(function() { return true; })()";
var returned = eval(str2); //Holds value of true

Related

How can I get a data from Spring-Security principal?

Now I face with some problems about principal data. Maybe it sounds like a fool. But I'm new to Spring..
I wanted to get some specific data from principal data, but it occured an error, So I cant.
this is my customUserDetails that implement UserDetails.
private String id;
private String pw;
private String name;
private String auth;
private String level;
private String label;
private int enabled;
#Override
public Collection<? extends GrantedAuthority> getAuthorities() {
ArrayList<GrantedAuthority> authList = new ArrayList<GrantedAuthority>();
authList.add(new SimpleGrantedAuthority(auth));
return authList;
}
#Override
public String getPassword() {
return pw;
}
#Override
public String getUsername() {
return id;
}
#Override
public boolean isAccountNonExpired() {
return true;
}
#Override
public boolean isAccountNonLocked() {
return true;
}
#Override
public boolean isCredentialsNonExpired() {
return true;
}
#Override
public boolean isEnabled() {
return enabled==1?true:false;
}
public String getName() {
return name;
}
public String getLabel() { return label;} // 4월 19일 동현 추가
public void setName(String name) {
this.name = name;
}
public String getAuth() {
return auth;
}
And this is principal data I got from console.log
CustomUserDetails(id=admin, pw=$2a$10$Z9C0gTGV0weknBvNi4YFY.l41vjrYo4UgO3MlPwgmIn4uDeYlepFq, name=Admin, auth=ROLE_ADMIN, level=null, label=N, enabled=1)
I want to extract label value from Principal, so I tried to do this code, but I can't.
console.log('${sessionScope.SPRING_SECURITY_CONTEXT.authentication.principal.label}');
How can I get 'label' data from principal?
Thank you for your kind support :)
In your Controller or any other bean, autowire user details like
public String doSomething(#AuthenticationPrincipal CustomUserDetails userDetails) {
String label = userDetails.getLabel();
}

Passing Object to Java from AngularJS

i'm in trouble with this problem.
I've a Javascript structur like this:
$scope.setting= {
enabled: false,
host:"",
port:"",
user:"",
pwd:"",
path:"/",
filePrefix:"",
type:"",
sendInterval:"",
dataPeriod:"",
compression:false,
subscription:[]
};
In the controller i modify the subscription array, but when i pass it to the java code:
$http.post('/api/testAndSetFTPSetting', $scope.setting)
.success(function (data) {
console.log(data);
})
.error(function (data, status, header, config) {
});
the subscription array is null.
Here the API
#RequestMapping(value = {"/api/testAndSetFTPSetting"}, method={RequestMethod.POST})
#ResponseBody
public boolean testAndSetFTPSetting(FTPConfiguration ftp) throws JAXBException {
System.out.println(ftp.getSubscribtion().size()); // here i've ever 0 and ftp.getSubscribtion() return me null
return true;
}
Here the Java Class who controls the object:
#XmlRootElement(name="FTPconfiguration")
#XmlAccessorType (XmlAccessType.FIELD)
public class FTPConfiguration{
boolean enabled = false;
String host="127.0.0.1";
int port=22;
String user="root";
String pwd="";
String path="/";
String filePrefix="data";
FTPType type=FTPType.SFTP;
int sendInterval=15;
int dataPeriod=5;
boolean compression=false;
#XmlElementWrapper(name="subscriptions")
List<String> subscription = new LinkedList<String>();
public FTPConfiguration() {
}
public FTPConfiguration(boolean enabled,String host, int port, String user, String pwd, String path, String filePrefix,
FTPType type, int sendInterval, int dataPeriod, boolean compression, List<String> subscription) {
super();
this.host = host;
this.port = port;
this.user = user;
this.pwd = pwd;
this.path = path;
this.filePrefix = filePrefix;
this.type = type;
this.sendInterval = sendInterval;
this.dataPeriod = dataPeriod;
this.compression = compression;
if(subscription != null)
this.subscription.addAll(subscription);
}
// setter and getter method
Where is my fault?
Finally solved!!! The problem was that the javascript array in java is a comma separated String. For this the value that i received was null!
EX
JavaScript OBJ
var arr = ["1", "2", "3"];
$http.post('someUrl', arr)...
Java
#RequestMapping(value = {"/someUrl"}, method={RequestMethod.POST})
public void foo(String s) { // s will be = "1,2,3"
}

How to create nested list of objects in javascript

I am trying to create Product instance in Javascript and than to pass it to the server using [webmethod].
[WebMethod]
public static void SetProduct(Product product)
{
// i want a product instance
}
Following is Product class that i'm trying to create:
public class Product
{
public Type Type { get; set; }
public Foo Foo { get; set; }
public List<Bar> Bars { get; set; }
}
public class Type
{
public string ID { get; set; }
}
public class Foo
{
public string ID { get; set; }
public string Color { get; set; }
}
public class Bar
{
public string Name { get; set; }
}
I am being able to create Type and Foo but not List<Bar> in Javascript: (see my comments in the code for more details)
Javascript
function setProduct() {
var product = {};
product.Type = {};
product.Foo = {};
product.Type.ID = 'typeID';
product.Foo.ID = 'fooID';
product.Foo.Color = 'fooColor';
//here is my question how can create List<Bar> Bars and add it to product item???
$.ajax({
type: "POST",
url: "Default.aspx/SetProduct",
contentType: "application/json; charset=utf-8",
dataType: "json",
async: false,
data: "{product:" + JSON.stringify(product) + "}",
});
}
JavaScript doesn't know what a List<T> is. It only knows how to make arrays. So you'll have to construct an array of Bars and pass that in the JSON.
Fortunately, it's an easy fix:
product.Bars = [
{ Name: "bar 1" },
{ Name: "bar 2" },
{ Name: "bar 3" },
];
The above is probably all you need. I'm pretty sure ASP.NET will be smart enough to convert that Bar[] into a List<Bar> automagically, but just in case it isn't:
public class Product
{
public Type Type { get; set; }
public Foo Foo { get; set; }
public IEnumerable<Bar> Bars { get; set; }
}
Then if you still want List<T> functionality, just convert the array to a List in your WebMethod:
[WebMethod]
public static void SetProduct(Product product)
{
var list = product.Bars.ToList();
product.Bars = list;
return product;
}
Now you can still access those nice List<T> methods:
((List<Bar>)product).Add(new Bar() { Name = "bar 4" });
// create an array
product.Bars = [];
// add an element to the array
product.Bars.push({
Name: "Foo"
});
alternatively you can initialize the array with elements as well:
// create and initialize array
product.Bars = [{Name:"Foo"}, {Name:"Bar"}];
Use an array, and add the items to the array with array.push. Eg :
product.Bars = [];
product.Bars.push({ Name: "foo" });

Translate boolean to bool after Ajax call

Hi,
I have a .net class that contains a Boolean, this class is sent to client with AJAX. The problem is that if I just use :
if(MyClass.CheckedValue)
It will always be true even if the CheckedValue is false. I supose that it is instead checking if the object is set and if so it is true? Im note sure what type this Boolean propertie gets when returning to the javascript after AJAX?
I have also tried this :
var checked;
checked = Boolean(this.CheckedValue === 'true');
if (checked)
But this will also laways be true?
How do I handle this?
Edit1 :
The classes that is sent to client :
/// <summary>
/// Are set to client with Ajax to render a correct view of the
/// current category and filter settings
/// </summary>
public class GetCategoriesAndFiltersAjax
{
public GetCategoriesAndFiltersAjax()
{
Filters = new Filter();
}
public SelectList categoryList { get; set; }
public Filter Filters { get; set; }
public class Filter
{
public Filter()
{
DefaultFilters = new List<CategoryItemFilter>();
FilterList = new List<CategoryItemFilter>();
}
/// <summary>
/// Filters like buy, sell, let and so on
/// </summary>
public List<CategoryItemFilter> DefaultFilters { get; set; }
/// <summary>
/// All other filters that a category might be bound to
/// </summary>
public List<CategoryItemFilter> FilterList { get; set; }
}
}
public class CategoryItemFilter
{
private int _filterId = -1;
private string _clientElementId1;
private string _clientElementId2;
public FilterControlType FilterControlType { get; set; }
public string Title1 { get; set; }
public string Title2 { get; set; }
public string ClientElementId1
{
get { return _clientElementId1; }
set
{
_clientElementId1 = value;
}
}
public string ClientElementId2
{
get { return _clientElementId2; }
set
{
_clientElementId2 = value;
}
}
/// <summary>
/// Keep track of whitch filter it is
/// </summary>
public int FilterId
{
get { return _filterId; }
set { _filterId = value; }
}
#region Values
public Boolean CheckedValue { get; set; }
public string TextValue { get; set; }
public SelectList DropDownList1 { get; set; }
public SelectList DropDownList2 { get; set; }
#endregion
public PublicAdFilterKey PublicAdFilterKey { get; set; }
}
And this is how the AJAX method looks like on server :
public JsonResult GetCategoriesByParent(int id, Boolean editMode)
{
FilterModel filterModel = new FilterModel();
CategoryModel categoryModel = new CategoryModel();
List<ModelViewCategory> mvCategoryList = new List<ModelViewCategory>();
//List<AdCategory> categoryList;
FilterHandler filterHandler = new FilterHandler();
GetCategoriesAndFiltersAjax value = new GetCategoriesAndFiltersAjax();
try
{
value.categoryList = new SelectList(categoryModel.GetCategoriesByParent(id).ToArray(), "Id", "Name");
if (editMode)
value.Filters = filterHandler.ConvertFilterModelToAjaxCategoryFilter(filterModel.GetCategoryFilterByCategory(id), Biss.Views.ViewClasses.Filter.FilterType.Edit);
else
value.Filters = filterHandler.ConvertFilterModelToAjaxCategoryFilter(filterModel.GetCategoryFilterByCategory(id), Biss.Views.ViewClasses.Filter.FilterType.Display);
return this.Json(value, JsonRequestBehavior.AllowGet);
}
catch (Exception ex)
{
throw;
}
}
Edit 2 :
This is how the client looks like(not exacly but close, its alot more complicated)
$.ajax({
url: actionPath,
type: 'POST',
dataType: 'json',
data: ((typeof config.postData == "function") ? config.postData() : config.postData) || { id: $(source).val(), editMode: _filterInEditMode },
success: function (data) {
methods.reset();
$.each(data.categoryList, function () {
SetFilterSubEdit(data.DefaultFilters);
},
error: function () {
methods.showError();
}
});
function SetFilterSubEdit(data) {
$.each(data, function () {
if (data.CheckedValue)
$("#" + visibleElements[0]).attr('checked', checked);
}
}
Sorry, the problem was that the brackets was missing on client side.
if (data.CheckedValue){
}

JavaScriptSerializer deserialize object "collection" as property in object failing

I have a js object structured like:
object.property1 = "some string";
object.property2 = "some string";
object.property3.property1 = "some string";
object.property3.property2 = "some string";
object.property3.property2 = "some string";
i'm using JSON.stringify(object) to pass this with ajax request. When i try to deserialize this using JavaScriptSerializer.Deserialize as a Dictionary i get the following error:
No parameterless constructor defined for type of 'System.String'.
This exact same process is working for regular object with non "collection" properties.. thanks for any help!
It's because the deserializer doesn't know how to handle the sub-object. What you have in JS is this:
var x = {
'property1' : 'string',
'property2' : 'string',
'property3' : { p1: 'string', p2: 'string', p3: 'string' },
};
which doesn't have a map to something valid in C#:
HashTable h = new HashTable();
h.Add("property1", "string");
h.Add("property2", "string");
h.Add("property3", ???);
The ??? is because there's no type defined here, so how would the deserializer know what the anonymous object in your JS represents?
Edit
There is no way to do what you're trying to accomplish here. You'll need to make your object typed. For example, defining your class like this:
class Foo{
string property1 { get; set; }
string property2 { get; set; }
Bar property3 { get; set; } // "Bar" would describe your sub-object
}
class Bar{
string p1 { get; set; }
string p2 { get; set; }
string p3 { get; set; }
}
...or something to that effect.
As a more general answer, in my case I had objects that looked like:
{ "field1" : "value", "data" : { "foo" : "bar" } }
I originally had the data field as a string when it should've been a Dictionary<string, string> as specified on MSDN for objects that use dictionary syntax.
public class Message
{
public string field1 { get; set; }
public Dictionary<string, string> data { get; set; }
}

Categories

Resources