How to Invoke web service async method to windows form application? - c#

I Have Written firebase database insertion code in web service and declared the method in web service as asynchronous. Now I want to call that async method in my windows form application button click event.
This is What i have tried:
Code for web service:
namespace Webservice
{
public class FireService1 : System.Web.Services.WebService
{
[WebMethod]
public async Task Insert()
{
mainform = new Form1();
SetResponse response = await
client.SetTaskAsync("Employee/"+mainform.txt_EID.Text,
Data.Instance.InsertInfo());
StudentData student = response.ResultAs<StudentData>();
}
}
}
Code for WinForm Application:
namespace FirebaseCRUD
{
public partial class Form1 : Form
{
FireService1SoapClient obj = new FireService1SoapClient();
private void btn_insert_Click(object sender, EventArgs e)
{
await obj.Insert();
}
}
}
I Want Insert() method to be invoked into insert button click event.But i am not getting the name of method when i try to call,
Thanks in Advance.

It is a bad idea to use Task and async/await with legacy technology like System.Web.Services.WebService since it was designed before async/await was introduced. These WebServices doesn't work properly with it. I recommend you to look at Asp.Net Core or at least WCF instead of System.Web.Services.WebService. Also you need to make a decision where asynchrony will be(on client side, on server side or both).
But if it is not production code, probably FireService1SoapClient generated async methods in "old style" with BeginXXX and EndXXX prefixes and you need to call obj.BeginInsert without await keyword.

Related

Error in Web Service ASMX in XAMARIN

I have a problem when calling a web-service(asmx) in Xamarin.forms. My web-service works in Android and I generated it with svcutil.exe, but when I tested it in IOS I got a problem saying:
"Mono touch does not support dynamic proxy code generation"
After searching I found out that I have to use a Silverlight tool called SLSvcutil.exe in order to override the CreateChannel method, and to make it work in IOS. It worked, but I need the methods to be synchronous (not async).
I kept searching how to make a pure synchronous method for my web-service and I found this: Monotouch/WCF: How to consume the wcf service without svcutil
Here is my code:
protected override POService2Soap CreateChannel()
{
return new POService2SoapClientChannel(this);
}
private class POService2SoapClientChannel : ChannelBase<POService2Soap>, POService2Soap
{
public POService2SoapClientChannel(System.ServiceModel.ClientBase<POService2Soap> client) :
base(client)
{
}
public ClientLoginResponse ClientLogin(ClientLoginRequest request)
{
object[] _args = new object[1];
_args[0] = request)
return (ClientLoginResponse)base.Invoke("ClientLogin", _args);
}
I get the interface from the Silverlight-generated code, and I create the LoginResponse class there etc, but the problem comes where i call base.invoke("Client Login",_args).
Basically, the ChannelBase doesn't have an Invoke method, it only has BeginInvoke and EndInvoke. So I get the problem cause there is no Invoke in the ChannelBase class inside ClientBase. How can I invoke this, or does anyone have any better solution for getting synchronous results from the web-service?
P.S. I know why Silverlight has async methods, also I know that it is better to async now, and I also know that web-services (asmx) especially in mobile development are a bit "outdated". But in my case I need it like that.
Thanks in advance.

Recording events(request & response) in an MVC application

