Question: How can I debug a WCF service - I can't hit the breakpoint inside the service
Using VS2012 and NUnit/TestDriven
I can run my test fine, as long as I've started the service before eg Ctrl F5 on the WcfHostApplication. Am hosting inside Visual Studio.
Have tried putting in a Web.Config into the WcfHostConsoleApplication and setting debug to true.
This sample app came from here
//hack to get working as we're not using wsdl yet...mimicking what happens in wsdl
[ServiceContract(Namespace = "http://www.programgood.net/examples/2012/09/wcf")]
public interface IHelloWcfService
{
[OperationContract]
string SayHello(string msg);
}
namespace HelloWcfTests
{
[TestFixture]
public class HelloWcfServiceLibrary_Tests
{
[Test]
public void SayHello_GivenHello_ShouldReturn()
{
//in reality add Service Ref.. using another special interface called IMetaDataExchange
IHelloWcfService proxy = ChannelFactory<IHelloWcfService>.CreateChannel(
new NetTcpBinding(),
new EndpointAddress("net.tcp://localhost:9000/HelloWcfEndPoint"));
string msg = "hello";
string result = proxy.SayHello(msg);
StringAssert.StartsWith("You entered: hello", result);
}
}
}
Do not start your service with Ctrl+F5 because it will start your service without debug.
Start it with F5.
Related
I just started playing with Ninject for self hosted WCF services.
I ran into a problem where it isnt generating a wsdl (url?wsdl or url?singleWsdl).
I start up the service with this :
private static void StartNinjectSelfHost()
{
var someWcfService = NinjectWcfConfiguration.Create<CalculatorService, NinjectWebServiceSelfHostFactory>();
_selfHost = new NinjectSelfHostBootstrapper(CreateKernel,someWcfService);
_selfHost.Start();
}
If I revert to the standard way with this:
private static void LoadWcf()
{
if (serviceHost != null)
{
serviceHost.Close();
}
// Create a ServiceHost for the CalculatorService type and
// provide the base address.
serviceHost = new ServiceHost(typeof(CalculatorService));
// Open the ServiceHostBase to create listeners and start
// listening for messages.
serviceHost.Open();
}
Then I get the wsdl just fine at this URL:
http://localhost:8000/ServiceModelSamples/service?singleWsdl
I'm guessing I have to tell Ninject to do this, but I'm struggling to find any good info by searching.
Any help on enabling the wsdl is appreciated.
Nevermind I'm dumb. I wanted to use "NinjectServiceSelfHostFactory" instead, now it works
I'd like to write a test for my ASP.NET WebApi service and run it against a self-hosted service and the live web hosted service. I imagine that this can be done with a test fixture, but I'm not sure how to set it up. Does anyone know of an example of using a configurable test fixture so that you can pass a parameter to Xunit to choose a self hosted fixture or a web hosted fixture?
Here is how it works with latest xUnit 2.0 beta.
Create a fixture:
public class SelfHostFixture : IDisposable {
public static string HostBaseAddress { get; private set; }
HttpSelfHostServer server;
HttpSelfHostConfiguration config;
static SelfHostFixture() {
HostBaseAddress = ConfigurationManager.AppSettings["HostBaseAddress"]; // HttpClient in your tests will need to use same base address
if (!HostBaseAddress.EndsWith("/"))
HostBaseAddress += "/";
}
public SelfHostFixture() {
if (/*your condition to check if running against live*/) {
config = new HttpSelfHostConfiguration(HostBaseAddress);
WebApiConfig.Register(config); // init your web api application
var server = new HttpSelfHostServer(config);
server.OpenAsync().Wait();
}
}
public void Dispose() {
if (server != null) {
server.CloseAsync().Wait();
server.Dispose();
server = null;
config.Dispose();
config = null;
}
}
}
Then define a collection that will use that fixture. Collections are the new concept to group tests in xUnit 2.
[CollectionDefinition("SelfHostCollection")]
public class SelfHostCollection : ICollectionFixture<SelfHostFixture> {}
It serves as just a marker so has no implementation.
Now, mark tests that rely on your host to be in that collection:
[Collection("SelfHostCollection")]
public class MyController1Test {}
[Collection("SelfHostCollection")]
public class MyController4Test {}
The runner will create a single instance of your fixture when running any test from within MyController1Test and MyController4Test ensuring that your server is initiated only once per collection.
I would recommend to use the In-Memory Server for testing your controllers, so you don't need to spin up a self-host in your unit tests.
http://blogs.msdn.com/b/youssefm/archive/2013/01/28/writing-tests-for-an-asp-net-webapi-service.aspx
I'm having difficulties with accessing a WCF service. My service is
running in the same solution as the MonoDroid App and is hosted by visual
studio. I configured it as BasicHttp. The reference adds ok but at runtime
when I call the one simple test method, I get ;
System.Net.WebException
it's very simple this is web service
public class Service1 : System.Web.Services.WebService
{
[WebMethod]
public string HelloWorld()
{
return "Hello World";
}
}
and here is call
button.Click += delegate
{
localhost.Service1 se = new localhost.Service1();
button.Text= se.HelloWorld();
};
and error snapshot in attachment
I agree that you need to add more information. However, I responded to this question sometime ago and this is what I am doing for the WCF stuff and it's working great for me.
Using Soap in Shared Mono Library for WP 7 and Android
This might help out.
One other thing that I just thought of. Do you have the internet option in the network manifest selected as shown here:
http://docs.xamarin.com/#api/deki/files/1026/=RequiredPermissionsVS.png
I have this strange problem where my client will hang when it calls a method from my WCF Service. Now the real strange thing is that this does not happen when the Client is a Console Application. It does happen when the client is a WinForm or WPF application.
I created a Client Library that a WCF Client can use to connect to the Service, seen here:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel; //needed for WCF communication
namespace DCC_Client
{
public class DCCClient
{
private DuplexChannelFactory<ServiceReference1.IDCCService> dualFactory;
public ServiceReference1.IDCCService Proxy;
public DCCClient()
{
//Setup the duplex channel to the service...
NetNamedPipeBinding binding = new NetNamedPipeBinding();
dualFactory = new DuplexChannelFactory<ServiceReference1.IDCCService>(new Callbacks(), binding, new EndpointAddress("net.pipe://localhost/DCCService"));
}
public void Open()
{
Proxy = dualFactory.CreateChannel();
}
public void Close()
{
dualFactory.Close();
}
}
public class Callbacks : ServiceReference1.IDCCServiceCallback
{
void ServiceReference1.IDCCServiceCallback.OnCallback(string id, string message, Guid key)
{
Console.WriteLine(string.Format("{0}: {1}", id, message));
}
}
}
Here is the code for the working WCF Console Client:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DCC_Client;
namespace Client_Console_Test
{
class Program
{
private static DCCClient DCCClient;
static void Main(string[] args)
{
try
{
DCCClient = new DCCClient();
DCCClient.Open();
DCCClient.Proxy.DCCInitialize(); //returns fine from here
Console.ReadLine();
DCCClient.Proxy.DCCUninitialize();
DCCClient.Close();
}
catch (Exception e)
{
throw;
}
}
}
}
And here is the code for the WPF Client that freezes (see comment)
using System; //etc
using DCC_Client; //Used for connection to DCC Service
namespace Client_WPF_Test
{
public partial class Main : Window
{
private static DCCClient DCCClient;
public Main()
{
InitializeComponent();
DCCClient = new DCCClient();
DCCClient.Open();
}
private void Connect_btn_event() {
try
{
DCCClient.Proxy.DCCInitialize(); //**never returns from this**
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
}
I stepped into the code DCCClient.Proxy.DCCInitialize(); and the service executes the commands successfully, however, for some reason the client gets stuck here and does not continue executing. The client gives no exception, and the stack trace says [external code].
That being said, the Console Client runs perfectly. I think I am missing something simple here. I appreciate any help you can provide.
In case that your service call backs the client directly from DCCInitialize and both operation and callback operation are not marked as one-way your application will deadlock. Try marking your callback implementation with this attribute:
[CallbackBehavior(ConcurrencyMode=ConcurrencyModel.Reentrant)]
Instead of this you can also try to mark operations in both contracts with
[OperationContract(IsOneWay=true)]
But both operations must return void
For the last if neither of these helps try to mark your callback implementation with:
[CallbackBehavior(UseSynchronizationContext=false)]
but in this case your callback operation will run in another thread and it will not be able to manipulate with UI controls directly.
Edit:
WCF behaves differently when hosted in UI thread. In such scenario all request are processed in sequential order in standard windows message loop so if you call the service you blocked your current thread but the service calls back your client and it waits to process the message but it can't because thread is blocked by the initial call = deadlock until initial request timenouts. By using last mentioned behavior you will say WCF to not join windows message loop and instead process messages in separate threads as usual. There is no security issue with this except the fact that you cannot access UI control from methods running in other threads - both WinForms and WPF has approaches to pass commands from other thread.
My application is accessing a WCF service hosted at the server.
When i try to call a Method with [WebInvoke] attribute the response returned is always "error".
All other methods with [WebGet] attribute are working fine.
The interface as in the reference.cs is
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(ConfigurationName="SyncService.IService")]
public interface IService
{
[WebInvoke(BodyStyle = WebMessageBodyStyle.WrappedRequest)]
[System.ServiceModel.OperationContractAttribute(Action="", ReplyAction="")]
[System.ServiceModel.FaultContractAttribute(typeof(DataSynchronization.SyncService.WebExceptionDetail), Action="Update", Name="WebExceptionDetail", Namespace="http://schemas.datacontract.org/xxx.WebServices")]
string Update(string mode, string data);
}
whenever i try to call the Update method of the service using the code
string response = objClient.Update("manual", string data);
the response obtained is "Error".and the log displays
Error -
"System.Xml.Schema.XmlSchemaValidationException:
The element 'providers' cannot contain
text. List of possible elements
expected: 'provider'". on calling
Update
The service is hosted in a remote server which i cannot debug either.