[英]Configure endpoint programmatically
首先,讓我首先說我沒有做端點/網絡類型的東西的經驗,所以我的問題似乎有點愚蠢,所以請耐心等待:)
我正在將為Windows Phone 7編寫的應用程序移植到Windows 8(Metro應用程序)上。 在原始應用程序中,有一個ServicesReference.ClientConfig文件,該文件定義了該應用程序連接到服務器的URL,綁定和其他位(地址已更改):
<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'的終結點元素。 這可能是因為找不到您的應用程序的配置文件,或者是因為在客戶端元素中找不到與該名稱匹配的端點元素。
因此,我認為該應用程序沒有使用ServicesReferces.ClientConfig文件來提取端點和網絡地址,或者沒有找到我已導入到項目中的Reference.cs文件。 因此,假設首先無法通過ServicesReferences.ClientConfig文件正確找到端點,是否可以在代碼中執行相同的操作?
到目前為止,我所得到的是:
BasicHttpBinding binding = new BasicHttpBinding();
EndpointAddress endpoint = new EndpointAddress(new Uri("https://someurl.com/someservice.svc"));
但我不打算更進一步(我將其添加到App.xaml.cs中)
希望這個問題有意義。 如果您需要任何其他信息,請讓我知道,我將在嘗試期間進一步了解有關此端點業務的信息
提前致謝
我遇到了同樣的問題,我嘗試將所有內容包裝到某些類中。.這就是我所做的:首先,我創建了一個名為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
}
}
一旦有了這個,就用我所有的客戶注冊創建一個靜態類。 啟動我的應用程序后,我將全部添加。 像這樣:
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;
}
這里的主要問題是,由於無法在Windows Store應用程序中引用DLL,因此使此示例工作的唯一方法是復制所有服務接口和我們轉移到類庫(Windows Store應用程序)的可能對象。 這樣,我們將能夠創建頻道並連接到WCF服務。 復制接口可能是一種解決方法,但不是一個好方法。 服務參考或其他代碼生成工具是必經之路。
此外,在這種情況下,異步和等待是不可能的。
**通過創建WCF ChannelFactory使用ServiceInvoker方法
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.