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.
Related
The ultimate goal here is to populate fields of a Bootstrap modal from an object in the C# code behind that has all the data I need. I serialized the object from the code behind, like this:
JavaScriptSerializer serializer = new JavaScriptSerializer();
sJSON = serializer.Serialize(aerationsystem.AerationSystem);
Now I want to reference that JSON in my Javascript function, like this:
</form>
<script type="text/javascript">
function fillModal() {
var diameterValue = document.getElementById('diameter');
var aeration = <%# sJSON %>;
diameterValue.innerText = aeration.dBinDiameter;
}
</script>
</asp:Content>
(I included that closing form tag and the closing asp:Content tag so you all could see where it was that I put this Javascript: at the very end of the file.)
However, when I call that Javascript function, this is what I see in the browser's debugger:
<script type="text/javascript">
function fillModal() {
var diameterValue = document.getElementById('diameter');
var aeration = ;
diameterValue.innerText = aeration.dBinDiameter;
}
</script>
I got the idea from here: Any way to pass an object from c# code behind to javascript?
But, the means of accessing that JSON variable does not work for me. I've tried moving my script, but when I do that, I get an error that says "The Controls collection cannot be modified because the control contains code blocks (i.e. <% ... %>).". And I've tried other delimiters, like <%= %>, but I get the same errors depending on script placement. What am I doing wrong? How can I get that JSON string to show up in my Javascript function?
<%# %> syntax is for binding data from data source.
The easiest way is to use a Literal Server Control. It seems a bit weird inside script tag, but it does the job.
<script type="text/javascript">
function fillModal() {
var diameterValue = document.getElementById('diameter');
var aeration = <asp:Literal id="JsonLiteral" runat="server"/>;
diameterValue.innerText = aeration.dBinDiameter;
}
</script>
Code Behind
JavaScriptSerializer serializer = new JavaScriptSerializer();
JsonLiteral.Text = serializer.Serialize(aerationsystem.AerationSystem);
<%# %> is a binding block so you need call the Page.DataBind() method, whether in the Page_Load or the Page_PreRender event.
You also need to curate the string so the JSON text doesn't break your javascript:
var aeration = '<%# sJSON.Replace("'", "\'").Replace("\n", " ") %>';
thank you so much for taking the time to answer my question! I ended up solving the problem, with some inspiration from you all. Instead of using a Literal control, I ended up using a <asp:HiddenField> control on the page to store the value. Then, I pulled that its value into the Javascript variable.
The hidden field: <asp:HiddenField ID="JsonLiteral" runat="server" />
The code in the event that assigned the value:
JavaScriptSerializer serializer = new JavaScriptSerializer();
JsonLiteral.Value = serializer.Serialize(aerationsystem.AerationSystem);
And the JavaScript that finished the job:
function fillModal()
{
$(document).ready(function () {
var diameter = document.getElementById('diameter');
var control = document.getElementById('<%= JsonLiteral.ClientID%>');
var aeration = JSON.parse(control.value);
diameter.innerText = aeration.dBinDiameter;
});
}
(There's gonna be a lot more to it than just that one property, of course.)
Again, thank you all for you help, because I could not have done it without you!
I have a view that passes a dictionary (along with a couple of forms and strings) to an HTML template. The template has a js file. I am accessing the dictionary in js like this:
<script type = "text/javascript">
var request_dict = {{request_dict|safe}};
</script>
Now, I want to pass this on to another view via POST(not necessarily, it can change). The format of request.POST in second view should be like a dictionary inside a dictionary. But the dictionary(request_dict) comes as a list instead of a dictionary.
How can I resolve this? Do I have to use JSON? Please mention if my explanation is wierd.
Use JSON, its safe.
View:
retutn render(request, 'template.html', {
'request_dict': json.dumps(request_dict),
}
Templete:
<script type = "text/javascript">
var request_dict = JSON.parse('{{request_dict|safe}}');
</script>
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.
I have this rows of c# code in View razor page:
#{
List<UserContact> userContacts = ViewBag.contacts;
String contacts = Html.Partial("~/Views/Shared/Contacts.cshtml", userContacts).ToHtmlString();
}
I want to use the content of contacts variable in JavaScript function since the contacts is a C# object I cant use this variable in JavaScript function.
Is there any way to use contacts variable in Javascript function?
Maybe since the type is string it can be converted to JavaScript variable?
You can use # directives like you would normally do. You can print it using Html.Raw:
var x = /* this is javascript */
#{
...
#Html.Raw(contacts)
}
Or just call #Html.Partial directly:
var x = /* this is javascript */
#{
...
#Html.Partial(...)
}
Or declare it here:
#{
...
string contacts = #Html.Partial(...)
}
And use it later:
#contacts
Yes there is, you only need to render it inside a script block. Try this:
<script>
var contacts = '#contacts';
alert(contacts);
</script>
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}" />;