如何使用字符串参数来区分命名空间或类型?
我需要在 .NET 2.0 C# 脚本中获取一些 JSON 输出。目标是使用一种方法来输出我需要的所有 JSON 提要。所有模型都具有相同的 id 和 name 属性,因此我有大约 15 个具有相同部分的命名空间。简而言之:因为我使用 castle,所以我可以调用如下函数:
/public/get_place_tags.castle
/public/get_place_types.castle
/public/get_place_whichEver.castle
castle 中的哪个函数正在调用每个方法,即: get_place_tags(){}
但我不想在我能做的地方工作调用一种方法来获取每种类型的输出,如下所示:
/public/get_json.castle?wantedtype=place_types
有人知道如何解决这个问题吗?
namespace campusMap.Controllers
{
[Layout("home")]
public class PublicController : BaseController
{
/* works and returns */
public void get_pace_type()
{
CancelView();
CancelLayout();
place_types[] types = ActiveRecordBase<place_types>.FindAll();
List<JsonAutoComplete> type_list = new List<JsonAutoComplete>();
foreach (place_types place_type in types)
{
JsonAutoComplete obj = new JsonAutoComplete();
obj.id = place_type.place_type_id;
obj.label = place_type.name;
obj.value = place_type.name;
type_list.Add(obj);
}
string json = JsonConvert.SerializeObject(type_list);
RenderText(json);
}
/* can;t ever find the namespace */
public void get_json(string wantedtype)
{
CancelView();
CancelLayout();
Type t = Type.GetType(wantedtype);
t[] all_tag = ActiveRecordBase<t>.FindAll();
List<JsonAutoComplete> tag_list = new List<JsonAutoComplete>();
foreach (t tag in all_tag)
{
JsonAutoComplete obj = new JsonAutoComplete();
obj.id = tag.id;
obj.label = tag.name;
obj.value = tag.name;
tag_list.Add(obj);
}
string json = JsonConvert.SerializeObject(tag_list);
RenderText(json);
}
}
}
[编辑]--(最新想法)运行时类型创建..我认为这是使其发挥作用的最简洁的想法...-----
所以目标实际上是在运行时使用了一种类型..对..所以我认为这会起作用。 http://www.java2s.com/Code/CSharp/Development-Class /说明runtimetypecreation.htm 到目前为止,这是基于此的方法。我在获取 t
克服错误时仍然遇到问题 “无法找到类型或命名空间名称“t”(您是否缺少 using 指令或程序集引用?)”.. 不确定我在哪里出错了。似乎无法让其中任何一个工作哈哈..
public void get_json(String TYPE)
{
CancelView();
CancelLayout();
if (String.IsNullOrEmpty(TYPE))
{
TYPE = "place_types";
}
// get the current appdomain
AppDomain ad = AppDomain.CurrentDomain;
// create a new dynamic assembly
AssemblyName an = new AssemblyName();
an.Name = "DynamicRandomAssembly";
AssemblyBuilder ab = ad.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run);
// create a new module to hold code in the assembly
ModuleBuilder mb = ab.DefineDynamicModule("RandomModule");
// create a type in the module
TypeBuilder tb = mb.DefineType(TYPE, TypeAttributes.Public);
// finish creating the type and make it available
Type t = tb.CreateType();
t[] all_tag = ActiveRecordBase<t>.FindAll();
List<JsonAutoComplete> tag_list = new List<JsonAutoComplete>();
foreach (t tag in all_tag)
{
JsonAutoComplete obj = new JsonAutoComplete();
obj.id = tag.id;
obj.label = tag.name;
obj.value = tag.name;
tag_list.Add(obj);
}
RenderText(JsonConvert.SerializeObject(tag_list));
}
[编辑]--(旧的想法)Eval代码-----
所以这种实现这一点的尝试是使用反射和东西基于此进行某种评估 http://www.codeproject.com/script/Articles/ViewDownloads.aspx?aid=11939
namespace EvalCSCode
{
/// <summary>
/// Interface that can be run over the remote AppDomain boundary.
/// </summary>
public interface IRemoteInterface
{
object Invoke(string lcMethod, object[] Parameters);
}
/// <summary>
/// Factory class to create objects exposing IRemoteInterface
/// </summary>
public class RemoteLoaderFactory : MarshalByRefObject
{
private const BindingFlags bfi = BindingFlags.Instance | BindingFlags.Public | BindingFlags.CreateInstance;
public RemoteLoaderFactory() { }
/// <summary> Factory method to create an instance of the type whose name is specified,
/// using the named assembly file and the constructor that best matches the specified parameters. </summary>
/// <param name="assemblyFile"> The name of a file that contains an assembly where the type named typeName is sought. </param>
/// <param name="typeName"> The name of the preferred type. </param>
/// <param name="constructArgs"> An array of arguments that match in number, order, and type the parameters of the constructor to invoke, or null for default constructor. </param>
/// <returns> The return value is the created object represented as ILiveInterface. </returns>
public IRemoteInterface Create(string assemblyFile, string typeName, object[] constructArgs)
{
return (IRemoteInterface)Activator.CreateInstanceFrom(
assemblyFile, typeName, false, bfi, null, constructArgs,
null, null, null).Unwrap();
}
}
}
#endregion
namespace campusMap.Controllers
{
public class JsonAutoComplete
{
private int Id;
[JsonProperty]
public int id
{
get { return Id; }
set { Id = value; }
}
private string Label;
[JsonProperty]
public string label
{
get { return Label; }
set { Label = value; }
}
private string Value;
[JsonProperty]
public string value
{
get { return Value; }
set { Value = value; }
}
}
[Layout("home")]
public class publicController : BaseController
{
#region JSON OUTPUT
/* works and returns */
public void get_pace_type()
{
CancelView();
CancelLayout();
place_types[] types = ActiveRecordBase<place_types>.FindAll();
List<JsonAutoComplete> type_list = new List<JsonAutoComplete>();
foreach (place_types place_type in types)
{
JsonAutoComplete obj = new JsonAutoComplete();
obj.id = place_type.id;
obj.label = place_type.name;
obj.value = place_type.name;
type_list.Add(obj);
}
string json = JsonConvert.SerializeObject(type_list);
RenderText(json);
}
/* how I think it'll work to have a dynmaic type */
public void get_json(string type)
{
CancelView();
CancelLayout();
/*t[] all_tag = ActiveRecordBase<t>.FindAll();
List<JsonAutoComplete> tag_list = new List<JsonAutoComplete>();
foreach (t tag in all_tag)
{
JsonAutoComplete obj = new JsonAutoComplete();
obj.id = tag.id;
obj.label = tag.name;
obj.value = tag.name;
tag_list.Add(obj);
}*/
StringBuilder jsonobj = new StringBuilder("");
jsonobj.Append(""+type+"[] all_tag = ActiveRecordBase<"+type+">.FindAll();\n");
jsonobj.Append("List<JsonAutoComplete> tag_list = new List<JsonAutoComplete>();{\n");
jsonobj.Append("foreach ("+type+" tag in all_tag){\n");
jsonobj.Append("JsonAutoComplete obj = new JsonAutoComplete();\n");
jsonobj.Append("obj.id = tag.id;\n");
jsonobj.Append("obj.label = tag.name;\n");
jsonobj.Append("obj.value = tag.name;\n");
jsonobj.Append("tag_list.Add(obj);\n");
jsonobj.Append("}\n");
CSharpCodeProvider c = new CSharpCodeProvider();
ICodeCompiler icc = c.CreateCompiler();
CompilerParameters cp = new CompilerParameters();
cp.ReferencedAssemblies.Add("system.dll");
cp.ReferencedAssemblies.Add("Newtonsoft.Json.Net20.dll");
cp.ReferencedAssemblies.Add("Castle.ActiveRecord.dll");
cp.CompilerOptions = "/t:library";
cp.GenerateInMemory = true;
StringBuilder sb = new StringBuilder("");
sb.Append("namespace CSCodeEvaler{ \n");
sb.Append("public class CSCodeEvaler{ \n");
sb.Append("public object EvalCode(){\n");
sb.Append("return " + jsonobj + "; \n");
sb.Append("} \n");
sb.Append("} \n");
sb.Append("}\n");
CompilerResults cr = icc.CompileAssemblyFromSource(cp, sb.ToString());
System.Reflection.Assembly a = cr.CompiledAssembly;
object o = a.CreateInstance("CSCodeEvaler.CSCodeEvaler");
Type t = o.GetType();
MethodInfo mi = t.GetMethod("EvalCode");
object s = mi.Invoke(o, null);
string json = JsonConvert.SerializeObject(s);
RenderText(json);
}/**/
#endregion
}
我知道有人建议不需要使用..我知道我不需要从顶部了解它们,也许这就是水平展示。但在这里,它们是为了我认为在上面起作用的。
using System;
using System.Collections;
using System.Collections.Generic;
using Castle.ActiveRecord;
using Castle.ActiveRecord.Queries;
using Castle.MonoRail.Framework;
using Castle.MonoRail.ActiveRecordSupport;
using campusMap.Models;
using MonoRailHelper;
using System.IO;
using System.Net;
using System.Web;
using NHibernate.Expression;
using System.Xml;
using System.Xml.XPath;
using System.Text.RegularExpressions;
using System.Text;
using System.Net.Sockets;
using System.Web.Mail;
using campusMap.Services;
using Newtonsoft.Json;
using Newtonsoft.Json.Utilities;
using Newtonsoft.Json.Linq;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Reflection;
using Microsoft.CSharp;
using System.Reflection.Emit;
using System.Runtime.InteropServices;
using System.Runtime.Remoting;
using System.IO;
using System.Threading;
using System.Reflection;
I need to get some JSON output in a .NET 2.0 C# script. The goal is to use one method to output all the JSON feeds I need. All the models have the same id and name properties so I have about 15 namespaces that have the same parts here. In short: since I'm use castle I can call the function like:
/public/get_place_tags.castle
/public/get_place_types.castle
/public/get_place_whichEver.castle
Which in castle is calling each method, ie: the get_place_tags(){}
but I want to not have to work where I can call one method to get output from each type like this:
/public/get_json.castle?wantedtype=place_types
Does anyone know how to fix this?
namespace campusMap.Controllers
{
[Layout("home")]
public class PublicController : BaseController
{
/* works and returns */
public void get_pace_type()
{
CancelView();
CancelLayout();
place_types[] types = ActiveRecordBase<place_types>.FindAll();
List<JsonAutoComplete> type_list = new List<JsonAutoComplete>();
foreach (place_types place_type in types)
{
JsonAutoComplete obj = new JsonAutoComplete();
obj.id = place_type.place_type_id;
obj.label = place_type.name;
obj.value = place_type.name;
type_list.Add(obj);
}
string json = JsonConvert.SerializeObject(type_list);
RenderText(json);
}
/* can;t ever find the namespace */
public void get_json(string wantedtype)
{
CancelView();
CancelLayout();
Type t = Type.GetType(wantedtype);
t[] all_tag = ActiveRecordBase<t>.FindAll();
List<JsonAutoComplete> tag_list = new List<JsonAutoComplete>();
foreach (t tag in all_tag)
{
JsonAutoComplete obj = new JsonAutoComplete();
obj.id = tag.id;
obj.label = tag.name;
obj.value = tag.name;
tag_list.Add(obj);
}
string json = JsonConvert.SerializeObject(tag_list);
RenderText(json);
}
}
}
[EDIT]-- (Newest Idea) Runtime type creation.. This I think is the cleanest idea on a way to get it to work...-----
So the goal is really to have at runtime a type used.. right.. so I thought this would work.
http://www.java2s.com/Code/CSharp/Development-Class/Illustratesruntimetypecreation.htm
and based of that here is the method so far. I'm still having issues getting t
to get past the error
"The type or namespace name 't' could not be found (are you missing a using directive or an assembly reference?)" .. not sure where I'm going wrong here. Can't seem to get any of it to work lol..
public void get_json(String TYPE)
{
CancelView();
CancelLayout();
if (String.IsNullOrEmpty(TYPE))
{
TYPE = "place_types";
}
// get the current appdomain
AppDomain ad = AppDomain.CurrentDomain;
// create a new dynamic assembly
AssemblyName an = new AssemblyName();
an.Name = "DynamicRandomAssembly";
AssemblyBuilder ab = ad.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run);
// create a new module to hold code in the assembly
ModuleBuilder mb = ab.DefineDynamicModule("RandomModule");
// create a type in the module
TypeBuilder tb = mb.DefineType(TYPE, TypeAttributes.Public);
// finish creating the type and make it available
Type t = tb.CreateType();
t[] all_tag = ActiveRecordBase<t>.FindAll();
List<JsonAutoComplete> tag_list = new List<JsonAutoComplete>();
foreach (t tag in all_tag)
{
JsonAutoComplete obj = new JsonAutoComplete();
obj.id = tag.id;
obj.label = tag.name;
obj.value = tag.name;
tag_list.Add(obj);
}
RenderText(JsonConvert.SerializeObject(tag_list));
}
[EDIT]-- (Older idea) Eval code-----
So this attempt to make this happen is to use reflection and stuff to do a eval of sorts based on this http://www.codeproject.com/script/Articles/ViewDownloads.aspx?aid=11939
namespace EvalCSCode
{
/// <summary>
/// Interface that can be run over the remote AppDomain boundary.
/// </summary>
public interface IRemoteInterface
{
object Invoke(string lcMethod, object[] Parameters);
}
/// <summary>
/// Factory class to create objects exposing IRemoteInterface
/// </summary>
public class RemoteLoaderFactory : MarshalByRefObject
{
private const BindingFlags bfi = BindingFlags.Instance | BindingFlags.Public | BindingFlags.CreateInstance;
public RemoteLoaderFactory() { }
/// <summary> Factory method to create an instance of the type whose name is specified,
/// using the named assembly file and the constructor that best matches the specified parameters. </summary>
/// <param name="assemblyFile"> The name of a file that contains an assembly where the type named typeName is sought. </param>
/// <param name="typeName"> The name of the preferred type. </param>
/// <param name="constructArgs"> An array of arguments that match in number, order, and type the parameters of the constructor to invoke, or null for default constructor. </param>
/// <returns> The return value is the created object represented as ILiveInterface. </returns>
public IRemoteInterface Create(string assemblyFile, string typeName, object[] constructArgs)
{
return (IRemoteInterface)Activator.CreateInstanceFrom(
assemblyFile, typeName, false, bfi, null, constructArgs,
null, null, null).Unwrap();
}
}
}
#endregion
namespace campusMap.Controllers
{
public class JsonAutoComplete
{
private int Id;
[JsonProperty]
public int id
{
get { return Id; }
set { Id = value; }
}
private string Label;
[JsonProperty]
public string label
{
get { return Label; }
set { Label = value; }
}
private string Value;
[JsonProperty]
public string value
{
get { return Value; }
set { Value = value; }
}
}
[Layout("home")]
public class publicController : BaseController
{
#region JSON OUTPUT
/* works and returns */
public void get_pace_type()
{
CancelView();
CancelLayout();
place_types[] types = ActiveRecordBase<place_types>.FindAll();
List<JsonAutoComplete> type_list = new List<JsonAutoComplete>();
foreach (place_types place_type in types)
{
JsonAutoComplete obj = new JsonAutoComplete();
obj.id = place_type.id;
obj.label = place_type.name;
obj.value = place_type.name;
type_list.Add(obj);
}
string json = JsonConvert.SerializeObject(type_list);
RenderText(json);
}
/* how I think it'll work to have a dynmaic type */
public void get_json(string type)
{
CancelView();
CancelLayout();
/*t[] all_tag = ActiveRecordBase<t>.FindAll();
List<JsonAutoComplete> tag_list = new List<JsonAutoComplete>();
foreach (t tag in all_tag)
{
JsonAutoComplete obj = new JsonAutoComplete();
obj.id = tag.id;
obj.label = tag.name;
obj.value = tag.name;
tag_list.Add(obj);
}*/
StringBuilder jsonobj = new StringBuilder("");
jsonobj.Append(""+type+"[] all_tag = ActiveRecordBase<"+type+">.FindAll();\n");
jsonobj.Append("List<JsonAutoComplete> tag_list = new List<JsonAutoComplete>();{\n");
jsonobj.Append("foreach ("+type+" tag in all_tag){\n");
jsonobj.Append("JsonAutoComplete obj = new JsonAutoComplete();\n");
jsonobj.Append("obj.id = tag.id;\n");
jsonobj.Append("obj.label = tag.name;\n");
jsonobj.Append("obj.value = tag.name;\n");
jsonobj.Append("tag_list.Add(obj);\n");
jsonobj.Append("}\n");
CSharpCodeProvider c = new CSharpCodeProvider();
ICodeCompiler icc = c.CreateCompiler();
CompilerParameters cp = new CompilerParameters();
cp.ReferencedAssemblies.Add("system.dll");
cp.ReferencedAssemblies.Add("Newtonsoft.Json.Net20.dll");
cp.ReferencedAssemblies.Add("Castle.ActiveRecord.dll");
cp.CompilerOptions = "/t:library";
cp.GenerateInMemory = true;
StringBuilder sb = new StringBuilder("");
sb.Append("namespace CSCodeEvaler{ \n");
sb.Append("public class CSCodeEvaler{ \n");
sb.Append("public object EvalCode(){\n");
sb.Append("return " + jsonobj + "; \n");
sb.Append("} \n");
sb.Append("} \n");
sb.Append("}\n");
CompilerResults cr = icc.CompileAssemblyFromSource(cp, sb.ToString());
System.Reflection.Assembly a = cr.CompiledAssembly;
object o = a.CreateInstance("CSCodeEvaler.CSCodeEvaler");
Type t = o.GetType();
MethodInfo mi = t.GetMethod("EvalCode");
object s = mi.Invoke(o, null);
string json = JsonConvert.SerializeObject(s);
RenderText(json);
}/**/
#endregion
}
I know it was suggested that the using is not needed.. I know I don't know them off the top and maybe that is level showing.. But here they are for what I think will work just above.
using System;
using System.Collections;
using System.Collections.Generic;
using Castle.ActiveRecord;
using Castle.ActiveRecord.Queries;
using Castle.MonoRail.Framework;
using Castle.MonoRail.ActiveRecordSupport;
using campusMap.Models;
using MonoRailHelper;
using System.IO;
using System.Net;
using System.Web;
using NHibernate.Expression;
using System.Xml;
using System.Xml.XPath;
using System.Text.RegularExpressions;
using System.Text;
using System.Net.Sockets;
using System.Web.Mail;
using campusMap.Services;
using Newtonsoft.Json;
using Newtonsoft.Json.Utilities;
using Newtonsoft.Json.Linq;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Reflection;
using Microsoft.CSharp;
using System.Reflection.Emit;
using System.Runtime.InteropServices;
using System.Runtime.Remoting;
using System.IO;
using System.Threading;
using System.Reflection;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
好吧,这只是一个建议,我对城堡一无所知,但在我看来,你想要一条自定义路线。
这是未经测试的,当然你必须调整它,但看看你的 Global.asax RegisterRoutes 方法并将其添加到你的默认路由之上,
这样的东西可能会得到你想要的东西。
你可能需要摆弄动作,使其与你的城堡框架相匹配
编辑
我有更多的时间来看看这个。使用我上面描述的路线和控制器上的以下方法,我得到了一个很好的结果
http://... /Public/System.Int32 有效,
此网址不起作用 http://.../Public/Int32
现在如果您想使用在简短版本中,您可以使用 MEF 或 AutoFAC 或 Castle 等工具在容器中查找所需的类型。
所以我的答案是使用一个好的途径来获取所需类型的密钥,然后构建一个工厂来管理类型映射并生成您想要的实例。
OK, this is just a suggestion, and I know nothing about castle but it seems to me that you are wanting a custom route.
This is untested and of course you will have to tweak it but have a look at your Global.asax RegisterRoutes method and add this above you default route
something like this might get what you are after.
you might need to fiddle with the action so it matches your castle framework
EDIT
I had some more time to look at this. Using the route I described above and the following method on the controller I got a good result
http://.../Public/System.Int32 works,
this url doesn't work http://.../Public/Int32
Now if you wanted to use the short version you could use something like MEF or AutoFAC or Castle to do a lookup in your container for the type you are after.
So my answer is use a good route to get the key for the wanted type then build a factory to manage the type mappings and produce an instance of what you are after.
我刚刚查看了 ActiveRecord API Doco此处
有一种方法 FindAll(Type targetType) : Array
您是否尝试
用
完全未经测试的替换,但看看您的想法
I just had a look at the ActiveRecord API Doco Here
There is a method FindAll(Type targetType) : Array
have you tried replacing
with
completely untested but see what you think
我厌倦了、尝试过、厌倦了其中一种方式。我和一位同事想出了解决方案。我做了2个文件。
Ijson_autocomplete.cs
json_autocomplete.cs
然后,当我从 url 调用该函数时,这就是它最终的结果,
现在
当您调用
或时,
您将获得每个模型的 json 输出。田田! :D 谢谢大家的帮助。
I tired and tried and tired to so one of these ways. Me and an co-worker came up this with solution. I made 2 files.
Ijson_autocomplete.cs
json_autocomplete.cs
then when I called the function from the url this is what it ended up as
and one off the models
now when you call
or
You will get the json output of each model. Tada! :D Thank you everyone for helping.