2013-03-14 8 views
8

Mam odręczny WCF pełnomocnictwa w jego własnym zespole, jest bardzo prosta:Jak używać niestandardowego proxy WCF w skrypcie Powershell z plikiem konfiguracyjnym?

public class MyServiceClient : ClientBase<IMyService>, IMyService 
{ 
    public MyServiceClient() 
    { 
    } 

    public MyServiceClient(string endpointConfigurationName) : 
     base(endpointConfigurationName) 
    { 
    } 
} 

wczytuję to do skryptu PowerShell:

Add-Type -Path "$LocalPath\MyService.Client.dll" 
Add-Type -Path "$LocalPath\MyService.Contracts.dll" 

jestem następnie próbuje ustawić aplikację config (zgodnie other posts na SO), tak, że klient może być tworzony z Punkt końcowy zdefiniowano w konfiguracji, a nie w scenariuszu, czyli:

[System.AppDomain]::CurrentDomain.SetData("APP_CONFIG_FILE", "$LocalPath\MyService.Client.dll.config") 

I sprawdziłem AppDomain i plik konfiguracyjny jest ustawiony jako jego właściwość ConfigurationFile.

Kiedy tworzę instancję klienta:

$endpointName = "MyServiceHttpEndpoint" # defined in the app.config file 
$myclient = New-Object MyService.Client.MyServiceClient($endpointName) 

To przewraca mówiąc:

Exception calling ".ctor" with "1" argument(s): "Could not find endpoint element with name 'MyServiceHttpEndpoint' and contract 'MyService.Contracts.IMyService' in the ServiceModel client configuration section. This might be because no configuration file was found for your application, or because no endpoint element matching this name could be found in the client element."

Jakieś pomysły? Nie chcę ręcznie tworzyć punktu końcowego w pliku skryptu - należy go odczytać z config.

+1

Błąd mówi: wyglądał w pliku konfiguracyjnym i nie mógł znaleźć punktu końcowego o nazwie "MyServiceHttpEndpoint". Będziesz musiał opublikować rzeczywisty plik konfiguracyjny, jeśli potrzebujesz znaczącej pomocy. – ErnieL

+0

Mówi także "Może to być spowodowane tym, że nie znaleziono pliku konfiguracyjnego dla twojej aplikacji" - na czym polega problem. Plik konfiguracyjny jest w porządku, działa bez Powershell bez żadnych problemów. – MalcomTucker

+0

Sprawdziłem AppDomain i plik konfiguracyjny jest obecny i poprawny w 'AppDomain.Właściwość ConfigurationFile', więc można znaleźć, po prostu nie mogę powiązać pliku konfiguracyjnego z proxy klienta zużywającego. Dodano konfigurację ... – MalcomTucker

Odpowiedz

0

Czy Twoje złożenia są zbudowane jako 32-bitowe lub 64-bitowe?

Napotkałem problem 32/64 w wielu przypadkach.

Tylko uważaj, że jeśli używasz 64-bitowego systemu operacyjnego, masz dwa PowerShelle 64-bitowe (zwykle) i 32-bitowe (interresting, gdy potrzebujesz 32 zewnętrznych złożeń).

0

Byłoby łatwiej, gdyby opublikowałeś swoją pełną konfigurację, ale wygląda na to, że brakuje ci poniższej sekcji.

<system.serviceModel> 
    <bindings> 
     <basicHttpBinding> 
     <binding name="BasicHttpBinding"> 
      <security mode="TransportCredentialOnly"> 
      <transport clientCredentialType="Windows" /> 
      </security> 
     </binding> 
     </basicHttpBinding> 
    </bindings> 
    <client> 
     <endpoint address="ServiceAddress" 
     binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding" 
     contract="MyService.Contracts.IMyService" name="MyServiceHttpEndpoint" /> 
    </client> 
</system.serviceModel> 

Chociaż brzmi to całkiem pewnie, że tak nie jest.

Więc spróbujmy i upewnij się, że Twoja aplikacja PowerShell jest podniesienie config poprawnie ...

Aby upewnić się, czy aplikacja PowerShell jest podniesienie config jak oczekiwano dodać coś takiego do pliku PowerShell:

Get-Content $LocalPath\MyService.Client.dll.config | foreach {Write-Output $_} 

Jeśli to nie jest problem konfiguracji, myślę, że możemy się na to zgodzić.

Czy biblioteka może zobaczyć ustawienia w konfiguracji? Wiemy już, że powershell może zobaczyć konfigurację i może wywołać twoją bibliotekę dll.

Czy konfiguracja znajduje się w tej samej lokalizacji, co plik dll?

Czy dodatek robi coś, czego nie oczekujemy? Patrząc na MSDN docs wygląda jak dodatek typu

