Web hizmeti aracılığıyla bir özel nesne isim / değer çiftleri Dizgeleştirme

5 Cevap

Bu veriler değil-güçlü yazılmış bir web hizmeti çağrısı yoluyla veri seri hale getirmek için nasıl ilgili çok karmaşık bir soru. Ben mümkün olduğunca en iyi ortaya koymak için çalışacağım.

Sample Storage Object:

[Serializable]
public class StorageObject {
  public string Name { get; set; }
  public string Birthday { get; set; }
  public List<NameValuePairs> OtherInfo { get; set; }  
}
[Serializable]   
public class NameValuePairs {
  public string Name { get; set; }
  public string Value { get; set; }
}

Sample Use:

[WebMethod]
    public List<StorageObject> GetStorageObjects() {
      List<StorageObject> o = new List<StorageObject>() {
        new StorageObject() { 
          Name = "Matthew",
          Birthday = "Jan 1st, 2008", 
          OtherInfo = new List<NameValuePairs>() {
            new NameValuePairs() { Name = "Hobbies", Value = "Programming" },
            new NameValuePairs() { Name = "Website", Value = "Stackoverflow.com" }
          }
        },
        new StorageObject() { 
          Name = "Joe",
          Birthday = "Jan 10th, 2008",
          OtherInfo = new List<NameValuePairs>() { 
            new NameValuePairs() { Name = "Hobbies", Value = "Programming" },
            new NameValuePairs() { Name = "Website", Value = "Stackoverflow.com" }
          }
        }
      };

      return o;
    }

Return Value from Web Service:

<StorageObject>
    <Name>Matthew</Name>
    <Birthday>Jan 1st, 2008</Birthday>
    <OtherInfo>
    	<NameValuePairs>
    		<Name>Hobbies</Name>
    		<Value>Programming</Value>
    	</NameValuePairs>
    	<NameValuePairs>
    		<Name>Website</Name>
    		<Value>Stackoverflow.com</Value>
    	</NameValuePairs>
    </OtherInfo>
</StorageObject>

What I want:

<OtherInfo>
    <Hobbies>Programming</Hobbies>
    <Website>Stackoverflow.com</Website>
</OtherInfo>

The Reason & Other Stuff:

Birincisi, yazının uzunluğu için özür dilerim, ama ben de tekrarlanabilir kodu vermek istedim.

Ben PHP web hizmetleri tüketen çünkü ben, bu formatta istiyorum. Ben kolayca gitmek istiyorum:

/ / BU imporant

In PHP => "$Result["StorageObject"]["OtherInfo"]["Hobbies"]".

Bu başka bir formatta ise, o hiç bana bunu başarmak için hiçbir yolu olmaz. Ben hizmet tüketen ediyorsam Ayrıca, C #, ben de aşağıdakileri yapabiliyor olmak istiyorum:

/ / BU imporant

In C# => var m = ServiceResult[0].OtherInfo["Hobbies"];

Ne yazık ki, bunu gerçekleştirmek için nasıl emin değilim. Ben, ancak, bu su dışarı WSDL şema esti (StackOverflow: IXmlSerializer Dictionary bakınız) IXmlSerializer uygulanan özel bir sözlük inşa ederek, bu şekilde elde edebildi. Aynı zamanda çok çok karmaşık ve benim WinFormsTester uygulamada korkunç sonuçlar üretti!

Bunu gerçekleştirmek için herhangi bir yolu var mı? Nesnelerin ne tür oluşturmak gerekiyor? Kesinlikle yazılı bir koleksiyon / yaparak dışında bu / yapmak için herhangi bir yolu var mı? Ben yaparsam Açıkçası, bu kesinlikle böyle yazmış:

public class OtherInfo {
  public string Hobbies { get; set; }
  public string FavoriteWebsite { get; set; }
}

Sonra ben hiçbir WSDL sorunları olurdu, mükemmel bir işe, ben kolayca PHP erişmek mümkün olacak, ve C # (. OtherInfo.Hobbies) olacaktır.

However, I would completely lose the point of NVP's, in that I would have to know in advance what the list is, and it would be un

5 Cevap

This is like dynamic properties for a object. C# is not quite a dynamic language unlike javascript or maybe PHP can parse the object properties on the fly. The following two methods are what I can think of. The second one might fit into your requirements.

The KISS Way

Keep It Simple Stupid yolu

public class StorageObject {
  public string Name { get; set; }
  public string Birthday { get; set; }
  public List<string> OtherInfo { get; set; }  
}

'|' Sen ayrılır hangi ad değer çiftleri olabilir

OtherInfo = {"Hobbies|Programming", "Website|Stackoverflow.com"}