Ok, so I have quite a task here:
The background of this project is very complex and fully covered by NDA's so I'll just state what I am trying to do without the background.
So what I need is a way to record every request made to an MVC application and every response from it.
Furthermore, I also need a way to "reply" the requests exactly as they were sent.
I was hoping that I could create some solution that "loads" the MVC application, Self hosts or runs in IIS, get requests, records them and passed them verbatim to the MVC application which would then act exactly like any other MVC app.
I could then create a second solution that "loads" the MVC app but instead of opening it up to request it would read the events from the event store and "replays" them in the MVC app.
Now I have no clue where to even start. This kinda thing is way out of my comfort zone.
If there is another solution for how I can record and replay request (and responses) then please let me know.
Even if there is a way to intercept a request in MVC before it starts doing all of its authentication and routing malarkey then that would be a great starting point. I would also need to know where I can capture the response at the very last second before it is sent.
Many thanks for your time
Andy
A HttpModule would work just fine for your scenario:
using System;
using System.Web;
public class HelloWorldModule : IHttpModule
{
public HelloWorldModule()
{
}
public String ModuleName
{
get { return "HelloWorldModule"; }
}
// In the Init function, register for HttpApplication
// events by adding your handlers.
public void Init(HttpApplication application)
{
application.BeginRequest +=
(new EventHandler(this.Application_BeginRequest));
application.EndRequest +=
(new EventHandler(this.Application_EndRequest));
}
private void Application_BeginRequest(Object source,
EventArgs e)
{
// Create HttpApplication and HttpContext objects to access
// request and response properties.
HttpApplication application = (HttpApplication)source;
HttpContext context = application.Context;
/*...*/
}
private void Application_EndRequest(Object source, EventArgs e)
{
HttpApplication application = (HttpApplication)source;
HttpContext context = application.Context;
/*...*/
}
public void Dispose() { }
}
The code and more information available here.

WCF hosted in WPF and how can i change control in MainWindow UI from wcf?

I write WCF code and hosted in my WPF app.
I write class to switch my MainWindow to show other page in my project
public static class Switcher
{
public static MainWindow pageSwitcher;
public static void Switch(Page newPage)
{
pageSwitcher.Navigate(newPage);
}
}
and I write my wcf service like this:
[ServiceContract]
public interface IAppManager
{
[OperationContract]
void DoWork();
[OperationContract]
void Page1();
[OperationContract]
void Page2();
}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Multiple)]
public class AppManager : IAppManager
{
public void DoWork()
{
}
public void Page1()
{
MainWindow.pageSwitcher = new MainWindow();
MainWindow.Switch(new Page1());
}
public void Page2()
{
MainWindow.pageSwitcher = new MainWindow();
MainWindow.Switch(new Page2());
}
}
I want change page remotely from another computer with WCF but it not work
and I trace code the wcf is run and response but do not do anything
how can access to main thread to change ui page or other element?
Your current solution is unusual, but WCF can be hosted in a WPF application. However you should never try to directly manipulate the UI from the WCF service - you'll have cross thread issues to begin with.
What you should consider doing is using messaging via a pub-sub broker (image linked from MSDN):
Something that fits this bill nicely is Prism's EventAggregator. A couple of samples I cherry picked are Simplifying PRISM’s EventAggregator and Prism EventAggregator Sample.
The way you use this is the service registers events and then raises them, the WPF subscribes to those events and processes them. With this you can also specify whether to receive the events on the UI thread or a background thread.
I suggest you start over and this time separate the WCF from your WPF app.
You need to:
1) Separate WCF from WPF - should be in different layers.
2) Use WCF with duplex binding - this way your WCF service will be able to communicate with clients when it needs to.
3) In your WCF callback contract (implemented by the client) - you should prepare a method that will be used to change the local UI mode.
Duplex binding is the perfect solution for your needs.
You can reed about Duplex here
Hope I helped!
Eking.

Code starts only when Application.Run() is invoked WPF application

