2011-11-30 13 views
9

Potrzebuję uzyskać niektóre dane wyjściowe JSON w skrypcie .NET 2.0 C#. Celem jest użycie jednej metody do wyprowadzenia wszystkich potrzebnych kanałów JSON. Wszystkie modele mają te same właściwości identyfikatora i nazwy, więc mam około 15 obszarów nazw, które mają tutaj te same części. W skrócie: ponieważ jestem użycie zamek mogę wywołać funkcję tak:Jak używać argumentu łańcuchowego do zapisania w przestrzeni nazw lub typu?

/public/get_place_tags.castle 
/public/get_place_types.castle 
/public/get_place_whichEver.castle 

Które w zamku dzwoni każdej metody IE: get_place_tags(){} ale chcę, aby nie musiał pracować, gdzie mogę zadzwonić do jednej metody uzyskać dane wyjściowe z każdego typu, jak to:

/public/get_json.castle?wantedtype=place_types 

Czy ktoś wie, jak to naprawić?

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] - (Najnowszy pomysł) tworzenie typ Runtime .. To moim zdaniem jest najczystszym pomysł na sposób, aby zmusić go do pracy ...-----

Tak więc celem jest posiadanie w środowisku uruchomieniowym typu używanego .. prawda ... więc myślałem, że to zadziała. http://www.java2s.com/Code/CSharp/Development-Class/Illustratesruntimetypecreation.htm i na podstawie tej metody jest jak dotąd. Nadal mam problemy z uzyskaniem t, aby ominąć błąd "Nie można znaleźć nazwy typu lub przestrzeni nazw" t "(czy brakuje instrukcji użycia lub odniesienia do zespołu?)" .. nie wiem, dokąd zmierzam źle tutaj. nie wydaje się uzyskać żadnego z nim pracować 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 pomysł) Kod Eval -----

Więc to próba aby tak się stało jest użycie refleksji i rzeczy zrobić eval sortuje na podstawie tego 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 
    } 

wiem, że sugerowano, że za pomocą nie jest potrzebna .. wiem, nie znam ich od szczytu i może to jest na poziomie pokazującym .. Ale tutaj są one dla tego, co moim zdaniem zadziała powyżej.

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; 
+1

Proszę zaksięgować tylko odpowiedni kod. "Używanie" jest bezużyteczne dla osób próbujących ci pomóc. – Otiel

+0

Jak przekonać ludzi, aby to zobaczyli? –

+3

Zobacz [faq] (http://stackoverflow.com/faq#bounty). – Otiel

Odpowiedz

0

Zmęczony i zmęczony na tak jeden z tych sposobów. Ja i współpracownik wpadliśmy na to z rozwiązaniem. Zrobiłem 2 pliki.

Ijson_autocomplete.cs

using System; 
namespace campusMap.Models 
{ 
    public interface Ijson_autocomplete 
    { 
     int id { get; set; } 
     string name { get; set; } 
     String get_json_data(); 
    } 
} 

json_autocomplete.cs

using System; 
using System.Data; 
using System.Configuration; 
using System.Web; 
using System.Web.Security; 
using System.Web.UI; 
using System.Web.UI.WebControls; 
using System.Web.UI.WebControls.WebParts; 
using System.Web.UI.HtmlControls; 
using Castle.ActiveRecord; 
using System.Collections.Generic; 
using System.Data.SqlTypes; 
using Newtonsoft.Json; 
using Newtonsoft.Json.Utilities; 
using Newtonsoft.Json.Linq; 



namespace campusMap.Models 
{ 

    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; } 
     } 
    } 
    public class json_autocomplete<t> where t : campusMap.Models.Ijson_autocomplete 
    { 

     virtual public String get_json_data() 
     { 
      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); 
      } 
      return JsonConvert.SerializeObject(tag_list); 
     } 
    } 
} 

wtedy gdy zadzwoniłem funkcję z URL, co skończyło się jak

 public void get_json(String TYPE) 
     { 
      CancelView(); 
      CancelLayout(); 
      Type t = Type.GetType("campusMap.Models."+TYPE); 
      Ijson_autocomplete theclass = (Ijson_autocomplete)Activator.CreateInstance(t); 
      RenderText(theclass.get_json_data()); 
     } 

i jednorazowe modele

namespace campusMap.Models 
{ 
    [ActiveRecord(Lazy=true)] 
    public class place_types : json_autocomplete<place_types>, campusMap.Models.Ijson_autocomplete 
    { 
     private int place_type_id; 
     [PrimaryKey("place_type_id")] 
     virtual public int id 
     { 
      get { return place_type_id; } 
      set { place_type_id = value; } 
     } 

     private string Name; 
     [Property] 
     virtual public string name 
     { 
      get { return Name; } 
      set { Name = value; } 
     } 

     private string Attr; 
     [Property] 
     virtual public string attr 
     { 
      get { return Attr; } 
      set { Attr = value; } 
     } 
     private IList<place> places; 
     [HasAndBelongsToMany(typeof(place), Lazy = true, Table = "place_to_place_models", ColumnKey = "place_model_id", ColumnRef = "place_id", Inverse = true, NotFoundBehaviour = NotFoundBehaviour.Ignore)] 
     virtual public IList<place> Places 
     { 
      get { return places; } 
      set { places = value; } 
     } 

    } 
} 