Dodaje typ Microsoft .NET Framework (klasa) do Windows PowerShell sesji.

Jeśli klasa jest teraz w sesji typu powershell, to czy ma dostęp do konfiguracji tak jak zwykle? Nie wiem.

Może spróbuj raczej [Reflection.Assembly]::LoadFrom i add-type, aby sprawdzić, czy to ma znaczenie?

Nie mam dokładnej odpowiedzi Obawiam się, ale mam nadzieję, że moje błądzenie jest nieco pomocne.

0

Wygląda brakuje typ oprawy należy BasicHttpBinding gdy jesteś w powershell

Dodać kod wyglądać tak:

$endpointName = "MyServiceHttpEndpoint" 
$httpBinding = new-object System.ServiceModel.WSHttpBinding 
$myclient = New-Object MyService.Client.MyServiceClient($httpBinding, $endpointName) 
0

Wydaje się, że różnica w sposobie, w jaki PowerShell i ISE Powershell radzą sobie z tym.

W przypadku ISE (przynajmniej wersja, której używam) musisz wyczyścić konfigurację, aby wymusić jej ponowne załadowanie. Chociaż, wydaje mi się, że można również umieścić zawartość pliku .dll.config w konfiguracji ISE Powerhell. Jednak wydaje się to nieprzyjemne. Poniższy kod działa. Znalazłem części tego googling ten problem.

# $dllPath is the path to the dll we want to load 
# first point to the correct config file 
[System.AppDomain]::CurrentDomain.SetData("APP_CONFIG_FILE", "$dllPath.config") 

# PowerShell ISE is a PITA we have to override the config 
if ($psISE -ne $null) { 
    Add-Type -AssemblyName System.Configuration 
    [Configuration.ConfigurationManager].GetField("s_initState", "NonPublic, Static").SetValue($null,0) 
    [Configuration.ConfigurationManager].GetField("s_configSystem", "NonPublic, Static").SetValue($null,$null) 
    ([Configuration.ConfigurationManager].Assembly.GetTypes() | where {$_.FullName -eq "System.Configuration.ClientConfigPaths"})[0].GetField("s_current", "NonPublic, Static").SetValue($null, $null) 
} 

#Now load the DLL 
$null = [Reflection.Assembly]::LoadFrom($dllPath) 

# DLL and Config should be loaded - test 
0

Proponuję pominąć plik konfiguracyjny razem, jeśli to możliwe. Jeśli api zawiera punkt końcowy MEX lub WSDL, spróbuj utworzyć swoje serwery proxy, wysyłając do nich zapytanie i użyj WsdlImporter, aby zbudować konfigurację powiązania w pamięci. Od tego momentu możesz w razie potrzeby zmodyfikować go w pamięci.

To jest to, co robię dla projektu, nad którym pracuję, który ma bardzo ciężkie pod względem konfiguracji usługi WCF, ponieważ jest zintegrowany z usługą tokena bezpieczeństwa przy użyciu WS-Trust.

Dla podobnej wersji question zasugerowałem, aby spróbować użyć modułu WcfPS dostępnego w galerii. Ponieważ z innym pytaniem występuje nakładanie się, zacytuję jego część.

code dla modułu jest open source i choć jej w skrypcie to zależy w dużej mierze od .net klas ramowych i zespołów z zespołami System.ServiceModel i System.IdentityModel. Wspominam o tym, ponieważ większość apisów wewnątrz tych zestawów nie jest dostępna w standardzie .NET 2, więc moduł niestety nie będzie działał w systemach operacyjnych innych niż Windows. Możesz także przeczytać więcej na ten temat w moim poście WCFPS - PowerShell module to work with SOAP endpoints.

To jest przykład z README

#region Initialize the channel/client 
$svcEndpoint="http://myserviceprovider/Service1.svc" 

$wsImporter=New-WcfWsdlImporter -Endpoint $svcEndpoint -HttpGet 
$proxyType=$wsImporter | New-WcfProxyType 

# select the endpoint and implicitly the binding from the imported configuration 
$endpoint=$wsImporter | New-WcfServiceEndpoint -Endpoint $svcEndpoint 
$channel=New-WcfChannel -Endpoint $endpoint -ProxyType $proxyType 
#endregion 

#region Use the channel/client 
$channel.Method1() 
$channel.Method2() 
#endregion 

Dzięki tej metodzie nie trzeba żadnych import typów inline .NET, ani serwery proxy używanego w Visual Studio i bez konfiguracji. Najprawdopodobniej będziesz musiał dostosować go do swojego przypadku użycia. Jeśli możesz poprawić funkcjonalność modułu, prześlij żądanie ściągnięcia.

Powiązane problemy