Artikel mit dem Tag "C#"

Einem WCF Dienst aus PHP ein Dictionary als Parameter übergeben

Einem WCF Dienst ein Dictionary (hier Dictionary<string, string>) als Parameter zu übergeben, kann z.B. sinnvoll sein, wenn der Dienst eine Suche in einer SQL-Datenbank durchführen soll, wobei die SQL-Abfrage, die dieser Suche zu Grunde liegt, beliebig viele SQL-Parameter enthalten kann:

SELECT
    *
FROM
    [TABLE]
WHERE
    FIELD1 LIKE @Search1
    FIELD2 LIKE @Search2
    FIELD3 LIKE @Search3
    ...
    FIELDN LIKE @SearchN

Die entsprechende Methode des Dienstes könnte dann so aussehen (die Deklaration als void um so einfach wie möglich zu bleiben):

public void SendDictString(Dictionary<string, string> dParam)
{
    SqlCommand sc = new SqlCommand();
    sc.CommandText = ...; // Die SQL-Abfrage, z.B. aus Datei geladen

    Dictionary<string,string>.Enumerator e = dParam.GetEnumerator();
    while (e.MoveNext())
    {
        Debug("{0}:{1}", e.Current.Key.ToString(), e.Current.Value.ToString());

        sc.Parameters.Add(new SqlParameter(e.Current.Key, e.Current.Value));
    }
    SqlDataReader sdr = sc.ExecuteReader();
}

Betrachtet man die resultierende WSDL-Datei, sieht diese so aus:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://schemas.microsoft.com/2003/10/Serialization/Arrays" elementFormDefault="qualified" targetNamespace="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<xs:complexType name="ArrayOfKeyValueOfstringstring">
<xs:annotation>
<xs:appinfo>
<IsDictionary xmlns="http://schemas.microsoft.com/2003/10/Serialization/">true</IsDictionary>
</xs:appinfo>
</xs:annotation>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="KeyValueOfstringstring">
<xs:complexType>
<xs:sequence>
<xs:element name="Key" nillable="true" type="xs:string"/>
<xs:element name="Value" nillable="true" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:element name="ArrayOfKeyValueOfstringstring" nillable="true" type="tns:ArrayOfKeyValueOfstringstring"/>
</xs:schema>

Interessant an dieser Beschreibung ist dieser Teil:

<xs:sequence>
<xs:element name="Key" nillable="true" type="xs:string"/>
<xs:element name="Value" nillable="true" type="xs:string"/>
</xs:sequence>

Mit einer PHP-Anwendung ließe sich der Dienst entsprechend wie folgt konsumieren:

$client->SendDictString(array(
	"dParam"	=>	array(
		array(
			"Key"	=>	"Search1",
			"Value"	=>	"Suchbegriff1"
		),
		array(
			"Key"	=>	"Search2",
			"Value"	=>	"Suchbegriff2"
		),
		array(
			"Key"	=>	"Search3",
			"Value"	=>	"Suchbegriff3"
		)
	)
)

Die Debug-Ausgabe des WCF Dienst sieht dann so aus:

Search1:Suchbegriff1
Search2:Suchbegriff2
Search3:Suchbegriff3
Share
Geschrieben von Philip Ehret am 15.07.2011 | Kommentare weiterlesen...

Fehlermeldung „Error Fetching http headers“ bei der Abfrage eines WCF Dienstes, welcher einen benutzerdefinierten Typ zurückgibt

Bei der Entwicklung eines WCF WebService, definierte ich den folgenden ServiceContract:

[ServiceContract]
public interface IClient
{
    ...
    [OperationContract]
    WebUser GetUserData(string sWebUserHash);
    ...
}

Beim Abruf einer Implementierung des Dienstes mit Hilfe des PHP SoapClient kam es zu der Exception:

Error Fetching http headers

Zwar hat mich die Suche nach dem Ursprung unter anderem zu einem PHP Bug Report geführt, jedoch konnten die dort angegebenen Hilfen mein Problem nicht beheben.

Da die Kompilierung des WebService ohne Probleme verlief, die Dienstbeschreibung per HTTP abrufbar war und andere Methoden ohne Probleme funktionierten, vermutete ich das Problem beim PHP SoapClient. Jedoch stellte sich dann heraus, dass ich vergessen hatte, dem WebService den Typ WebUser bekanntzumachen.

Das Problem löste sich durch die simple Ergänzung des folgenden Attributs:

[ServiceKnownType(typeof(WebUser))]

Der funktionierende Quellcode sah dann so aus:

[ServiceContract]
[ServiceKnownType(typeof(WebUser))]
public interface IClient
{
    ...
    [OperationContract]
    WebUser GetUserData(string sWebUserHash);
    ...
}
Share
Geschrieben von Philip Ehret am 30.06.2011 | Kommentare weiterlesen...