Разделить константы между C # и Javascript в MVC Razor - PullRequest
31 голосов
/ 02 июня 2011

Я хотел бы использовать строковые константы с обеих сторон, в C # на сервере и в Javascript на клиенте.Я инкапсулирую свои константы в классе C #

namespace MyModel
{
        public static class Constants
        {
            public const string T_URL = "url";
            public const string T_TEXT = "text";
     . . .
        }
}

Я нашел способ использовать эти константы в Javascript, используя синтаксис Razor, но мне это кажется странным:«элегантный» способ обмена константами между C # и Javascript?(Или хотя бы более автоматический, поэтому мне не нужно вносить изменения в два файла)

Ответы [ 4 ]

77 голосов
/ 02 июня 2011

То, как вы его используете, опасно. Представьте, что некоторые из ваших констант содержат кавычки или, что еще хуже, некоторые другие опасные символы =>, которые могут нарушить ваши сценарии JavaScript.

Я бы порекомендовал вам написать действие контроллера, которое будет обслуживать все константы как 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>
4 голосов
/ 02 июня 2011

Вы можете использовать помощник 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());
    }
1 голос
/ 12 марта 2015

Моя версия для создания объекта javascript с пространством имен из моих констант C #, который является неизменным:

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>())
0 голосов
/ 02 июня 2011

Вместо того, чтобы хранить ваши постоянные данные в классе 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 # на лету во время выполнения, используя отражение черной магии, либо просто располагаете хеш-таблицу / словарь, содержащий ваши константы под ключами.

jQuery.getJSON, JsonReaderWriterFactor

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...