从string中的属性创建对象

时间:2016-01-30 20:08:04

标签: c# json asp.net-mvc razor expandoobject

应该创建具有来自类似json的表示法字符串的附加属性的对象。 方法将从Razor视图调用以将colmodel传递给jqgrid 像json对象一样

@Html.Raw( Json.Encode( Model.GetColModel()))

方法应该有像

这样的签名
object GetColModel(string colName, int colWidth, string additonalProperties)

例如,

GetColModel("customer", 17, "address=\"Toronto\", index=1555" )

应返回对象

new { colName="customer", colwidth=17, address="Toronto", index=1555 }

可能存在嵌套属性,例如JSON,eq。

GetColModel("customer", 17, "formatoptions= new { formatter=\"number\", editable=true } " )

应返回对象

new { colName="customer", colwidth=17, formatoptions=new {
                   formatter="number", 
                   editable=true
                   }
}

我试过方法

    public object GetColModel(string colName, int colWidth, string additonalProperties)
    {
        return new
        {
            name = colName,
            width = colWidth,
            &addtitionalProperties
        };
    }

但由于C#

不支持宏,因此失败

如何创建这样的方法或其他方法将数据库中的属性添加到R​​azor视图中的json中?

从ASP.NET/Mono C#MVC 4 viewmodel调用它。 使用Razor视图和RazorEngine。

2 个答案:

答案 0 :(得分:0)

没有内置任何内容可以执行此操作,但是您使用字符串解析字符串(string.Split将允许您拆分','但如果您的文本中可能包含那些,则必须构建一个真正的解析器,或者将字符串格式转换为类似CSV的格式,您可以在其中找到许多解析器。您可以找到一个简单语法的属性解析器。或者将您的附加属性字符串作为json推送并使用Json.net进行解析。

将字符串解析为键/值结构后,可以使用ExpandoObject填充最终对象并返回。
https://msdn.microsoft.com/en-us/library/system.dynamic.expandoobject(v=vs.110).aspx

答案 1 :(得分:0)

这是一个真正的基于json的解决方案的简单实现 您可以使用以下方式调用它:

static class ModelExtension
{   
    public static dynamic GetColModel(this Model model, string colName, int colWidth, string additonalProperties) {
        dynamic expando = new ExpandoObject();
        var json = JsonConvert.DeserializeObject<JObject>(additonalProperties);

        expando.name = colName;
        expando.width = colWidth;

        return new FromPropertiesDynamicObjectCreator(expando, json);
    }

    private class FromPropertiesDynamicObjectCreator : DynamicObject
    {
        private readonly dynamic expando = null;

        public FromPropertiesDynamicObjectCreator(IDictionary<string, object> expando, JObject props = null) {
            this.expando = expando;

            if (props != null) {
                ((dynamic)this).props = props;
            }
        }

        public override bool TrySetMember(SetMemberBinder binder, object value) {
            if (binder.Name.Equals("props")) {
                var jsonObj = value as JObject;
                JToken current = jsonObj.First;
                var dictionary = expando as IDictionary<string, object>;

                RecurseJson(current, dictionary);
                return true;
            }

            return false;
        }

        private void RecurseJson(JToken current, IDictionary<string, object> dictionary) {
            JToken value;
            Dictionary<string, object> newDictionary;

            while (current != null) {
                var children = current.Children().ToList();

                foreach (var child in children) {
                    switch (child.Type) {

                        case JTokenType.Object:
                        case JTokenType.Array:
                            newDictionary = new Dictionary<string, object>();
                            dictionary[child.Path] = newDictionary;
                            RecurseJson(child, newDictionary);
                            break;

                        case JTokenType.Property:
                            var prop = ((JProperty)child);
                            value = prop.Value;

                            if (value.HasValues) {
                                newDictionary = new Dictionary<string, object>();
                                dictionary[prop.Name] = newDictionary;
                                RecurseJson(child, newDictionary);
                                break;
                            }
                            dictionary[prop.Name] = ((dynamic)value).Value;
                            break;

                        default:
                            var val = ((dynamic)child).Value;

                            if (val is JToken) {
                                dictionary[child.Path] = val.Value;
                            }
                            else {
                                dictionary[child.Path] = val;
                            }

                            break;
                    }
                }

                current = current.Next;
            }
        }

        public override bool TryGetMember(GetMemberBinder binder, out object result) {
            object value;
            var dictionary = expando as IDictionary<string, object>;

            if (dictionary.TryGetValue(binder.Name, out value)) {
                var innerDictionary = value as IDictionary<string, object>;

                if (innerDictionary != null) {
                    result = new FromPropertiesDynamicObjectCreator(innerDictionary);
                }
                else {
                    result = value;
                }
                return true;
            }

            result = null;
            return true;
        }
    }
}

实现:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    if ([segue.identifier isEqualToString:@"showLogin"]) {
        [segue.destinationViewController setHidesBottomBarWhenPushed:YES];
    } else {
        [segue.identifier isEqualToString:@"showImage"];
        [segue.destinationViewController setHidesBottomBarWhenPushed:YES];
        ImageViewController *imageViewController = (ImageViewController *)segue.destinationViewController;
        imageViewController.message = self.selectedMessage;
    }
}
相关问题