1

次のような静的なネストされたクラスのセットが与えられます。

public static class LocalSiteMap
{
    public static class Navigation
    {
        public static readonly string Home = "homePage";

        public static class PageIds
        {
            public static class ShowManagement
            {
                public static readonly string Index = "showManagement";
            }

            public static class Shows
            { 
                public static readonly string Create = "addShows";
            }
        }

        public static class Actors
        {
            public static readonly string Details = "actorDetailsForm";
            public static readonly string History= "historyDetailsForm";
        }
    }
}

次のような同等のJSON文字列を作成したいと思います。

{ 'localSiteMap' : {
    { 'navigation': {
        'home': 'homePage',
        'pageIds': {
            'showManagement': {
                'index': 'showManagement'
            },
            'shows': {
                'create': 'addShows'
            }
        },
        'actors': {
            'details': 'actorDetailsForm',
            'history': 'historyDetailsForm'
        }
    }
}

ネストされた各クラスは、JSONにネストされたオブジェクトになります。各文字列プロパティは、JSONで文字列のキーと値のペアになります。

ルートの静的クラスを反映してJSON文字列を非常に簡単に構築できることは知っていますが(これが現在採用しているアプローチです)、もっと洗練された方法があるのではないかと思いました。たとえば、これがインスタンスの匿名型である場合、非常に簡単にシリアル化できます。

背景:これは、WebAPIコントローラーを介してブラウザーで実行されているシングルページアプリケーションに渡される定数のセットです。C#(サーバー)とJS(クライアント)の両方の世界で同じページ識別子のセットを使用できると、ページオブジェクトパターンを使用するブラウザー自動化テストに非常に役立ちます。

'LocalSiteMap'静的クラスはすでにかなり成熟したプロジェクトに組み込まれているため、代わりにインスタンスクラスまたは匿名型に変更することは私にとって実際のオプションではありません。

4

1 に答える 1

0

ここで文字列を作成する際の問題は、構文が100%正しいこと、中括弧の開閉、コンマの追加などを確認する必要があることです。すべて可能ですが、かなり面倒です。

マジックストリングを完全に回避するための解決策は、中間の変換ステップとしてLINQ-to-XMLを使用することです。このような:

public static class NestedStaticClassWithStringPropertiesJsoniser
{
    public static string GetJson(this Type type)
    {
        XElement rootXml = new XElement(type.Name);
        XElement xmlContent = CreateXmlTree(rootXml, type);

        string jsonString = JsonConvert.SerializeXNode(xmlContent);

        return jsonString;
    }

    public static XElement CreateXmlTree(XElement parent, Type type)
    {
        AddStringProperties(parent, type);

        AddNestedClasses(parent, type);

        return parent;
    }

    private static void AddNestedClasses(XElement parent, Type type)
    {
        var subTypes = type.GetNestedTypes();

        foreach (var subType in subTypes)
        {
            var newElement = new XElement(subType.Name);
            var subTree = CreateXmlTree(newElement, subType);
            parent.Add(subTree);
        }
    }

    private static void AddStringProperties(XElement parent, Type type)
    {
        var properties = type.GetFields();
        foreach (var property in properties)
        {
            var propertyElement = new XElement(property.Name);
            propertyElement.SetValue(property.GetValue(null));
            parent.Add(propertyElement);
        }
    }
}

次のように簡単に使用できます。

string json = typeof(ATypeWithNestedStaticClasses).GetJson();
于 2013-01-29T17:40:39.903 に答える