What is the equivalent of this javascript object in c# - javascript

I have this javascript (I'm new to javascript so forgive me)
var data = [
['fff', 10.38],
['ddd', 56.33],
['ss', 24.03],
['ff', 4.77],
['dd', 0.91]
];
alert(data);
To me this looks like an array of arrays. and the alert gives:
fff,10.38,ddd,56.33,ss,24.03,ff,4.77,dd,0.91
I'm trying to create this in a c# Model - I've tried a lot but it never seems to provide exactly the same result.
alert('#Model.obs');
where the Model is:
//property
public object[] obs { get; set; }
//contructor
public EmployeeAbsenceChartViewModel()
{
object[] obbs1 = new object[2];
obbs1[0] = "rick";
obbs1[1] = 3;
object[] obbs2 = new object[2];
obbs2[0] = "rick";
obbs2[1] = 3;
obs = new object[] { obbs1, obbs2 };
}
the alert for the #Model.obs results in
System.Object[]
This should be pretty simple but the javascript that uses the data object doesn't like what I return from the model. I think I'm, missing something somewhere...
so, how would I recreate the var data object in my c# model?

When you directly write object to your View, it executes ToString() method.
In order to insert data in such format that JavaScript can work with it, you need to use JSON.
alert('#Html.Raw(JsonConvert.SerializeObject(Model.obs))');
Note that JsonConvert is a part of JSON.NET library which you can obtain using NuGet. Probably, you can use Json.Encode native method - it should work in the same way.

Related

Accessing JSON array items from Javascript returned from C# using Jint

I am trying to communicate back and forth between C# and Javascript, using Jint. Mostly smooth sailing, however I am unable to access items in arrays returned from C# within my JS scripts. Accessing properties on returned objects works fine, but accessing array items always returns null.
Below is my C# code setting up the Jint engine and executing my Javascript.
public class Runtime
{
public dynamic fetch()
{
var json = #"{
'firstName': 'Anakin',
'age': 100,
'kids': ['Luke', 'Leia']
}";
var results = JsonConvert.DeserializeObject(json);
return results;
}
}
// setup jint engine
var engine = new Engine();
engine.SetValue("runtime", new Runtime());
// execute JS script (see below)
engine.Execute(script);
My Javascript being executed looks like this:
var graph = runtime.fetch();
// accessing simple properties like this works fine
var fname = graph.firstName;
var age = graph.age;
// however, accessing array items returns null
// note: i can get the array, but not the items in the array
var firstKid = graph.kids[0]; //returns null?!
Note: I realize I can return a string from C# and then call JSON.parse(...) from Javascript, but I am trying to avoid the extra step.
Any help is very much appreciated. Thank you.

How to implement upload function using DTO?

I'm currently working on a project that uses ASP.NET Boilerplate framework and I'm starting to get the hang of using DTOs.
So I'm trying to implement an upload function where I can upload files/images, but using DTO instead of directly calling it from the controller. I would like some guidance on how to create it from DTO, including AppServices and the JavaScript, if anyone could help me.
You have to use IFormFile as a parameter of your service method.
Please find the sample code to use it. You can also create a Dto and declare an IFormFile property in Dto class and pass as a parameter to the method.
using Microsoft.AspNetCore.Http;
public async void UploadFile(IFormFile csvInput)
{
using (var stream = csvInput.OpenReadStream())
{
var currentLine = 0;
using (var reader = new StreamReader(stream))
{
...
}
}
}

Creating an array of JSON objects in JavaScript on a Razor page from custom viewmodel in MVC?

