我想在服务器上的C#和客户端的Javascript中使用字符串常量。 我将我的常量封装在C#类
中namespace MyModel
{
public static class Constants
{
public const string T_URL = "url";
public const string T_TEXT = "text";
. . .
}
}
我找到了一种使用Razor语法在Javascript中使用这些常量的方法,但它看起来很奇怪:
@using MyModel
<script type="text/javascript">
var T_URL = '@Constants.T_URL';
var T_TEXT = '@Constants.T_TEXT';
. . .
var selValue = $('select#idTagType').val();
if (selValue == T_TEXT) { ...
还有更优雅的方式在C#和Javascript之间共享常量吗? (或者至少更自动,所以我不必在两个文件中进行更改)
答案 0 :(得分:77)
您使用它的方式很危险。想象一下你的一些常量包含引用,或者更糟糕的是其他一些危险的字符=&gt;那会破坏你的javascripts。
我建议你编写一个控制器动作,它将以javascript:
的形式提供所有常量public ActionResult Constants()
{
var constants = typeof(Constants)
.GetFields()
.ToDictionary(x => x.Name, x => x.GetValue(null));
var json = new JavaScriptSerializer().Serialize(constants);
return JavaScript("var constants = " + json + ";");
}
然后在你的布局中引用这个脚本:
<script type="text/javascript" src="@Url.Action("Constants")"></script>
现在,只要在脚本中需要常量,只需按名称使用它:
<script type="text/javascript">
alert(constants.T_URL);
</script>
答案 1 :(得分:4)
您可以使用HTML帮助程序输出必要的脚本,并使用反射来获取字段及其值,以便它自动更新。
public static HtmlString GetConstants(this HtmlHelper helper)
{
System.Text.StringBuilder sb = new System.Text.StringBuilder();
sb.AppendLine("<script type=\"text/javascript\">");
foreach (var prop in typeof(Constants).GetFields())
{
sb.AppendLine(string.Format(" var {0} = '{1}'", prop.Name, prop.GetValue(null).ToString()));
}
sb.AppendLine("</script>");
return new HtmlString(sb.ToString());
}
答案 2 :(得分:1)
我的版本是从我的C#常量创建一个不可变的命名空间的javascript对象:
public static HtmlString GetConstants<T>()
{
StringBuilder jsConstant = new StringBuilder();
jsConstant.Append("myApp." + typeof(T).Name + " = Object.freeze({");
foreach(var item in typeof(T).GetFields())
{
jsConstant.Append(string.Format("{0}:'{1}'",item.Name,item.GetValue(null).ToString()) + ",");
}
jsConstant.Remove(jsConstant.Length - 1, 1);
jsConstant.Append("})");
return new HtmlString(jsConstant.ToString());
}
在Razor中这样使用:
@(HtmlHelpers.GetConstants<MyApp.Infrastructure.ApplicationConstants.SomeConstants>())
答案 3 :(得分:0)
而不是将常量数据存储在C#类中,而是将其存储在静态配置/常量文件中。
// Constants.json
{
"T_URL": "url",
"T_TEXT": "text"
}
// Constants.cs
// load the json from a file stream into a constants object
// Constants.js
window.Constants = $.getJSON(url);
只需将其存储为某种文件格式(json,xml,cvs等),然后从客户端和文件格式加载它。服务器
这意味着您可以在运行时使用黑魔法反射在C#中创建一个类,或者只是在键下包含一个包含常量的哈希表/字典。