【问题标题】:servicestack serialize to json with function使用函数将 servicestack 序列化为 json
【发布时间】:2014-10-08 15:28:02
【问题描述】:

我有一个 c# 助手类,它声明了一个包含 javascript 函数名称的 javascript 组件。

new Button({Label = "Execute", OnClick = "ExecuteFunction"});

这应该会创建一个 json 文本:

{ label = "Execute", onClick = ExecuteFunction}

(其中 ExecuteFunction 是一个 javascript 函数)

servicestack-text 转 json 可以吗?

【问题讨论】:

    标签: json servicestack-text


    【解决方案1】:

    这对于任何 JSON 序列化程序都是不可能的,因为这不是 valid JSON

    { label = "Execute", onClick = ExecuteFunction}
    

    最接近的有效 JSON 是:

    {"label": "Execute", "onClick": "ExecuteFunction"}
    

    在 JSON 中也没有 function 文字的概念,它只是一种数据格式,不要与 JavaScript 代码混淆。

    【讨论】:

    • @Marco 这是 JavaScript 而不是 JSON 的一个例子,我的回答特别提到不要混淆两者。
    • 是和否,但我希望通过 json 从服务器端对象中获取侦听器部分。不过没关系,我刚刚发现 extjs (v5) 支持使用函数名作为字符串,所以可以使用 { "onClick": "ExecuteFunction"}。谢谢!
    【解决方案2】:

    您可以使用 JSON.NET (Newtonsoft.JSON)。
    但它仍然是无效的 JSON,因为这是一个 JavaScript 对象,而不是有效的 JavaScript 对象表示法。
    因此,您需要邪恶的 eval,JSON.parse 不起作用。
    从好的方面来说,eval 可能更快。

    至于 ServiceStack.NET:当您忽略所有功能和向后兼容性(例如 .NET 2.0)时,很容易变得快速。

    代码:

    namespace JQuery.Plugins.SlickGrid
    {
    
    
        // Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaargh, invalid JSON 
        public class FunctionNameConverter : Newtonsoft.Json.JsonConverter
        {
    
    
            public override void WriteJson(Newtonsoft.Json.JsonWriter writer
                , object value, Newtonsoft.Json.JsonSerializer serializer)
            {
                string jsfn = (string)value;
                writer.WriteRawValue(jsfn);
            } // End Sub WriteJson
    
    
            public override object ReadJson(Newtonsoft.Json.JsonReader reader, System.Type objectType
                , object existingValue, Newtonsoft.Json.JsonSerializer serializer)
            {
                throw new System.NotImplementedException();
            } // End Function ReadJson
    
    
            public override bool CanConvert(System.Type objectType)
            {
                return object.ReferenceEquals(typeof(string), objectType);
            } // End Function CanConvert
    
    
        } // End Class FunctionNameConverter
    
    
    } // End Namespace JQuery.Plugins.SlickGrid
    

    这里有一个用法示例:

    namespace JQuery.Plugins.SlickGrid
    {
    
    
        public class cSlickGrid
        {
            // public List<object> data 
            // public System.Data.DataTable data 
    
            protected string m_strLanguage = null;
    
            protected System.Collections.Generic.List<JQuery.Plugins.SlickGrid.cColumn> m_columns;
            protected System.Collections.IList m_List;
    
            protected System.Data.DataTable m_dt;
            public object data
            {
                get
                {
                    if (m_List != null)
                    {
                        return m_List;
                    }
    
                    return m_dt;
                }
    
                set
                {
                    if (value == null)
                    {
                        m_List = null;
                        m_dt = null;
                        return;
                    }
    
                    System.Type tValueType = value.GetType();
    
                    if (object.ReferenceEquals(tValueType, typeof(System.Data.DataTable)))
                    {
                        m_dt = (System.Data.DataTable)value;
                        return;
                    }
    
                    if (IsGenericList(value) || object.ReferenceEquals(tValueType, typeof(System.Collections.IList)))
                    {
                        m_List = (System.Collections.IList)value;
                        return;
                    }
    
                    throw new System.NotImplementedException("cSlickGrid property data: Support for this type not implemented. Only supports DataTable or IList at the moment.");
                }
            } // data
    
    
            protected bool IsGenericList(object obj)
            {
                if (obj == null)
                {
                    throw new System.ArgumentNullException("obj");
                } // (obj == null) 
    
                return IsGenericList(obj.GetType());
            } // IsGenericList
    
    
            protected bool IsGenericList(System.Type tObjectType)
            {
                if (tObjectType == null)
                {
                    throw new System.ArgumentNullException("type");
                } // (tObjectType == null) 
    
                foreach (System.Type @interface in tObjectType.GetInterfaces())
                {
                    if (@interface.IsGenericType)
                    {
                        if (object.ReferenceEquals(@interface.GetGenericTypeDefinition(), typeof(System.Collections.Generic.ICollection<>)))
                        {
                            // if needed, you can also return the type used as generic argument 
                            return true;
                        } // Object.ReferenceEquals([interface].GetGenericTypeDefinition(), GetType(ICollection(Of )))
                    } // (@interface.IsGenericType) 
                }
    
                return false;
            } // IsGenericList
    
    
            public System.Collections.Generic.List<JQuery.Plugins.SlickGrid.cColumn> columns
            {
    
                get { return m_columns; }
    
                set
                {
                    foreach (JQuery.Plugins.SlickGrid.cColumn SlickGridColumn in value)
                    {
                        if (SlickGridColumn.formatter != null && SlickGridColumn.formatter == "Slick.Formatters.Date")
                        {
                            if (string.IsNullOrEmpty(m_strLanguage))
                            {
                                throw new System.NullReferenceException("m_strLanguage is NULL. Please set the language in the constructor.");
                            }
                            else
                            {
                                SlickGridColumn.formatter = "Slick.Formatters.Date_" + m_strLanguage;
                            }
    
                        }
                    }
    
                    m_columns = value;
                }
            }
    
    
    
            public cSlickGrid()
            {
            }
    
    
            //Public Sub New(strLanguage As String, lsData As List(Of Object), lsColumns As List(Of JQuery.Plugins.SlickGrid.cColumn))
            public cSlickGrid(string strLanguage, object objData, System.Collections.Generic.List<JQuery.Plugins.SlickGrid.cColumn> lsColumns)
            {
                if (string.IsNullOrEmpty(strLanguage))
                {
                    throw new System.Data.NoNullAllowedException("strLanguage may not be NULL.");
                }
    
                this.m_strLanguage = strLanguage.ToUpper();
                //Me.data = lsData
                this.data = objData;
                this.columns = lsColumns;
            }
    
    
        } // cSlickGrid
    
    
    
    
        // various partial sources
        // http://www.developerfusion.com/project/18821/slickgrid/
        // jQuery.Plugins.SlickGrid.cOptions
        public class cOptions
        {
            public bool asyncEditorLoading = true;
            public bool autoEdit = true;
    
            public bool autoHeight = true;
    
            public short defaultColumnWidth = 80;
    
            public bool editable = true;
    
            public bool editOnDoubleClick = false;
    
            public bool enableAddRow = false;
            public bool enableCellNavigation = true;
            public bool enableCellRangeSelection = true;
    
            public bool enableColumnReorder = true;
            public bool forceFitColumns = false;
            public bool leaveSpaceForNewRows = true;
            public bool manualScrolling = false;
            public bool multiSelect = true;
            public bool rerenderOnResize = true;
            public int secondaryHeaderRowHeight = 25;
        } // cOptions 
    
    
        // http://www.java2s.com/Open-Source/ASP.NET/Framework/lucilla/Lucilla/Framework/Web/Builders/SlickGrid/Column.cs.htm
        // jQuery.Plugins.SlickGrid.cColumn
        public class cColumn
        {
    
    
            public cColumn()
            {
            }
    
    
            public cColumn(string strID, string strName, string strField)
            {
                this.id = strID;
                this.name = strName;
                this.field = strField;
            }
    
    
            public string id = null;
            // Column ID.
            public string name = "";
            // Column name to put in the header.
            public string toolTip = null;
            // Tooltip (if different from name).
            public string field = null;
            // Property of the data context to bind to.
    
            [Newtonsoft.Json.JsonProperty(), Newtonsoft.Json.JsonConverter(typeof(FunctionNameConverter))]
            public string formatter = null;
            // (default 'return value || ""') Function responsible for rendering the contents of a cell. Signature: function formatter(row, cell, value, columnDef, dataContext) { ... return "..."; }
    
            [Newtonsoft.Json.JsonProperty(), Newtonsoft.Json.JsonConverter(typeof(FunctionNameConverter))]
            public string editor = null;
            // An WithEditorFunction class.
    
            [Newtonsoft.Json.JsonProperty(), Newtonsoft.Json.JsonConverter(typeof(FunctionNameConverter))]
            public string validator = null;
            // An extra validation function to be passed to the editor.
            public bool? unselectable = null;
            // If true, the cell cannot be selected (and therefore edited).
            public bool? cannotTriggerInsert = null;
            // If true, a new row cannot be created from just the value of this cell.
    
            [Newtonsoft.Json.JsonProperty(), Newtonsoft.Json.JsonConverter(typeof(FunctionNameConverter))]
            public string setValueHandler = null;
            // If true, this handler will be called to set field value instead of context[field].
    
    
            public short? width = null;
            // Width of the column in pixels.
            public bool? resizable = null;
            // (default true) If false, the column cannot be resized.
            public bool? sortable = null;
            // (default false) If true, the column can be sorted (onSort will be called).
            public short? minWidth = null;
            // Minimum allowed column width for resizing.
            public short? maxWidth = null;
            // Maximum allowed column width for resizing.
            public string cssClass = null;
            // A CSS class to add to the cell.
            public string headerCssClass = null;
            // A CSS class to add to the cell.
            public bool? rerenderOnResize = null;
            // Rerender the column when it is resized (useful for columns relying on cell width or adaptive formatters).
    
            [Newtonsoft.Json.JsonProperty(), Newtonsoft.Json.JsonConverter(typeof(FunctionNameConverter))]
            public string asyncPostRender = null;
            // Function responsible for manipulating the cell DOM node after it has been rendered (called in the background).
    
            public string behavior = null;
            // Configures the column with one of several available predefined behaviors: "select", "move", "selectAndMove".
        } // cColumn
    
    
        public class RLExtends
        {
            public static void translateHeader(System.Data.DataTable pData, System.Data.DataTable pHeader, string pLanguageField)
            {
                if ((pData != null) && (pHeader != null))
                {
                    for (int tC = pData.Columns.Count - 1; tC >= 0; tC += -1)
                    {
                        System.Data.DataColumn tColumn = pData.Columns[tC];
    
                        if (tColumn.ColumnName.StartsWith("x_"))
                            pData.Columns.RemoveAt(tC);
    
                        if (tColumn.ColumnName.StartsWith("h"))
                        {
                            string tH = tColumn.ColumnName.Split(';')[0].Remove(0, 1);
    
                            int itH = int.Parse(tH);
    
                            if (itH < pHeader.Rows.Count && pHeader.Columns.Contains(pLanguageField))
                            {
                                string tName = System.Convert.ToString(pHeader.Rows[itH][pLanguageField]);
    
                                tColumn.Caption = tColumn.ColumnName;
                                tColumn.ColumnName = !pData.Columns.Contains(tName) ? tName : tName + " (" + tC.ToString() + ")";
                            }
                            else
                            {
                                tColumn.Caption = tColumn.ColumnName;
                                tColumn.ColumnName = string.Format("404: (h: {0}, c: {1}, l: {2})", tH, tC, pLanguageField);
                            }
                        }
                    }
                }
            }
    
    
            public static System.Collections.Generic.List<SlickGrid.cColumn> dataToColumns(System.Data.DataTable pData)
            {
                System.Collections.Generic.List<SlickGrid.cColumn> tColumns = new System.Collections.Generic.List<SlickGrid.cColumn>();
    
                // Fix - pData = NULL error, 07.03.2014, sts
    
                if (pData != null)
                {
                    foreach (System.Data.DataColumn tColumn in pData.Columns)
                    {
                        string[] tValue = tColumn.Caption.Split(';');
    
                        if (!tColumn.ColumnName.StartsWith("x_") && tValue.Length >= 3)
                        {
                            string tField = tColumn.ColumnName;
                            string tFormatter = null;
                            short tWidth = System.Convert.ToInt16(tValue[1]);
    
                            if (!string.IsNullOrEmpty(tValue[2]))
                                tFormatter = tValue[2];
                            string tHCSS = tValue.Length > 3 ? tValue[3] : string.Empty;
                            string tCSS = tValue.Length > 4 ? tValue[4] : tHCSS;
    
                            tColumns.Add(new SlickGrid.cColumn
                            {
                                id = tColumn.ColumnName,
                                name = tField,
                                field = tColumn.ColumnName,
                                formatter = tFormatter,
                                sortable = true,
                                maxWidth = tWidth,
                                width = tWidth,
                                cssClass = tCSS,
                                headerCssClass = tHCSS
                            });
                        }
                    }
                }
    
                return tColumns;
            }
    
    
            public static System.Collections.Generic.List<SlickGrid.cColumn> dataToColumnsAny(System.Data.DataTable pData)
            {
                System.Collections.Generic.List<SlickGrid.cColumn> tColumns = new System.Collections.Generic.List<SlickGrid.cColumn>();
                foreach (System.Data.DataColumn tColumn in pData.Columns)
                {
                    string[] tValue = tColumn.Caption.Split(';');
    
                    if (!tColumn.ColumnName.StartsWith("x_") && tValue.Length >= 3)
                    {
                        tColumn.ColumnName = tValue[0];
    
                        if (tColumn.ColumnName.StartsWith("r_"))
                        {
                            if (pData.Rows.Count == 0 || (pData.Rows.Count > 0 && pData.Rows[0].IsNull(tColumn) ))
                            {
                                continue;
                            }
                            else
                            {
                                tColumn.ColumnName = tValue[0].Substring(2);
                            }
                        }
    
                        string tFormatter = null;
                        short tWidth = System.Convert.ToInt16(tValue[1]);
                        short tMinWidth = 30;
                        string tV = tValue.Length > 5 ? tValue[5] : string.Empty;
    
                        int bla;
                        if (int.TryParse(tV, out bla))
                            tMinWidth = System.Convert.ToInt16(tV);
    
                        if (!string.IsNullOrEmpty(tValue[2]))
                            tFormatter = tValue[2];
    
                        string tHCSS = tValue.Length > 3 ? tValue[3] : string.Empty;
                        string tCSS = tValue.Length > 4 ? tValue[4] : tHCSS;
                        string tTooltip = tValue.Length > 6 ? tValue[6] : string.Empty;
    
                        tColumns.Add(new SlickGrid.cColumn
                        {
                            id = tColumn.ColumnName,
                            name = tColumn.ColumnName,
                            field = tColumn.ColumnName,
                            formatter = tFormatter,
                            sortable = true,
                            minWidth = tMinWidth,
                            maxWidth = tWidth,
                            width = tWidth,
                            cssClass = tCSS,
                            headerCssClass = tHCSS,
                            toolTip = tTooltip
                        });
                    }
                }
    
                return tColumns;
            }
    
            public static string toJSON(System.Data.DataTable pData
                , System.Collections.Generic.List<JQuery.Plugins.SlickGrid.cColumn> pColumns
                , string pLanguage = "en")
            {
                cSlickGrid tGrid = new cSlickGrid(pLanguage, pData, pColumns);
    
                return Serialize(tGrid);
            }
    
            public static string toJSON(System.Data.DataTable pData, System.Data.DataTable pHeader, string pLanguageField, string pLanguage = "en")
            {
                RLExtends.translateHeader(pData, pHeader, pLanguageField);
                System.Collections.Generic.List<JQuery.Plugins.SlickGrid.cColumn> tColumns = RLExtends.dataToColumns(pData);
    
                return RLExtends.toJSON(pData, tColumns);
            }
    
    
            public static string Serialize(object obj)
            {
                return Newtonsoft.Json.JsonConvert.SerializeObject(obj);
            }
    
        }
    
    
    } // End Namespace jQuery.SlickGrid 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-07-12
      • 2012-11-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-26
      • 1970-01-01
      • 2014-12-12
      相关资源
      最近更新 更多