How would one get resx resource strings into javascript code stored in a .js file?
If your javascript is in a script block in the markup, you can use this syntax:
<%$Resources:Resource, FieldName %>
and it will parse the resource value in as it renders the page... Unfortunately, that will only be parsed if the javascript appears in the body of the page. In an external .js file referenced in a <script> tag, those server tags obviously never get parsed.
I don't want to have to write a ScriptService to return those resources or anything like that, since they don't change after the page is rendered so it's a waste to have something that active.
One possibility could be to write an ashx handler and point the <script> tags to that, but I'm still not sure how I would read in the .js files and parse any server tags like that before streaming the text to the client. Is there a line of code I can run that will do that task similarly to the ASP.NET parser?
Or does anyone have any other suggestions?
Here is my solution for now. I am sure I will need to make it more versatile in the future... but so far this is good.
using System.Collections;
using System.Linq;
using System.Resources;
using System.Web.Mvc;
using System.Web.Script.Serialization;
public class ResourcesController : Controller
{
private static readonly JavaScriptSerializer Serializer = new JavaScriptSerializer();
public ActionResult GetResourcesJavaScript(string resxFileName)
{
var resourceDictionary = new ResXResourceReader(Server.MapPath("~/App_GlobalResources/" + resxFileName + ".resx"))
.Cast<DictionaryEntry>()
.ToDictionary(entry => entry.Key.ToString(), entry => entry.Value.ToString());
var json = Serializer.Serialize(resourceDictionary);
var javaScript = string.Format("window.Resources = window.Resources || {{}}; window.Resources.{0} = {1};", resxFileName, json);
return JavaScript(javaScript);
}
}
// In the RegisterRoutes method in Global.asax:
routes.MapRoute("Resources", "resources/{resxFileName}.js", new { controller = "Resources", action = "GetResourcesJavaScript" });
So I can do
<script src="/resources/Foo.js"></script>
and then my scripts can reference e.g. window.Resources.Foo.Bar and get a string.
There's no native support for this.
I built a JavaScriptResourceHandler a while ago that can serve Serverside resources into the client page via objects where each property on the object represents a localization resource id and its value. You can check this out and download it from this blog post:
http://www.west-wind.com/Weblog/posts/698097.aspx
I've been using this extensively in a number of apps and it works well. The main win on this is that you can localize your resources in one place (Resx or in my case a custom ResourceProvider using a database) rather than having to have multiple localization schemes.
whereas "Common" is the name of the resource file and Msg1 is the fieldname. This also works for culture changes.
Partial Javascript...:
messages:
{
<%=txtRequiredField.UniqueID %>:{
required: "<%=Resources.Common.Msg1 %>",
maxlength: "Only 50 character allowed in required field."
}
}
In a nutshell, make ASP.NET serve javascript rather than HTML for a specific page. Cleanest if done as a custom IHttpHandler, but in a pinch a page will do, just remember to:
1) Clear out all the ASP.NET stuff and make it look like a JS file.
2) Set the content-type to "text/javascript" in the codebehind.
Once you have a script like this setup, you can then create a client-side copy of your resources that other client-side scripts can reference from your app.
If you have your resources in a separate assembly you can use the ResourceSet instead of the filename. Building on #Domenics great answer:
public class ResourcesController : Controller
{
private static readonly JavaScriptSerializer Serializer = new JavaScriptSerializer();
public ActionResult GetResourcesJavaScript()
{
// This avoids the file path dependency.
ResourceSet resourceSet = MyResource.ResourceManager.GetResourceSet(CultureInfo.CurrentUICulture, true, true);
// Create dictionary.
var resourceDictionary = resourceSet
.Cast<DictionaryEntry>()
.ToDictionary(entry => entry.Key.ToString(), entry => entry.Value.ToString());
var json = Serializer.Serialize(resourceDictionary);
var javaScript = string.Format("window.Resources = window.Resources || {{}}; window.Resources.resources = {1};", json);
return JavaScript(javaScript);
}
}
The downside is that this will not enable more than one resource-file per action. In that way #Domenics answer is more generic and reusable.
You may also consider using OutputCache, since the resource won't change a lot between requests.
[OutputCache(Duration = 3600, Location = OutputCacheLocation.ServerAndClient)]
public ActionResult GetResourcesJavaScript()
{
// Logic here...
}
http://www.asp.net/mvc/overview/older-versions-1/controllers-and-routing/improving-performance-with-output-caching-cs
I usually pass the resource string as a parameter to whatever javascript function I'm calling, that way I can continue to use the expression syntax in the HTML.
I the brown field application I'm working on we have an xslt that transforms the resx file into a javascript file as part of the build process. This works well since this is a web application. I'm not sure if the original question is a web application.
use a hidden field to hold the resource string value and then access the field value in javascript
for example :
" />
var todayString= $("input[name=TodayString][type=hidden]").val();
Add the function in the BasePage class:
protected string GetLanguageText(string _key)
{
System.Resources.ResourceManager _resourceTemp = new System.Resources.ResourceManager("Resources.Language", System.Reflection.Assembly.Load("App_GlobalResources"));
return _resourceTemp.GetString(_key);
}
Javascript:
var _resurceValue = "<%=GetLanguageText("UserName")%>";
or direct use:
var _resurceValue = "<%= Resources.Language.UserName %>";
Note:
The Language is my resouce name. Exam: Language.resx and Language.en-US.resx
Good Morning:
I am having several problems trying to receive a String from Java to JSP (Javascript inside).
Java File
String var = "Hello World!";
JavaScript (inside the JSP):
window.onload = function() {
loadData();
};
function loadData() {
document.getElementById('paragraph').innerHTML = "<%=var%>";
alert(matr1); }
}
But I received org.apache.jasper.JasperException: Cannot compile the class.
The rest of JSP and JavaScript is correct, I am trying only to fill the select with the text received in Java, I read other topics but nothing works.
Any help?
Thanks.
The <%= %> or the expression tag is used in jsp as a replacement for out.print() function of java.
You don't need to put double quotes around it to use it in java script, in your case if you have imported the java file into your jsp correctly then i think this should work:
document.getElementById('paragraph').innerHTML = <%=var%>;
Or
try using the variable name directly,
document.getElementById('paragraph').innerHTML = var;
I am using cefSharp in my winForm application.
I want to pass a long json from my winform to the html page displayed by the cefSharp.
I tried to write the following:
Private WithEvents m_chromeBrowser As ChromiumWebBrowser
...
CefSharp.Cef.Initialize()
page = New Uri("www...")
m_chromeBrowser = New ChromiumWebBrowser(page.ToString)
Panel.Controls.Add(m_chromeBrowser)
...
Dim json as String = "[{code:1,name:a,val:0},{...}....]"
m_chromeBrowser.ExecuteScriptAsync("functionName('" & json & "');")
But I keep getting the following error:
Request-URI Too Long
Do you have any idea how to pass long json from winform to browser.
Thanks
Well, you would be better off exposing a .Net class to JavaScript by registering an AsyncJSObject, execute the class method from JavaScript and parse the return result.
Something like this:
public class CallbackObjectForJs {
public string getJson() {
return myJsonString;
}
}
... then register the class:
_webBrowser.RegisterAsyncJsObject(
"Browser",
new CallbackObjectForJs(),
BindingOptions.DefaultBinder);
... and finally call the method from Javascript and use a promise to get the result:
Browser.getJson().then((result) => {
var myJsonString = JSON.parse(result);
console.log(myJsonString);
});
You can read more about it here:
https://github.com/cefsharp/CefSharp/wiki/General-Usage#3-how-do-you-expose-a-net-class-to-javascript
Hope it helps!
I want to pass data from controller to javascript by embedded data directly in view. (So there won't be additional requests.)
My first solution is to use as JSON in GSP like this:
<script>
var data = ${invoice as JSON};
</script>
I don't think it's good idea since I have to use (Grails 2.2)
grails.views.default.codec = "none"
or (Grails 2.3)
grails {
views {
gsp {
codecs {
expression = 'none'
}
}
}
}
Now, I found that I can create little taglib like this:
def json = { attrs, body ->
out << (attrs.model as JSON)
}
And I can use following code in GSP:
<script>
var data = <g:json model="${invoice}" />;
</script>
Now, the question. Is using taglib is best practice? If not, please give me the best solution.
Transforming the comment in answer. You can create your JSON String in the controller and pass it to the view. Grails 2.3.x have the raw codec that don't encode your content. More info about this codec here.
Example:
class MyController {
def index() {
String invoiceString = invoice as JSON
[json: invoiceString]
}
}
index.gsp
<script>
var data = ${raw(json)};
</script>
using grails 2.4.4.
Above answer did not worked for me.
so adding what worked for me.
Source:
http://aruizca.com/how-to-render-json-properly-without-escaping-quotes-inside-a-gsp-script-tag/
<g:applyCodec encodeAs="none">
var data = ${data};
</g:applyCodec>
Now, I'm upgrading to Grails 3.2.4. I found that Sérgio Michels' method is still work. Just make sure jsonString is a String object.
<script>
var data = ${raw(jsonString)};
</script>
If it is not a String object, you can use something like following code.
<script>
var data = ${raw(mapInstance.encodeAsJSON().toString)};
</script>
I'm writing html extension (Razor) for javascript rendered charts.
I can edit javascript to read most values from data attributes, but sometime I need to insert directly inline javascript into the page and link a library. I want to make it automatic.
Is there some way to access a section (like #RenderSection("Scripts", false) ) from extension method via html helper?
Thank you
RenderSection is regular method of WebPageBase so you can use it in your helper. Here you have a snippet:
public static class HtmlExtensions
{
public static HelperResult InvokeRenderSection(this HtmlHelper html)
{
var view = (WebPageBase)html.ViewDataContainer;
var result = view.RenderSection("scripts", false);
return result;
}
}