Im creating a simple web service in a console app. (PersonService)
this is my Program.cs below
im trying to add a service reference to a different console app (PersonClient)
how can i do this?
i tried adding it by right clicking, add service reference, pointing to the refernce etc...
but it wont work.
[DataContract]
public class Person
{
[DataMember]
public string FirstName { get; set; }
[DataMember]
public string LastName { get; set; }
}
[ServiceContract]
public interface IPersonLookup
{
[OperationContract]
Person GetPerson(int identifier);
}
public class PersonService : IPersonLookup
{
public PersonService()
{
}
public Person GetPerson(int identifier)
{
Person p = new Person();
p.FirstName="Jane";
p.LastName="Doe";
return p;
}
}
class Program
{
static void Main(string[] args)
{
using (ServiceHost host = new ServiceHost(typeof(PersonService)))
{
WSHttpBinding binding = new WSHttpBinding();
host.AddServiceEndpoint(typeof(IPersonLookup), binding, "http://localhost:9090/PersonService");
host.Open();
Console.WriteLine("Listening....");
Console.ReadLine();
}
}
}
Solution:
Create a console application using visual studio.
Right click on the project and click on "Add Service Reference...".
On the window, you will find the "Advanced" button at the bottom.
Click on the button and it will open service reference settings window. It has a button at bottom called "Add Web Reference".
You need to read about WCF MEX Endpoints. Here's a blog post that may help.
You have two console exes, one which runs a ServiceHost - is that correct? Run the server console without debugging; then in the IDE add the WCF reference to the url. It should work, but it needs the server (your second console exe) to be running when you query the mex.
When you added the webservice reference, you defined the namespace and 'class name' for the service. You must either add the namespace reference ("using FooNameSpace;") or use the fully qualified class name of the service ("FooNameSpace.BarClass ws = new FooNameSapce.BarClass()");
Create a console application.
Right click on the References and click on Add Service
Reference.
Click on Advanced button at the bottom.
In the New Window click on Add Web Reference.
No one mentioned yet that you need a couple things before you can use "Add Service Reference".
Use the Visual Studio 2019 Installer tool to modify your existing installation.
Check the ".NET Desktop Development Workload". (This will add a second type of console app.)
Now launch VS 2019 and then create a project using: Console App (.NET Framework) IMPORTANT: Do not select the one for .NET Core, or it will not have the "Add Service Reference" option!
Now go to the main menu bar and select Project -> Add Service Reference. Now you can add your reference.
Happy coding!
Related
I have been trying to add Azure application insights to a few projects. The whole experience was seamless with a .net core app. However, when I tried to update the Cloud role name property, that is where I could not find a lot for an OWIN based app. I want the name of the bubble in Insights Application Map to appear what I set in this property (My API for example) but it keeps resorting to the resource name that I have for this resource in Azure (my-azure-api). After scouring through most online resources, I was able to do the following which does not work.
using Microsoft.ApplicationInsights.Channel;
using Microsoft.ApplicationInsights.Extensibility;
namespace MyApp.Insights
{
public class RoleNameInitializer : ITelemetryInitializer
{
public void Initialize(ITelemetry telemetry)
{
// set role name correctly here.
telemetry.Context.Cloud.RoleName = "My API";
}
}
}
Also added the following in the applicationinsights.config
<Add Type="MyApp.Insights.RoleNameInitializer, MyApp"/>
Added the following to the startup class too (Just as a precaution)
using IntegratedTeleHealthPlatformApi.Insights;
using Microsoft.ApplicationInsights.Extensibility;
using Owin;
namespace MyApp
{
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
TelemetryConfiguration
.Active
.TelemetryInitializers
.Add(new RoleNameInitializer());
ConfigureAuth(app);
ApplyDatabaseMigrations();
}
}
}
I just setup a simple owin based asp.net project(asp.net web application, then in nuget install Microsoft.Owin.Host.SystemWeb).
After the setup, in visual studio -> Project -> Add Application Insights Telemetry:
My custom TelemetryInitializer as below:
Then just add the initializer to the applicationinsights.config:
And after execution, the role name is the one which I set in the initializer:
Please have a try if it's ok at your side. And to make sure your RoleNameInitializer is called, you can set breakpoint there to see if it's called or not.
I worte a server class as DLTransMonCore.cs using C# .Net 4.0.
DLTransMonCore.cs in DLTransMonCore DLL Project
public void MonStart() {
var client = new WebSignalrClient();
client.HubUrl = "http://10.20.30.40/MyApp";
client.HubName = "MyAppHub";
client.InitialSignalrHub();
}
WebSignalrClient.cs in WebSignalrClient DLL Project
public string HubUrl;
public string HubName;
public void InitialSignalrHub() {
var hubConnection = new HubConnection(HubUrl);
var hubProxy = hubConnection.CreateHubProxy(HubName);
hubConnection.Start().Wait();
}
This server will connect to a web site by using signalr(1.2.2). And listen some ports use socket as a socket server.
1st Scenario,
I use a console application (Program.cs) to instance the DLTransMonCore class and start it.
Everything is work fine.
Program.cs
static void Main(string[] args) {
var core = new DLTransMonCore();
core.MonStart();
Console.Readkey();
}
2nd Scenario,
I make a windows service (Service1.cs) to instance DLTransMonCore class and start it. When I try to launch the "Service1" in Windows Services, the "Service1" will start for about 10 seconds and then auto stopped by Windows.
Service1.cs
protected override void OnStart(string[] args) {
var core = new DLTransMonCore();
core.MonStart();
}
I wrote a log file to find which line last executed was:
hubConnection.Start().Wait(); (in WebSignalrClient.cs),
and it never reach the next line.
3rd Scenario,
I make another windows service (Service2.cs) to instance WebSignalrClient directly. And this "Service2" start successfully. (hubConnection.Start().Wait(); is executed successfully and reach the next line)
Service2.cs
protected override void OnStart(string[] args) {
var client = new WebSignalrClient();
client.HubUrl = "http://10.20.30.40/MyApp";
client.HubName = "MyAppHub";
client.InitialSignalrHub();
}
Why the Service1 be fail and the Service2 be success?
Any comment will be appreciate!
Edit:
The description of this post is simplify from my "Original Solution". The Original Solution has lots of Models, Repositories, Interfaces, Utilities, Extensions, Projects...etc.
So I have to simplify it to describe my problem.
But I just created another "New Solution", with the minimized code to test Scenario2 and Scenario3.
Then I found the "New Solution" were worked. It's really bother me...
Now I have to retest and review my code in the "Original Solution".
But if you have any suggestions or comments, please still comment it.
Thank you!
Edit 2:
Dear all, This pattern is no problem.
I found my problem in the "Original Solution".
The problem is : NullReferenceException.
The reason is : When Windows starts the Service, the working directory IS NOT where your Service.exe existed.
In my solution, I have my customize configuration file in that Service's location. And the Service will get the configuration by using the filename directly. Then, the Service will got a null object, and the NullReferenceException when Service Starting is trying to access the config.
I can't explain why but i had the same issue as i wanted a self hosted server using windows service and i never figured out why it was so unstable, what i can suggest is to use Owin selfhost as i switched to it using signalR and it's much more reliable than windows service.
I have a web service and a client DLL. The web service uses an Oracle database.
For testing the client DLL, I copied the web service and made it point to a test database. Then I copied the client DLL and added this test web service using "Add web reference".
What I would like to do is to use one web service and one client DLL but be able to tell the client DLL to use either use the test or production database rather than two identical web serivces and client DLLs.
Edit
I mis-stated the issue. What I need to do is use one client DLL and two web services (one production version, one development/test version) and be able to, somehow, tell the client DLL which web services to use.
This is a sample of how the web service, client DLL and client app are used:
public class DSSService : System.Web.Services.WebService
{
public DSSService()
{
}
[WebMethod(MessageName = "GetFacility", BufferResponse=true, Description = "blah.")]
public Facility GetFacility(string sFDBID, string sZip, string sFinNo)
{
Facility oFacility = ...;
...
return oFacility;
}
....
}
Client DLL:
namespace DSSConfig
{
string sWSURL;
public class Config
{
public Config()
{
}
public void SetWSURL(string sURL)
{
sWSURL = sURL;
}
public Facility GetFacility(string sFDBID, string sZip, string sFinNo)
{
DSSService Proxy = new DSSService();
proxy.Url = sWSURL;
Facility oFacility = Proxy.GetFacility(sFDBID, sZip, sFinNo);
return oFacility;
}
In client application, having DSSConfig DLL as reference:
DSSConfig oConfig = new DSSConfig();
oConfig.SetWSURL("http://myserver/WebService1/service.asmx");
oConfig.GetFacility("blah", "blah", "blah");
What you need to do is change the WEB Service to take a parameter that it will use to construct the connection string to the DB.
Then change client DLL to pass that parameter as part of the call or connection.
Then you can configure the Client DLL to using any technique you like to pass the parameter. My suggestion is perhaps derive a class from the generated proxy in the client DLL and use this in the client code.
Without specific implementation details I can't be more precise.
I have a WCF method which have a nested List parameter, like this
public void Method(List<class1> class1Obj, List<List<SomeClass>> someClassObj)
{
// CODE
}
After setting service reference I get this in my client reference method through which I can call my WCF method
public void Method(class1[] class1Obj, SomeClass[][] someClassObj)
{
base.Channel.Method(class1Obj, someClassObj);
}
Now to call this method from my code I can do this
void myServiceCaller()
{
List<class1> class1Obj = new List<class1>();
// Add items to class1Obj
List<List<SomeClass>> someClassObj = List<List<SomeClass>>();
// Add items to someClassObj
ServiceRef.myServiceClient service = new ServiceRef.myServiceClient();
service.Method(
class1Obj.ToArray(), // This one is fine
someClassObj.ToArray() // This gives me compile time error
);
}
How can I resolve this issue to convert List<List<SomeClass>> to SomeClass[][] ?
When you add your Service Reference and the dialog pops up you can click the Advanced... button in the lower left and change the Collection type drop-down from System.Array to System.Collection.GenericList this will then change the proxy that is created and use List<...> instead of [...] when collections are used.
In addition, if you have already added your Service Reference you can right-click on the Service Reference within the Solution tree and click Configure Service Reference... from the context-menu. This will show the same "Advanced" dialog mentioned above.
I've got a local WCF service in my solution which I have referenced. However my controller class is not able to pick up the Service namespace? Traditionally I would use svcUtil to write a wrapper class but as this is internal I though I could simply add 'Service Reference', tap into the namespace then simple invoke my service (ie var service = new QServiceReference.MyClass();)
I'm unable to show pictures so here's the structure for my solution,
Solution
-> Services Folder
-> QService Folder
QService Project
-> Web Folder
-> Zipporah.Queuing.Web (project)
-> Services References
-> QServiceReference
-> Controllers Folder
-> KioskProcessController
My class (KioskProcessController) is as follows:
using System.Web.Mvc;
using Zipporah.Queuing.Web.QServiceReference; (ITS THIS NAMESPACE REFERENCE THAT DOES NOT WORK)
namespace Zipporah.Queuing.Web.Controllers
{
public class KioskProcessController : ZipController
{
public ActionResult Index()
{
return View();
}
public ViewResult Queue()
{
return View();
}
public ViewResult PreAppointment()
{
return View();
}
}
}
Sorry if that structure is not clear (as aforementioned i cannot post pictures)
Any clues or thoughts would be most appreciated?
The namespace generated for your WCF Client might be different than the one you are using. In your Solution Explorer window, when you select your Service References folder, you can enable the Show All Files button and then navigate to file Reference.cs as shown in below screenshot:
Then, in Reference.cs file, you can find the actual generated namespace by the Add Service Reference dialog, which you can use in your other file with a using statement.