servicestack用函数序列化为json

时间:2014-08-18 21:18:39

标签: json servicestack-text

我有一个c#helper类声明了一个包含javascript函数名的javascript组件。

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

这应该创建一个json文本:

{ label = "Execute", onClick = ExecuteFunction}

(其中 ExecuteFunction 是一个javascript函数)

使用servicestack-text到json可以吗?

2 个答案:

答案 0 :(得分:1)

任何JSON序列化程序都无法做到这一点,因为这不是valid JSON

{ label = "Execute", onClick = ExecuteFunction}

最接近的有效JSON是:

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

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

答案 1 :(得分:0)

您可以使用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