I have a method which is invoked in class A and it is defined in class B:
class B{
[STAThread]
public static void ScanForAxisCameras() {
DNSSDService service = new DNSSDService();
DNSSDEventManager eventManager = new DNSSDEventManager();
eventManager.ServiceFound += new _IDNSSDEvents_ServiceFoundEventHandler(eventManager_ServiceFound);
DNSSDService browse = service.Browse(0, 0, "_axis-video._tcp", null, eventManager);
Application.Run();//if not invoked everything above does not start
}
}
class A{ ...before invoking..... B.ScanForAxisCameras(); ....after invoking....}
The code in class B "starts"/works only if I invoke Application.Run(). But it causes that all the code in class A ....after invoking.... method does not work. How to handle it so it will not freeze the application?
Edit: the class A is class MainWindow.xaml.cs. It is WPF application.
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e) {
createGUI();
}
private void createGUI() {
LocalNetworkScanner.ScanForAxisCameras();//when there is no Application.Run() ScanForAxisCameras() does not work.
}
}
The WPF UI thread on which you call ScanForAxisCameras() already has a message loop. I believe the problem with your code is that all objects you create inside ScanForAxisCameras have the local scope:
public static void ScanForAxisCameras() {
DNSSDService service = new DNSSDService();
DNSSDEventManager eventManager = new DNSSDEventManager();
eventManager.ServiceFound += new _IDNSSDEvents_ServiceFoundEventHandler(eventManager_ServiceFound);
DNSSDService browse = service.Browse(0, 0, "_axis-video._tcp", null, eventManager);
Application.Run();//if not invoked everything above does not start
}
Without Application.Run(), your objects (service, eventManager, browse) may be getting destroyed and finalized as soon as ScanForAxisCameras finishes. So, the events you're looking for (like ServiceFound) may not even have a chance to get fired.
If you call Application.Run(), then ScanForAxisCameras doesn't exit (at least not until Application.Run() itself exits). That keeps your objects alive and functional.
Try refactoring your code to keep the references to these objects in member fields of your class (or in static variables, FWIW). I believe that should fix the problem.
[EDITED] On a side note, the [STAThread] attribute doesn't make sense in that context (unless you use ScanForAxisCameras as an entry point for a new thread - apparently, that's not the case here).
You can introduce a new Run()-method in your App in the App.xaml.cs file.
Here you can perform custom actions before the application itself gets initialized.
Further information here.
public partial class App : Application
{
public new void Run()
{
// Do your stuff here
B.DoStuff();
// Call the base method
base.Run();
}
}
Application.Run starts the message loop for that particular thread, if there is no message loop then there is no notification for your objects to know they have to do something.
The code in class B "starts"/works only if I invoke Application.Run(). But it causes that all the code in class A ....after invoking.... method does not work.
Run is a blocking call therefore any code after that call is not reachable until the application is closing down i.e. when you exit the message loop.
How to handle it so it will not freeze the application?
In short, you can't. Run will always block so any code you need to run as part of your application startup will have to happen before the call.
After your edit to mention that this is a WPF application then Application.Run as a static method is not the right way to go here. If you need to run initialization when your application starts then you can do what has already been suggested and override the Run method of the Application class, or alternatively (maybe more appropriately) you can hook into the OnStartup event e.g.
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
// code before startup
base.OnStartup(e);
// code after startup
}
}
It seems as though in this situation you would need to add Application.Run() in a different class. Run() accepts nothing, ApplicationContext, Form. This controls the lifetime of the application and should be called before class A, unless class A is the entry point.
See http://msdn.microsoft.com/en-us/library/ms157900.aspx for details.
A Windows Forms application starts when the Main method is called. You can implement initialization procedures on the Main function. However, to initialize a Windows Forms application fully and start it routing Windows Forms events, you need to invoke Application.Run.
you can read about Application here

difference in consume WCF service - Console vs Silverlight

Can someone tell my why when I have wcf contract:
[ServiceContract]
public interface IService1
{
[OperationContract]
string TestGetName();
}
and implementation
public string TestGetName()
{
return "Kasia";
}
When I try consume it in Console app I can do just that:
Service1Client client = new Service1Client();
Console.WriteLine((client.TestGetName()));
but in Silverlight I must use that way :
Service1Client clientTest = new Service1Client();
clientTest.TestGetNameCompleted += new EventHandler<TestGetNameCompletedEventArgs>(clientTest_TestGetNameCompleted);
clientTest.TestGetNameAsync();
void clientTest_TestGetNameCompleted(object sender, TestGetNameCompletedEventArgs e)
{
this.dataGridChild.DataContext = e.Result;
}
Why in SL I don't see this first short solution, but only this with Event handlers?
Or better... why in Console app I can choose synchro operation generation and in SL I must use Generate asynchronous operations... :/
A synchronous call would stop the Silverlight UI thread and possibly the executing environment, i.e. the browser. To prevent this, only asynchronous calls are allowed.
Of course this is something unusual at first, but in the long run it is actually helpful to decouple the view and service layer.
Silverlight does not support synchronous calls (which is what you're doing in your console app).
Update: http://forums.silverlight.net/forums/p/34531/104526.aspx "The main point is that it looks like synchronous behaviour was removed on account of not being supported by all browsers."

Categories

Resources