I'm trying to populate the array in my script (it's going to be used for charting with D3.JS later on). According to this post, I'm supposed to use the syntax below. However, it doesn't work, bacause I get the error on the pushy line saying Uncaught ReferenceError: WebSite is not defined, where WebSite is the name of the namespace of the data (I'm guessing that, as it's the name of my project).
<script>
var data = new Array();
#foreach (var piece in #Model.DataPieces)
{
#:data.push(#piece);
}
</script>
I'm pretty sure it has to do with the data type of piece, because the following change makes it work (at least not producing a bunch of errors). I'm picking out the individual fields from piece object and push those into the array, as a new object.
<script>
var data = new Array();
#foreach (var piece in #Model.DataPieces)
{
#:data.push({'cat': '#piece.Category', 'key': '#piece.Key', 'val': '#piece.Value'});
}
</script>
It's inconvenient, prone to mistakes and requires a refactoring of the assignment each time the model changes. How can I avoid this approach and be able to automagically create JSON objects upon assignment, as shown in the first sample?
The viewmodel for the Razor page is declared as folows.
namespace WebSite.Models
{
public class DrillDataViewModel
{
public List<DataPiece> DataPieces { get; set; }
public class DataPiece
{
public string Category { get; set; }
public string Key { get; set; }
public int Value { get; set; }
}
}
}
The line #:data.push(#piece); will be written to the output HTML as
data.push(<the result of calling ToString() on #piece>);
You need to replace #piece with something that will be evaluated to the JSON you want. This should work:
#:data.push(#Html.Raw(Json.Encode(piece)));
Or you can just output the whole array at once:
var data = #Html.Raw(Json.Encode(Model.DataPieces));
Try to pass this from Razor page to JavaScript.
#Html.Raw(#JsonConvert.SerializeObject(Model.DataPieces)
.Replace("{\"", "{")
.Replace(",\"", ",")
.Replace("\":", ":"))
The replaces serve to get rid of the invalid characters produced by default in the converter without you needing to play with streams or applying other libraries. Ugly but working.
Sometimes, I also add one more replace: .Replace("\"","'") to get a more JS like look. The outer method is needed so you don't get problems with & in the &quote;.
This is a hand-on solution so if anybody knows a better way, I'd love to get some feedback.
Try
var yourJavascriptArray=#Html.Raw(Json.Encode(YouModel));

Pass Spring model vars from JSP template to javascript

Within a <script> tag in a jsp file I have some code that looks like this:
var chart = new myChart({'id': ${user.id}, 'type': ${user.type}, 'name': {user.name});
Where user is a Spring model attribute set on the server side. My problem is that passing each different field of user feels clunky. It would be nice if I could do something like this:
var chart = new myChart('user': "${user}");
However when done this way the value of ${user} will be an object string that looks like this:
User{id=1, type='admin', name='foo'}
I know that I could just parse this string into an object in my external js, but it feels like there should be a cleaner way to do this. Thanks for the help.
EDIT: Going off of Cameron's answer below I could add this to my server-side controller code:
model.put("user", user);
String userJSON = MyJSONSerializer.serialize(user);
model.put("userJSON", userJSON);
Then in my JSP I could do:
var chart = new myChart({'user': JSON.parse('${userJSON}')});
This does solve my problem of having a messy options object, but it brings up the issue of using two model attributes for the same exact data. It would be ideal if I could use one model attribute for the user object, and then could somehow encode it to JSON on the fly.
You can convert the Object to JSON using a library like Jackson:
public static String objectAsJSON(Object obj) {
try
{
// This could be optimized by making a static ObjectMapper
return new ObjectMapper().writeValueAsString(obj);
}
catch (IOException e)
{
// Log exception and re-throw or return null
return null;
}
}
You could either call this method before putting the objectin your model and reference the String in your JSP like this:
var chart = ${jsonChart};
Or you could write a custom taglib and call objectAsJSON() from there. Then the actual myChart object could go in your model once. Your JSP might look like:
var chart = <chartlib:toJson obj="${chart}" />;

Passing Dictionary from controller to Javascript

I have a view model like this:
public class weightdata
{
...some properties
public string weights;
}
Then, I have in the controller:
weightdata details = new weightdata();
Dictionary<string,float> dict = new Dictionary<string,float>();
//do something to fill the dictionary with values
var ser = new System.Web.Script.Serialization.JavaScriptSerializer();
details.weights = ser.Serialize(dict);
return View(details);
Then in the view:
<script type="text/javascript">
var dict = #{Html.Raw(new JavaScriptSerializer().Deserialize<Dictionary<string,float>>(Model.Weights));}
</script>
But the rendering of the page is:
var dict = (it's blank)
How can I get this dictionary of values into where it can be used by javascript?
Your property is already serialized, meaning it's already JSON. You don't want to deserialize it on the view, just write it out directly:
var dict = #Html.Raw(Model.Weights);
The other alternative is to make your property a Dictionary<string, float> instead of a string, then you would serialize it on the view:
var dict = #Html.Raw(new JavaScriptSerializer().Serialize(Model.Weights));
Something I just recently read about which may make your view a bit cleaner - you can actually dump the JSON into its own script tag with type="application/json", and reference it in javascript. This may make your editor a little happier, since it's easier to separate the javascript from the C# code.
Something like:
<!-- assuming your Weights property is the serialized JSON string -->
<script id="some-json" type="application/json">
#Model.Weights
</script>
<script type="text/javascript">
var dict = JSON.parse(document.getElementById("some-json").innerHTML);
</script>
Just make sure you're targeting IE8+ or a real browser - if you need IE7 support, you'll need something like json2.js.

Categories