Kindly, i made a simple WCF self console hosted service with the following code:
using System.ServiceModel;
namespace SimpleService
{
[ServiceContract]
public interface ISimpleService
{
[OperationContract]
int IncrementNumber();
}
}
And the implementation :
using System;
using System.Collections.Generic;
using System.ServiceModel;
using System.Threading;
namespace SimpleService
{
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single, InstanceContextMode = InstanceContextMode.Single)]
public class SimpleService : ISimpleService
{
int _number;
public int IncrementNumber()
{
_number = _number + 1;
Thread.Sleep(100);
Console.WriteLine(_number.ToString());
return _number;
}
}
}
And I hosted in app with the following code :
using System;
using System.ServiceModel;
namespace Host
{
class Program
{
public static void Main()
{
using (ServiceHost host = new
ServiceHost(typeof(SimpleService.SimpleService)))
{
host.Open();
Console.WriteLine("Host started # " + DateTime.Now.ToString());
Console.ReadLine();
}
}
}
}
And app config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="mexBehavior">
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="mexBehavior" name="SimpleService.SimpleService">
<endpoint address="SimpleService" binding="basicHttpBinding"
contract="SimpleService.ISimpleService" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8080" />
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
</configuration>
And now iam trying to call this service from Android mobile app that will call this service hopfully using SOAP Message through this address( http://amyamyamy.no-ip.org/ )
but i couldnt make it work till now!!!
so i need your help regarding c# code that can call the above hosted service using SOAP message.
Many thanks for your kind effort.
My Client app code is :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.IO;
using System.Xml;
namespace Client
{
class Program
{
public static void Main()
{
//SimpleService.SimpleServiceClient client =
//new SimpleService.SimpleServiceClient();
var client = new WebClient();
string data = GetSoap();
Console.WriteLine(data);
client.Headers.Add("Content-Type", "text/xml;charset=utf-8");
client.Headers.Add("SOAPAction", "\"http://tempuri.org/IService1/GetData\"");
var response = client.UploadString("http://amyamyamy.no-ip.org/SimpleService/SimpleService.svc", data);
Console.WriteLine("Number after first call = " +response.ToString());
Console.ReadLine();
}
static string GetSoap()
{
string xmlPayloadText = #"<soapenv:Envelope xmlns:soapenv=""http://schemas.xmlsoap.org/soap/envelope/"" xmlns:tem=""http://tempuri.org/"">
<soapenv:Header/>
<soapenv:Body>
<tem:GetData>
<!--Optional:-->
<tem:value></tem:value>
</tem:GetData>
</soapenv:Body>
</soapenv:Envelope>";
return xmlPayloadText;
}
}
}
With 404 it means it giving you a service not found error and to my understanding that's because the <baseAddresses> part in your service configuration file
<host>
<baseAddresses>
<add baseAddress="http://localhost:8080" />
</baseAddresses>
</host>
You are actually using localhost wheras you should be using a proper server name or IP address.
Again, in your client application you are trying to get the service metadata WSDL using
http://amyamyamy.no-ip.org/SimpleService/SimpleService.svc
Which to me looks like, as if your service is deployed in IIS server but it's not and so you are not able to access the service.
You should rather change your base address like
<host>
<baseAddresses>
<add baseAddress="http://my_actual_server_name:8080/" />
</baseAddresses>
</host>
In your client application try accessing it like
http://my_actual_server_name:8080/SimpleService
That is, your client code
var response = client.UploadString("http://my_actual_server_name:8080/SimpleService", data);
Related
I'm creating a WCF Service, and it's working fine while I'm connecting it to a WinForms Client. But I want to access it throught the browser. Some methods are working fine, but when I'm trying to send back an object that includes multiples objects it returns the error message "A connection was reset"... I was trying to test my service with ARC and with JQuery Ajax, and all the cases I received the same error.
I almost forgot telling you, this issue only happens if I create a instance to Period attribute. If I return the object clear, I don't have any issue.
I share to you a test I made based on the original code. I hope you could help me.
WCF Service
using MercSoft.Conservatorio.DataModels;
using MercSoft.Conservatorio.Request;
using MercSoft.Conservatorio.Response;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Web;
using System.Text;
namespace Mercsoft.Conserv.WSv2
{
[ServiceContract(Namespace = "")]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class Conservatorio
{
// To use HTTP GET, add [WebGet] attribute. (Default ResponseFormat is WebMessageFormat.Json)
// To create an operation that returns XML,
// add [WebGet(ResponseFormat=WebMessageFormat.Xml)],
// and include the following line in the operation body:
// WebOperationContext.Current.OutgoingResponse.ContentType = "text/xml";
[OperationContract]
public void DoWork()
{
// Add your operation implementation here
return;
}
[OperationContract(Name = "EstaActivo"), WebGet]
public bool isActive()
{
return false;
}
[OperationContract(Name="PruebaOro"), WebInvoke(Method="POST", ResponseFormat= WebMessageFormat.Json)]
public PreRegisterResponse pruebaOro(PreRegisterRequest request)
{
PreRegisterResponse response = new PreRegisterResponse();
response.Period = new ModulesDataModel();
return response;
}
// Add more operations here and mark them with [OperationContract]
}
}
PreRegister Response
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Web;
using MercSoft.Conservatorio.DataModels;
using System.Runtime.Serialization;
using MercSoft.Conservatorio.Request;
namespace MercSoft.Conservatorio.Response
{
[DataContract]
public class PreRegisterResponse : BaseResponse
{
[DataMember]
public PreRegisterDataModel Period { get; set; }
public PreRegisterResponse()
: base()
{
}
}
}
PreRegisterDataModel
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
namespace MercSoft.Conservatorio.DataModels
{
[DataContract(IsReference=true)]
public class SystemPeriodsDataModel
{
[DataMember]
public int Id { get; set; }
[DataMember]
public int PeriodType { get; set; }
[DataMember]
public String PeriodTypeString { get; set; }
[DataMember]
public DateTime? StartDate { get; set; }
[DataMember]
public DateTime? EndDate { get; set; }
[DataMember]
public String DatePeriod { get; set; }
[DataMember]
public bool WithInstument { get; set; } //Pre-register ONLY
[DataMember]
public bool Active { get; set; }
}
}
WebConfig
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5"/>
</system.web>
<system.serviceModel>
<services>
<service name="Mercsoft.Conserv.WSv2.Conservatorio">
<endpoint address="" behaviorConfiguration="Mercsoft.Conserv.WSv2.ConservatorioAspNetAjaxBehavior"
binding="webHttpBinding" contract="Mercsoft.Conserv.WSv2.Conservatorio" />
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="Mercsoft.Conserv.WSv2.ConservatorioAspNetAjaxBehavior">
<enableWebScript />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"
multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<!--
To browse web app root directory during debugging, set the value below to true.
Set to false before deployment to avoid disclosing web app folder information.
-->
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
I just found the same issue with a piece of code in a WCF service I'm working on, that is (now) using the webHttpBinding (for REST clients). The culprit was the property "IsReference=true" in a DataContract class. I needed that flag set to TRUE because the graph of objects contains circular references; this way the returned response has a lot less bytes than if the real objects were serialized.
I don't know why this works with SOAP and other bindings but not with webHttpBinding, but since I needed to add REST support, the service stopped working when a DataContract class with IsReference=true was being returned.
My temporary solution was to create another class with the same properties as the original, but without the IsReference property. I need to investigate this further but in the meantime I hope this helps.
I'm having trouble with Team Foundation Server 2015 Web Hooks (https://www.visualstudio.com/get-started/webhooks-and-vso-vs)
I can create web hook on TFS side and it successfully uses RequestBin WebService. But when I create the WCF Web service - have errors all the time.
First of all I get #Cannot process the message because the content type 'application/json; charset utf-8' was not the expected type 'text/xml;charset utf-8'.(415)"
I've read a lot of articles and related questions here.
Tried to add Factory="System.ServiceModel.Activation.WebServiceHostFactory" to .svc file. After it I've got 404 error while consuming service and no endpoint found while trying to open it's WSDL
So, my Interface is:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
namespace MyService
{
// ПРИМЕЧАНИЕ. Команду "Переименовать" в меню "Рефакторинг" можно использовать для одновременного изменения имени интерфейса "IService1" в коде и файле конфигурации.
[ServiceContract]
public interface IService1
{
[OperationContract]
[WebInvoke]
string RollUp(string sData);
// TODO: Добавьте здесь операции служб
}
// Используйте контракт данных, как показано в примере ниже, чтобы добавить составные типы к операциям служб.
[DataContract]
public class CompositeType
{
bool boolValue = true;
string stringValue = "Hello ";
[DataMember]
public bool BoolValue
{
get { return boolValue; }
set { boolValue = value; }
}
[DataMember]
public string StringValue
{
get { return stringValue; }
set { stringValue = value; }
}
}
}
My program is:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
namespace MyService
{
// ПРИМЕЧАНИЕ. Команду "Переименовать" в меню "Рефакторинг" можно использовать для одновременного изменения имени класса "Service1" в коде, SVC-файле и файле конфигурации.
// ПРИМЕЧАНИЕ. Чтобы запустить клиент проверки WCF для тестирования службы, выберите элементы Service1.svc или Service1.svc.cs в обозревателе решений и начните отладку.
public class Service1 : IService1
{
public string RollUp(string sData)
{
return "Sucess " + sData;
}
}
}
my web.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5.2" />
<httpRuntime targetFramework="4.5.2"/>
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<!--Чтобы избежать раскрытия метаданных, до развертывания задайте следующим параметрам значение "false". -->
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<!-- Чтобы при сбое получать подробные сведения об исключении для целей отладки, установите для нижеприведенного параметра значение true. Перед развертыванием установите значение false, чтобы избежать раскрытия информации об исключении -->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="json">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
<services>
<service name="MyService.Service1">
<endpoint name="jsonEP"
address=""
binding="webHttpBinding"
behaviorConfiguration="json"
contract="MyService.IService1"/>
</service>
</services>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<!--
Для просмотра корневого каталога веб-приложения во время отладки установите значение true.
Перед развертыванием установите значение false, чтобы избежать раскрытия сведений в папке веб-приложения.
-->
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
And with all of this I get 404 error.
Hope someone can help me as I can't beat this web services for days and for now have no idea what to do.
I am adding objects sent from a client to a list which is at the service, my issue is this, during debugging I see that as soon as i return from the main service to the client the list turns to 0. It's like the list gets emptied and as soon as the flow of the program returns to the client and then when the client sends data to the service the data are there, as soon as i enter the method of the service the list gets filled with the old data. I would like to access these data from another part of the program but i always see the list empty. Any tips?
As per my comment you need to setup the ServiceContract's SessionMode and also the ServiceBehavior's InstanceContextMode. The default InstanceContextMode is PerCall which means that your list will not be preserved. You need to change it to use PerSession. See below for fully working example (.NET 4):
Service Side Code:
using System.Collections.Generic;
using System.ServiceModel;
namespace WcfService1
{
[ServiceContract(SessionMode = SessionMode.Required)]
public interface IService1
{
[OperationContract]
int AddData(string data);
[OperationContract]
List<string> GetData();
}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
public class Service1 : IService1
{
private readonly List<string> _myList = new List<string>();
public int AddData(string data)
{
_myList.Add(data);
return _myList.Count;
}
public List<string> GetData()
{
return _myList;
}
}
}
Service Side web.config
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<protocolMapping>
<add scheme="http" binding="wsHttpBinding"/>
</protocolMapping>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
Client Side:
using System;
using System.Collections.Generic;
using ConsoleApplication1.ServiceReference1;
namespace ConsoleApplication1
{
internal class Program
{
private static void Main()
{
using (var service = new Service1Client())
{
// Add items...
int itemCount;
itemCount = service.AddData("Test Item 1");
Console.WriteLine("Service now holds {0} items", itemCount);
itemCount = service.AddData("Test Item 2");
Console.WriteLine("Service now holds {0} items", itemCount);
itemCount = service.AddData("Test Item 3");
Console.WriteLine("Service now holds {0} items", itemCount);
// Get all of the items added...
List<string> listFromService = service.GetData();
foreach (var listItem in listFromService)
{
Console.WriteLine(" * {0}", listItem);
}
Console.WriteLine();
}
Console.ReadKey();
}
}
}
Client Side app.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IService1" />
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:59604/Service1.svc" binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_IService1" contract="ServiceReference1.IService1"
name="WSHttpBinding_IService1">
</endpoint>
</client>
</system.serviceModel>
</configuration>
Note: I had to ensure that wsHttpBinding was used as basicHttpBinding does NOT support sessions.
I'm getting the fabled Error: Cannot obtain Metadata from... message, particularly http://localhost:1640/Service1.svc I've scoured stackoverflow and Google and, so far, none of it has helped. I created a new product to dumb it down and it's still not working. So I am here asking for help.
I'm trying to setup a WCF Service that uses JSON, which means I need to use webhttpbinding, in C#. When I use the WCF Test Client, I get the aforementioned metadata error. I'm using Visual Studio Express 2010 and the target framework. I've been at this for two days and cannot understand why or what is the problem.
I would appreciate any help. Thank you.
Here is my web.config file:
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<services>
<service name="WcfService4.Service1"
behaviorConfiguration="jsonRestDefault">
<endpoint
name="jsonRestEndpoint"
behaviorConfiguration="RESTFriendly"
binding="webHttpBinding"
contract="IService1"
address="http://localhost:1640/Service1.svc"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="jsonRestDefault">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="RESTFriendly">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
Here is the IService1.cs file:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
namespace WcfService4
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IService1" in both code and config file together.
[ServiceContract]
public interface IService1
{
[OperationContract]
[WebInvoke(
Method = "GET",
UriTemplate = "players",
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Bare)]
List<Person> GetPlayers();
}
// Use a data contract as illustrated in the sample below to add composite types to service operations.
[DataContract]
public class Person
{
[DataMember]
public string FirstName { get; set; }
[DataMember]
public string LastName { get; set; }
[DataMember]
public int Age { get; set; }
public Person(string firstName, string lastName, int age)
{
this.FirstName = firstName;
this.LastName = lastName;
this.Age = age;
}
}
}
Here is the Service1.svc.cs file:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using System.Net;
namespace WcfService4
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in code, svc and config file together.
public class Service1 : IService1
{
public List<Person> GetPlayers()
{
List<Person> players = new List<Person>();
players.Add(new Person ( "Peyton", "Manning", 35 ) );
players.Add(new Person ( "Drew", "Brees", 31 ) );
players.Add(new Person ( "Brett", "Favre", 38 ) );
return players;
}
}
}
Take a look at this link
It states the following:
WebHttpBinding is a REST-based binding - REST does not expose
metadata like WSDL/XSD contrary to SOAP.
In addition to bruno bologna's answer and link, the link at WCF REST Service not visible in WCFTestClient also provides some very useful information. Basically, the reason why it's not working is the WCFTestClient is not designed for web (think JSON). It hooks in through SOAP. If I have a service that is dependent on JSON, I cannot test it through the WCFTestClient.
I see that it is possible to modify the client configuration file in WCFTestClient to enable web binding, but that may be because of future-proofing for WADL or if someone writes a WADL service extension. That's just specultation on my part, though. Otherwise, it doesn't appear one can test WCF Service with JSON using the WCFTestClient tool.
I have created the WCF service and trying to host in Managed Windows Service (followed article). The service is up and running in services.
When trying to add the URL in the client application (net.tcp://localhost:8000/UserManagement) I get the error:
Metadata contains a reference that cannot be resolved:
'net.tcp://localhost:8000/UserManagement'. Could not connect to
net.tcp://localhost:8000/UserManagement. The connection attempt lasted
for a time span of 00:00:00.9531433. TCP error code 10061: No
connection could be made because the target machine actively refused
it 127.0.0.1:8000. No connection could be made because the target
machine actively refused it 127.0.0.1:8000 If the service is defined
in the current solution, try building the solution and adding the
service reference again.
Service.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.ServiceModel;
using System.ServiceProcess;
using System.Configuration;
using System.Configuration.Install;
namespace AddUser
{
public class UserManagement : IUserManagement
{
public bool AddUser(string strName, DateTime dtDOB, string strGender, string strRole)
{
return true;
}
}
[ServiceContract]
public interface IUserManagement
{
[OperationContract]
bool AddUser(string strLname,string strFName, string strUname, string strPswd, DateTime dtDOB, string strGender, string strRole, string strHobbies);
}
public class UserManagementService : ServiceBase
{
public ServiceHost serviceHost = null;
public UserManagementService()
{
ServiceName = "WCFUserManagementService";
}
public static void Main()
{
ServiceBase.Run(new UserManagementService());
}
protected override void OnStart(string[] args)
{
if (serviceHost != null)
{
serviceHost.Close();
}
serviceHost = new ServiceHost(typeof(UserManagementService));
serviceHost.Open();
}
protected override void OnStop()
{
if (serviceHost != null)
{
serviceHost.Close();
serviceHost = null;
}
}
}
[RunInstaller(true)]
public class ProjectInstaller : Installer
{
private ServiceProcessInstaller process;
private ServiceInstaller service;
public ProjectInstaller()
{
process = new ServiceProcessInstaller();
process.Account = ServiceAccount.LocalSystem;
service = new ServiceInstaller();
service.ServiceName = "WCFUserManagementService";
Installers.Add(process);
Installers.Add(service);
}
}
}
app.config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<service behaviorConfiguration="AddUser.UserManagementServiceBehavior" name="AddUser.UserManagement">
<endpoint address="" binding="netTcpBinding" contract="AddUser.IUserManagement"/>
<endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:8000/UserManagement" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="AddUser.UserManagementServiceBehavior">
<serviceMetadata httpGetEnabled="false"/>
<serviceDebug includeExceptionDetailInFaults="False"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
You need to use the address
net.tcp://localhost:8000/UserManagement/mex
when you are configuring your service reference.
Alternatively your metadata endpoint should use the mexHttpBinding and you should set your httpGetEnabled to true in your service behavior
<serviceMetadata httpGetEnabled="true"/>
I also faced the same issue after following MSDN link you provided. There is a error in that code.
In you OnStart method,
serviceHost = new ServiceHost(typeof(UserManagementService));
instead of creating ServiceHost for UserManagementService, use your actual WCF service class name here. This line of code will create an instance of windows service and not the WCF service. I was able to fix mine using that.