2012-09-27 39 views
0

首先,請允許我說我沒有做的東西端點/網絡型的經驗,所以我的問題似乎有點愚蠢開始,所以請多多包涵:)配置端點編程

我的工作將爲Windows Phone 7編寫的應用程序移植到Windows 8(Metro應用程序)上。在原有的應用程序,有其定義的URL,綁定和其他位的應用程序連接到服務器ServicesReference.ClientConfig文件(地址變更):

<client> 
    <endpoint address="https://someurl.com/userservice.svc" 
     binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_UserServices" 
     contract="UserApi.UserServices" name="User_Services" /> 
    <endpoint address="https://someurel.com/dataservice.svc" 
     binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_DataServices" 
     contract="DataApi.DataServices" name="Data_Services" /> 

此外,在WP7項目中,有已經添加了兩個「服務參考」(一個用於用戶服務,另一個用於數據服務),並支持Reference.cs生成的文件。當我嘗試將服務引用添加到Win8項目(VS2012)中時,它生成了一個空白的reference.cs文件,因此我只是將WP7項目中的Reference.cs文件添加到W8項目中,並且還複製了ServiceReferences.ClientConfig文件進入W8項目(就目錄結構而言,它看起來與WP7項目相同)。 我覺得這些Reference.cs文件是對合同

現在,當我跑我的W8的應用程序,我得到它需要訪問該服務的部分過程中發生錯誤提供接口的那些:

InvalidOperationException異常是由用戶代碼未處理 無法找到在ServiceModel客戶 配置部分名稱 「User_Services」和合同 「UserApi.UserServices」終結點元素。這可能是因爲沒有爲您的應用程序找到配置文件 ,或者因爲在客戶端元素中找不到此名稱匹配的端點元素 。

所以我想在App未使用ServicesReferces.ClientConfig文件皮卡端點和網絡不會忽略,或者它沒有找到,我有importes到項目的Reference.cs文件。因此,首先假設它沒有通過ServicesReferences.ClientConfig文件正確找到端點,是否可以在代碼中執行相同的操作?

所有我走到這一步,是這樣的:

BasicHttpBinding binding = new BasicHttpBinding(); 
EndpointAddress endpoint = new EndpointAddress(new Uri("https://someurl.com/someservice.svc")); 

但我不如何藉此進一步(我加入到這個App.xaml.cs)

希望這個問題是有道理的。如果您需要任何進一步的信息,請讓我知道,我會盡量了解它,而我去和更多的教育自己在這個端點業務

在此先感謝

回答

1

我有同樣的問題,我試着在一些類包裝的一切。這就是我所做的:所有的 首先,我創建了一個名爲ClientService它創建幷包裝EndpointAdress類:

編輯的Win8:

public class ClientService 
{ 
    public Type ContractType {get;set;} 
    public EndpointAdress EndpointAdress {get;set;} 
    public Binding Binding { get; private set; } 

    public ClientService(Type contractType) 
    { 
    ContractType = contractType; 
    CreateEndpoint(); 
    CreateBinding(); 
    } 

    private void CreateEndpoint() 
    { 
     EndpointAdress = new EndpointAddress(....) //You can get some parameters about the service adress in the Constructor of this class 
    } 

    private void CreateBinding() 
    { 
     Binding = new BasicHttpBinding(); //Or your specific Binding 
    } 
} 

Ø nce我有這個,我創建一個靜態類與所有我的客戶端註冊。一旦我開始我的應用程序,我將它們全部添加。事情是這樣的:

ClientServices.AddClientService(new ClientService(typeof(IYourService)); 


public static class ClientServices 
{ 
    private static readonly Dictionary<Type, ClientService> _clientServices; 

    static ClientServices() 
    { 
     _clientServices = new Dictionary<Type, ClientService>(); 
    } 

    public static void AddClientService(ClientService clientService) 
    { 
     if (!_clientServices.ContainsKey(clientService.ContractType)) 
     { 
      _clientServices.Add(clientService.ContractType, clientService); 
     } 
    } 

    public static ClientService GetClientServiceBy(Type contract) 
    { 
     if (_clientServices.ContainsKey(contract)) 
     { 
      return _clientServices[contract]; 
     } 
     throw new ArgumentException(string.Format("The contract's Type {0} is not registered. Please register the client's endpoint.", contract)); 
    } 
} 

所以,我的應用程序啓動時,我有一個靜態類註冊的所有我的客戶端點。現在,當我想調用服務時,我有一個名爲ServiceInvoker的包裝器。我這樣使用它,每當我想調用一個服務:

var invoker = new ServiceInvoker(); 
    var result = invoker.InvokeService<IMyService, MyObjectReturnType>(
     proxy => proxy.DoSomething(myParameters)); 
    return result; 

凡InvokeService看起來是這樣的:

public TResult InvokeService<TServiceContract, TResult>(Func<TServiceContract, TResult> invokeHandler) where TServiceContract : class 
{ 
    ICommunicationObject communicationObject; 
    var arg = CreateCommunicationObject<TServiceContract>(out communicationObject); 
    var result = default(TResult); 
    try 
    { 
     result = invokeHandler(arg); 
    } 
    catch (Exception ex) 
    { 
     throw; 
    } 

    finally 
    { 
     try 
     { 
      if (communicationObject.State != CommunicationState.Faulted) 
       communicationObject.Close(); 
     } 
     catch 
     { 
      communicationObject.Abort(); 
     } 
    } 
    return result; 
} 

private TServiceContract CreateCommunicationObject<TServiceContract>(out ICommunicationObject communicationObject) 
    where TServiceContract : class 
{ 
     var clientService = GetClientService(typeof(TServiceContract)); 
     var arg = new ChannelFactory<TServiceContract>(clientService.Binding, clientService.EndpointAdress).CreateChannel(); 
     communicationObject = (ICommunicationObject)arg; 
     return arg; 
} 

private ClientService GetClientService(Type type) 
    { 
     var clientService = ClientServices.GetClientServiceBy(type); 
     return clientService; 
    } 

這裏的主要問題是,由於DLL的不能在Windows Store應用被引用,使這個例子工作的唯一方法是複製所有的服務接口和我們傳遞給類庫的可能的對象(Windows應用商店應用程序)。這樣我們就可以創建一個頻道並連接到WCF服務。 複製接口可能是一種解決方法,但不是一種好方法。 服務引用或其他代碼生成工具是要走的路。

此外,異步和等待在這種情況下是不可能的。

** ServiceInvoker apprach從creating WCF ChannelFactory

+0

感謝使用,我會嘗試一下:) – NullPointer

+0

希望它能幫助!這只是一個簡單的例子,將其擴展以滿足您的要求。 – margabit

+0

你做到了嗎? – margabit