teraz kiedy zadzwonić

/public/get_json.castle?wantedtype=place_types 

lub

/public/get_json.castle?wantedtype=place_tags 

Dostaniesz wyjście json każdego modelu. Tada! : D Dziękuję wszystkim za pomoc.

1

OK, to tylko sugestia, a ja nic nie wiem o zamku, ale wydaje mi się, że szukasz niestandardowej trasy.

To niesprawdzone i oczywiście trzeba będzie go podkręcić ale przyjrzeć się swojej metody Global.asax RegisterRoutes i dodać ten nad wami trasa domyślna

 routes.MapRoute(
      "TypeRoute", // Route name 
      "Public/{wantedtype}", // URL with parameters 
      new { controller = "Public", action = "get_json", wantedtype = UrlParameter.Optional } // Parameter defaults 
     ); 

coś takiego może dostać to, czego po .

może trzeba pobawić się z działaniem, dlatego pasuje do ram zamek

EDIT

miałem trochę więcej czasu, aby spojrzeć na to.Korzystanie z trasą opisałem powyżej i następującą metodę na kontrolerze mam dobry wynik

public void get_json(string wantedtype) 
    { 
     Type t = Type.GetType(wantedtype); 
     // t.Name = "Int32" when "System.Int32 is used as the wanted type 
    } 

http://.../Public/System.Int32 prace, Ten adres URL nie działa http://.../Public/Int32

Teraz, jeśli chciał wykorzystać krótką wersję ty może użyć czegoś takiego jak MEF lub AutoFAC lub Castle, aby wykonać wyszukiwanie w swoim kontenerze dla typu, którego szukasz.

Moja odpowiedź brzmi: użyj dobrej trasy, aby zdobyć klucz do poszukiwanego typu, a następnie zbuduj fabrykę, która będzie zarządzać mapowaniem typów i wygenerować instancję tego, co chcesz.

+0

Przepraszam, ale myślę, że jesteś daleko .. Nie chcę niestandardowej trasy URL, do której chcę użyć argumentu typu string, aby stworzyć przestrzeń nazw lub typ, jak mówi tytuł. Upraszczając, potrzebuję dynamicznego typu w C# .net 2.0. Dziękuję za próbę. –

+0

Zrobiłem małą makietę i udało mi się uzyskać System.Int32 z kodu, który dodałem do mojej oryginalnej sugestii – Peter

+0

caslte już obsługuje trasę, jak pokazano w powyższym kodzie, więc nie jest to konieczne. Zauważysz, że nie przeszedł System.Int32 ani żadnej innej FullyQuailfiedName, tak jak w oryginalnym kodzie, w którym skończyłeś z tym samym kodem, o którym mówiłem, że nie działa. Jeśli możesz pokazać przykład, gdzie jest to pożądany typ == tj. Kończący się na jako typ t jest równy arg wantedtype, pozwalając na ruch aktywnyrecord przez wpisany obiekt, więc foreach (place_types typ_lokalny w typach) działa. Ponieważ pierwsza metoda jest wyświetlana, działa, po prostu muszę sprawić, że będzie dynamiczny. Mam nadzieję, że to wyczyści. –

1

miałem tylko spojrzeć na ActiveRecord API Doco Here

istnieje metoda FindAll (typ TargetType): Array

próbowałeś zastępując

Type t = Type.GetType(wantedtype); 
t[] all_tag = ActiveRecordBase<t>.FindAll(); 
// blah blah blah 

z

Type t = Type.GetType(wantedtype); 
dynamic all_tag = ActiveRecordBase.FindAll(t); 
RenderText(JsonConvert.SerializeObject(all_tag)); 

całkowicie nietestowany, ale zobacz co myślisz

+0

um .. Nie jestem tutaj w 100%, ale nie sądzę, żeby kamera dynamiczna się skończyła do 3.5, a to 2.0 .. Spróbuję tk. -J –

+0

Myślę, że ważnym bitem jest użycie ActiveRecordBase.FindAll (t); a jeśli dynamiczne nie działa, użyj var all_tag = ActiveRecordBase.FindAll (t); również powinieneś rozważyć uaktualnienie do .net 4 jeśli w ogóle możliwe – Peter

+0

: D hmm przepraszam, ale uaktualnienie do 4.0+ się nie dzieje, a ActiveRecordBase.FindAll() jest tym, co tworzy obiekt przez bazę danych. który powinien wyjaśnić błąd w ActiveRecordBase.FindAll (t) "Error 79" Castle.ActiveRecord.ActiveRecordBase.FindAll (Typ systemu, NHibernate.Expression.DetachedCriteria, params NHibernate.Expression.Order []) "jest niedostępny z powodu poziom ochrony "również dla dynamicznej otrzymuję oczekiwany błąd również z" Błąd 78 Nie można znaleźć typu lub przestrzeni nazw "dynamic" (czy brakuje instrukcji użycia lub odniesienia do zespołu?) ".. –

Powiązane problemy