2012-10-18 13 views
5

Buduję WCF w języku C# i klienta do konsumpcji w tym samym czasie. Z jakiegoś powodu mam problem z uzyskaniem metody zwracania int. Oto mój kontrakt:WCF nie zwróci int

[ServiceContract] 
public interface IMData 
{ 
    [OperationContract] 
    int ReturnAnInt(); 

    [OperationContract] 
    String HelloWorld(); 
} 

Oto gdzie wdrożyliśmy go:

public class MData : IMData 
{ 
    public String HelloWorld() 
    { 
    return "Hello World"; 
    } 

    public int ReturnAnInt() 
    { 
    return 5; 
    } 
} 

Używam Visual Studio, a dla klienta, że ​​importowany ten WCF jako odniesienie internetowej. Teraz z jakiegoś powodu, kiedy deklaruję wystąpienie MData i próbuję zadzwonić do HelloWorld, nie ma problemu, ale dostaję błąd kompilacji podczas wywoływania ReturnAnInt.

MData m = new MData(); 
String helloWorld = m.HelloWorld(); 
int result = m.ReturnAnInt(); 

Błąd pojawia się ReturnAnInt jest: „Nie przeciążenie dla metody«ReturnAnInt»zajmuje 0 argumenty” Więc mam myszkę aby zobaczyć, co Visual Studio spodziewa się, a ona mówi, że metoda powinna wyglądać jak:

void MData.ReturnAnInt(out int ReturnAnIntResult, out bool ReturnAnIntResultSpecified) 

byłem walić głową w ścianę nad tym godzinami, a teraz nic nie można znaleźć w Google, i to moi współpracownicy zaskoczony, jak dobrze. Dlaczego dodano dwa parametry, których nie ma w definicji, i zmieniono typ zwrotu? Każda pomoc będzie wielce ceniona. Przepraszam, jeśli pominąłem wszelkie informacje, które byłyby pomocne.

Odpowiedz

4

Czy można go zaimportować jako odniesienie do usługi (nowsza technika) zamiast odwołania do strony internetowej (starsza technologia)? Pracuję z usług WCF poprzez referencje usług i nie widziałem takiego problemu - Widziałem tylko właściwości Specified (i to jako właściwość obok int, nie jako dwie out params), gdy definicja usługa pozwala nie int być określony (definicje usług generowanych przez WCF, zgodnie z moim doświadczeniem, działały zgodnie z oczekiwaniami).

Jeśli nie można znaleźć lepsze rozwiązanie, tutaj jest obejście tego problemu za pomocą partial classes: (ta musiałaby być wykonane w dowolnym momencie zwrócić struct, nie tylko int ów)

public partial class MData 
{ 
    public int ReturnAnInt() 
    { 
     int result; 
     bool specified; 
     this.ReturnAnInt(out result, out specified); 
     if (!specified) throw new InvalidOperationException(); 
     return result; 
    } 
} 

Aktualizacjahttp://www.codeproject.com/Articles/323097/WCF-ASMX-Interoperability-Removing-the-Annoying-xx ma (nieco dziwaczne) rozwiązanie i informuje nas, że główną przyczyną jest to, że WCF generuje słabe (prawdopodobnie niedokładne) WSDL-y - mają one minOccurs="0" na elementach, które naprawdę tego nie potrzebują. Odsyłacze do stron internetowych czytają to tak, jak są, i generują klunkowy kod, aby sobie z tym poradzić, z czym próbujesz sobie poradzić. W oparciu o jego artykule, można powrócić tego typu zamiast int:

[MessageContract(IsWrapped = false)] 
public class MyInt 
{ 
    [MessageBodyMember] 
    public int Result { get; set; } 

    public static implicit operator MyInt(int i) 
    { 
     return new MyInt { Result = i }; 
    } 

    public static implicit operator int(MyInt m) 
    { 
     return m.Result; 
    } 
} 

Wraz z modyfikując typ zwracanej przez metodę:

[ServiceContract] 
public interface IMData 
{ 
    [OperationContract] 
    MyInt ReturnAnInt(); 

    [OperationContract] 
    String HelloWorld(); 
} 
public class Service1 : IMData 
{ 
    public MyInt ReturnAnInt() 
    { 
     return 4; 
    } 

    public string HelloWorld() 
    { 
     return "Hello World"; 
    } 
} 
+0

Czy WCF naprawdę wspierać 'out' parametry? – abatishchev

+0

Tak, ale to nie jest tak naprawdę pytanie. Problem opisany w pytaniu jest taki, że kod WCF C# nie określa parametrów 'out' ani opcjonalnych' int's, ale w ten sposób generuje go generator kodu Web References. To działa. Można jednak zdefiniować usługę WCF, taką jak 'int ReturnAnInt (out int otherInt) ;, która działa i może być dostępna zarówno jako odniesienie do usługi, jak i jako odniesienie w Internecie. Wygenerowany WSDL jest po prostu obiektem odpowiedzi z wieloma elementami, więc powinien generować także coś użytecznego w innych językach klienta. –

+0

Dziękuję wszystkim za odpowiedzi, byli bardzo pomocni! Zaimportowałem go jako Service Reference i mój problem został rozwiązany :) –

2

importować go jako usługa Reference (z przestrzeni nazw MData) zamiast Web Reference.

i użyj kodu poniżej,

MDataClient m = new MDataClient(); 
String helloWorld = m.HelloWorld(); 
int result = m.ReturnAnInt(); 

Nie ma nic złego w kodzie. Powinien działać poprawnie, jeśli dodasz odniesienie do usługi i użyjesz powyższego fragmentu.

0

Miałem podobny problem, nie mogłem uzyskać parametru mojej usługi internetowej do pracy. Nadal nie jestem pewien z powodu tego, co dokładnie było, ale miałem to działające przy użyciu parametru string jako out.

[OperationContract] 
LoginStatus GetLogin(string username, string password, out string s_uId); 

na stronie usługi Web:

s_uId = uId.ToString(); 

po stronie klienta:

int uId; 
string s_uId; 
result = client.GetLogin(username, password, out s_uId); 
Int32.TryParse(s_uId, out uId); 
Powiązane problemy