Я создал приложение для использования WCF в WPF, добавив ссылку на службу. Теперь его работоспособность. Но теперь у меня есть новое требование: я хочу динамически вызвать службу, введя URL-адрес, имя пользователя и пароль.WCF-сервис без добавления ссылки в WPF
ответ
Вы можете создать клиент WCF без добавления ссылки на службу с использованием ClientBase, но вы по-прежнему нужна ссылка на интерфейс для компилятора knowwhat функции для вызова.
Это работает так:
public class ServiceClient : System.ServiceModel.ClientBase<IService>, IService {
public ServiceClient() {
}
public ServiceClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) :
base(binding, remoteAddress) {
}
public void Login(string user, string password) {
return base.Channel.Login(user, password);
}
}
NetNamedPipeBinding binding = new NetNamedPipeBinding();
binding.TransactionFlow = true;
EndpointAddress address = new EndpointAddress(youraddress);
ServiceClient client = new ServiceClient(binding, address);
client.Login("xxx", "yyy");
Спасибо, Вы говорите, что нет способа позвонить, не зная интерфейс. – Raveesh
Если вы не хотите этого, вы можете пойти по ссылке, которую Jeroen опубликовал в комментарии – Laurijssen
См this веб-сайт для общей идеи. Создайте новое решение VisualStudio и добавьте проект приложения службы WCF и проект тестирования модулей. Поместите следующий код в тестовый проект (слегка измененная версия кода в ссылке) и добавьте недостающие ссылки в проект тестирования модуля. Запустите службу WCF без отладки, при необходимости измените номер порта в тесте и запустите тест. Как уже упоминалось в статье, код может по-прежнему использовать некоторые корректировки, прежде чем он может быть запущен в производство.
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.Xml.Linq;
namespace UnitTestProject1
{
public class ServiceDetail
{
public Uri WSDLUri { get; set; }
public Uri ServiceUri { get; set; }
public String ContractName { get; set; }
public string MethodName { get; set; }
}
public class GenericService
{
public object Call(ServiceDetail svc, List<object> payLoads)
{
//Import WSDL
WsdlImporter imptr = ImportWSDL(svc.WSDLUri);
//Extract Service and Data Contract Descriptions
Collection<ContractDescription> svcCtrDesc = imptr.ImportAllContracts();
//Compile the description to assembly
var assembly = GetAssembly(svcCtrDesc);
if (assembly == null) return null;
//Extract all end points available on the WSDL
IDictionary<string, IEnumerable<ServiceEndpoint>> allEP = GetEndPointsOfEachServiceContract(imptr, svcCtrDesc);
IEnumerable<ServiceEndpoint> currentSvcEP;
if (allEP.TryGetValue(svc.ContractName, out currentSvcEP))
{
//Find the endpoint of the service to which the proxy needs to contact
var svcEP = currentSvcEP.First(x => x.ListenUri.AbsoluteUri == svc.ServiceUri.AbsoluteUri);
//Generate proxy
var proxy = GetProxy(svc.ContractName, svcEP, assembly);
//Deserialize each payload argument to object
List<object> pls = new List<object>();
foreach (var pl in payLoads)
{
object clrObj = null;
try
{
clrObj = Deserialize(pl.ToString(), assembly);
}
catch
{
clrObj = pl;
}
pls.Add(clrObj);
}
//Find opration contract on the proxy and invoke
return proxy.GetType().GetMethod(svc.MethodName).Invoke(proxy, pls.ToArray());
}
return null;
}
private Assembly GetAssembly(Collection<ContractDescription> svcCtrDesc)
{
CodeCompileUnit ccu = GetServiceAndDataContractCompileUnitFromWSDL(svcCtrDesc);
CompilerResults rslt = GenerateContractsAssemblyInMemory(new CodeCompileUnit[] { ccu });
if (!rslt.Errors.HasErrors)
return rslt.CompiledAssembly;
return null;
}
private object GetProxy(string ctrName, ServiceEndpoint svcEP, Assembly assembly)
{
Type prxyT = assembly.GetTypes().First(t => t.IsClass && t.GetInterface(ctrName) != null && t.GetInterface(typeof(ICommunicationObject).Name) != null);
object proxy = assembly.CreateInstance(prxyT.Name, false, System.Reflection.BindingFlags.CreateInstance,
null, new object[] { svcEP.Binding, svcEP.Address }, CultureInfo.CurrentCulture, null);
return proxy;
}
private WsdlImporter ImportWSDL(Uri wsdlLoc)
{
MetadataExchangeClient mexC = new MetadataExchangeClient(wsdlLoc, MetadataExchangeClientMode.HttpGet);
mexC.ResolveMetadataReferences = true;
MetadataSet metaSet = mexC.GetMetadata();
return new WsdlImporter(metaSet);
}
private Dictionary<string, IEnumerable<ServiceEndpoint>> GetEndPointsOfEachServiceContract(WsdlImporter imptr, Collection<ContractDescription> svcCtrDescs)
{
ServiceEndpointCollection allEP = imptr.ImportAllEndpoints();
var ctrEP = new Dictionary<string, IEnumerable<ServiceEndpoint>>();
foreach (ContractDescription svcCtrDesc in svcCtrDescs)
{
List<ServiceEndpoint> eps = allEP.Where(x => x.Contract.Name == svcCtrDesc.Name).ToList();
ctrEP.Add(svcCtrDesc.Name, eps);
}
return ctrEP;
}
private CodeCompileUnit GetServiceAndDataContractCompileUnitFromWSDL(Collection<ContractDescription> svcCtrDescs)
{
ServiceContractGenerator svcCtrGen = new ServiceContractGenerator();
foreach (ContractDescription ctrDesc in svcCtrDescs)
{
svcCtrGen.GenerateServiceContractType(ctrDesc);
}
return svcCtrGen.TargetCompileUnit;
}
private object Deserialize(string xml, Assembly assembly)
{
Type ctr = GetDataContractType(xml, assembly);
return Deserialize(xml, ctr);
}
private object Deserialize(string xml, Type toType)
{
using (Stream stream = new MemoryStream())
{
byte[] data = System.Text.Encoding.UTF8.GetBytes(xml);
stream.Write(data, 0, data.Length);
stream.Position = 0;
DataContractSerializer d = new DataContractSerializer(toType);
return d.ReadObject(stream);
}
}
private Type GetDataContractType(string xml, Assembly assembly)
{
var serializedXML = ConvertToXML(xml);
var match = assembly.GetTypes().First(x => x.Name == serializedXML.Root.Name.LocalName);
return match;
}
private XDocument ConvertToXML(string xml)
{
using (Stream stream = new MemoryStream())
{
byte[] data = System.Text.Encoding.UTF8.GetBytes(xml);
stream.Write(data, 0, data.Length);
stream.Position = 0;
return XDocument.Load(stream);
}
}
private CompilerResults GenerateContractsAssemblyInMemory(params CodeCompileUnit[] codeCompileUnits)
{
// Generate a code file for the contracts
CodeGeneratorOptions opts = new CodeGeneratorOptions();
opts.BracingStyle = "C";
CodeDomProvider pro = CodeDomProvider.CreateProvider("C#");
// Compile the code file to an in-memory assembly
// Don't forget to add all WCF-related assemblies as references
CompilerParameters prms = new CompilerParameters(new string[] { "System.dll", "System.ServiceModel.dll",
"System.Runtime.Serialization.dll"});
prms.GenerateInMemory = true;
prms.GenerateExecutable = false;
return pro.CompileAssemblyFromDom(prms, codeCompileUnits);
}
}
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
// Arrange
var target = new GenericService();
var serviceDetail = new ServiceDetail
{
WSDLUri = new Uri("http://localhost:13152/Service1.svc?singleWsdl"),
ServiceUri = new Uri("http://localhost:13152/Service1.svc"),
ContractName = "IService1",
MethodName = "GetData"
};
var arguments = new List<object> { 5 };
// Act
var result = target.Call(serviceDetail, arguments);
// Assert
Assert.AreEqual("You entered: 5", result);
}
}
}
ошибка, возникающая на ** var svcEP = currentSvcEP.First (x => x.ListenUri.AbsoluteUri == svc.ServiceUri.AbsoluteUri); ** . Ошибка: {«Последовательность не содержит соответствующего элемента»} – Raveesh
Код перепроверяется и выполняется. Проверьте настройки порта serviceDetail.ServiceUri. Посмотрите в отладчике в currentSvcEP; должна быть одна запись. –
- 1. Веб-сервис без добавления ссылки?
- 2. Вызывать классы другого проекта без добавления ссылки
- 3. Как создать экземпляр класса другого модуля без добавления ссылки с помощью призмы в wpf
- 4. Работа с Json RPC в VS 2005 без добавления ссылки?
- 5. Потребляя Java написаны службы без добавления веб-ссылки в C#
- 6. WCF без добавления ссылки на обслуживание в vb
- 7. Fancybox: Создание ссылки на группу изображений без добавления другого изображения?
- 8. C# call nav веб-сервис без добавления веб-ссылки
- 9. Невозможно посещать ссылки без добавления вопросительного знака к URL-адресу
- 10. Обнаружение xmlns при добавлении ссылки в WPF?
- 11. WPF: после добавления WPF Toolkit DLL
- 12. Назначение ссылки без ссылки
- 13. Метод добавления ссылки LinkedList [C++]
- 14. Список добавления ссылки на Python
- 15. ошибка добавления ссылки в .net 3.5
- 16. Добавления произвольной ссылки в элементе управления RichTextBox
- 17. Как правильно разрешать ссылки DLL через библиотеки классов без добавления ссылки на вызывающий проект
- 18. добавления глобальных объектов в WPF приложения
- 19. Добавление функции добавления в WPF Combobox
- 20. «Рассмотрите возможность добавления ссылки на сборку System.Data»
- 21. TimeBasedRollingPolicy без добавления даты
- 22. выполнить запрос без добавления
- 23. Копирование объектов без сохранения ссылки
- 24. WPF Обрабатывать ссылки внутри FlowDocument
- 25. Wpf webbrowser отключает внешние ссылки
- 26. Как отключить ссылки даже после добавления новой ссылки?
- 27. Пример приложения wpf без окон?
- 28. WPF. Элементы группы в ListBox без ItemsSource
- 29. WPF: ссылки на ресурсы приложения в кодировке
- 30. Ошибка компиляции после добавления ссылки asp.net
Вы посмотрите на [этом] сайт (http://www.pinfaq.com/1494/wcf-service-proxy-on-the-fly-dynamically-using-wsdl-url)? –
Позвольте мне проверить, и опубликует статус – Raveesh
hi @JeroenHeier: у меня есть несколько douts Копирует все эти коды и добавляет нужные ссылки. После этого я создал и событие для кнопки для выполнения функции. 'private void getData_Click (отправитель объекта, RoutedEventArgs e) { ServiceDetail sd = new ServiceDetail(); GenericService gs = new GenericService(); sd.WSDLUri = новый Uri (WSDLUri.Text); sd.ServiceUri = новый Uri (ServiceUri.Text); sd.ContractName = ContractName.Text; sd.MethodName = MethodName.Text; } 'что это за список полезных данных и WSDLuri означает, serviceuri? – Raveesh