Tefrika formlar

<StorageObject>
    <Name>Matthew</Name>
    <Birthday>Jan 1st, 2008</Birthday>
    <OtherInfo>
        <string>Hobbies|Programming</string>
        <string>Website|Stackoverflow.com</string>
    </OtherInfo>
</StorageObject>

The Dynamic Way in C#

Dinamik inşa böylece ad değer çifti parçası bir XML öğesi haline olun.

public class StorageObject {
  public string Name { get; set; }
  public string Birthday { get; set; }
  public XElement OtherInfo { get; set; } // XmlElement for dot net 2
}

You can easily build up OtherInfo object as element centric e.g.

XElement OtherInfo = new XElement("OtherInfo");
OtherInfo.Add( ..Hobbies xelement & text value..);
OtherInfo.Add( ..WebSite xelement & text value..);

Tefrika formu olacak

<OtherInfo>
    <Hobbies>Programming</Hobbies>
    <Website>Stackoverflow.com</Website>
</OtherInfo>

veya nitelik merkezli olarak inşa

XElement OtherInfo = new XElement("OtherInfo");
OtherInfo.Add( ..nvp xattribute Hobbies & value..);
OtherInfo.Add( ..nvp xattribute WebSite & value..);

<OtherInfo>
    <nvp n="Hobbies" v="Programming" />
    <nvp n="Website" v="Stackoverflow.com" />
</OtherInfo>

For any dynamic language, it can access to the properties directly. For the rest, they can access the value by read the XML. Reading XML is well supported by most of framework.

Bu benim yerleşti ettik budur.

Sınıf Yapısı:

public class StorageObject {
  public string Name { get; set; }
  public string Birthday { get; set; }
  [XmlAnyElement("Info")]  // this prevents double-nodes in the XML
  public XElement OtherInfo { get; set; }
}

Kullanımı:

StorageObject o = new StorageObject();
o.OtherInfo.Add(new XElement("Hobbies","Programming");
o.OtherInfo.Add(new XElement("Website","Stackoverflow.com");

Çıktı:

<Info>
  <Hobbies>Programming</Hobbies>
  <Website>Stackoverflow.com</Website>
</Info>

Ben onların yardım için herkese teşekkür etmek istiyorum, ben gerçekten yardım ve fikirler için teşekkür ederiz.

Bu tamamen farklı bir almak gibi, neden tamamen farklı yapıyor düşünmek değil. Bir web hizmeti tefrika depolama nesneyi döndürmek için yöntem, eksi OtherInfo ve OtherInfo özelliklerini (anahtar) listesini döndürmek için başka bir yöntem, ve listesini döndürmek için üçüncü var Herhangi bir anahtar değerleri. Verilen, tüm verileri istiyorsanız bu web hizmetine daha yuvarlak gezileri alacak, ancak çözüm çok daha basit ve daha esnek olacaktır.

[Serializable]
public class StorageObject {
  public string Name { get; set; }
  public string Birthday { get; set; }

  [Nonserializable]
  public Dictionary<string,List<string>> OtherInfo { get; set; }  
}

[WebMethod]
public List<StorageObject> GetStorageObjects() {
    // returns list of storage objects from persistent storage or cache
}

[WebMethod]
public List<string> GetStorageObjectAttributes( string name )
{
    // find storage object, sObj
    return sObj.Keys.ToList();
}

[WebMethod]
public List<string> GetStorageObjectAtributeValues( sting name, string attribute )
{
    // find storage object, sObj
    return sObj[attribute];
}

System.Xml.Serialization.XmlSerializerAssemblyAttribute niteliğine bir görünüm var. Bu özel bir sınıf düzeyi serileştiriciye belirlemenizi sağlar. Siz ne isterseniz XML tükürmek mümkün olacak.

Bu hız kadar almak için hızlı bir şekilde birini oluşturabilir ve Reflektör ile ona bir göz var sgen.exe kullanmaktır.

-Oisin

Ben bu sorunu çözmek istiyorum emin değilim (C # olur, ama belki de değil PHP), fakat Dictionary<string,List<string>> OtherInfo yerine List<NameValuePairs> kullanmayı deneyin. Sonra "Oyuncak" ve "Web Siteleri" anahtarların olacak ve değerler hobileri veya web sitelerinin listesi olacaktır. Gerçi, bu seri nasıl emin değilim.

Sen gibi hobileri listelerini referans mümkün olacaktır:

List<string> hobbies = storageObject.OtherInfo["Hobbies"];

[EDIT] genel bir XML seri hale sözlüğü için here bakın. Bu türetilmiş sınıf jenerik Sözlük yerine kullanmak gerekir biridir.