Calling a C# web service's method using volley in android - c#

I have read almost all the related questions, but unfortunately no one solved my problem.
My problem is that I have created a C# web service and created four methods into it for different purposes and one of them called getSections here it is:
[WebMethod]
public string getSections()
{
connectToDB();
da = new SqlDataAdapter("select * from Sections", link);
dt = new DataTable();
da.Fill(dt);
return Newtonsoft.Json.JsonConvert.SerializeObject(dt,Newtonsoft.Json.Formatting.Indented);
}
when I test the web service from the visual studio it shows links to the four methods to invoke them one by one, all of them work fine, so I uploaded them to my server. After that I tried to access to getSections method from my app using volley and here how I have done:
private fun getAllSections() {
/**
* Start Downloading all the sections
*/
var uri="http://......../myProject/WebService1.asmx?op=getSections";
val stringRequest = object : StringRequest(Request.Method.POST, uri, Listener<String> { response ->
Log.i("SectionsResponse", response)
Toast.makeText(this,"SectionsResponse: "+response,Toast.LENGTH_LONG).show()
}, object : Response.ErrorListener {
override fun onErrorResponse(error: VolleyError?) {
if (error != null) {
Log.i("SectionsError:", error.message.toString())
Toast.makeText(baseContext,"error"+error.message.toString(),Toast.LENGTH_LONG).show()
}
}
}) {
override fun getParams(): MutableMap<String, String> {
val params=HashMap<String,String>()
//params.put("a","aa")
return params
}
}
if (Funs().isOnline(this)) {
val requesQueue = Volley.newRequestQueue(this)
requesQueue.add<String>(stringRequest)
} else {
Toast.makeText(this, resources.getString(R.string.connectionFailed), Toast.LENGTH_LONG).show()
}
/**
* End Downloading all the sections
*/
}
After all above I am getting a null result from the error listener which means that the url is not valid or not found.
so
what is the valid way to access to the method into c# web service using volley library.
appreciate any help.

Related

.NET async webservice call with a callback

We have a legacy VB6 application that uses an ASMX webservice written in C# (.NET 4.5), which in turn uses a library (C#/.NET 4.5) to execute some business logic. One of the library methods triggers a long-running database stored procedure at the end of which we need to kick off another process that consumes the data generated by the stored procedure. Because one of the requirements is that control must immediately return to the VB6 client after calling the webservice, the library method is async, takes an Action callback as a parameter, the webservice defines the callback as an anonymous method and doesn't await the results of the library method call.
At a high level it looks like this:
using System;
using System.Data.SqlClient;
using System.Threading.Tasks;
using System.Web.Services;
namespace Sample
{
[WebService(Namespace = "urn:Services")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class MyWebService
{
[WebMethod]
public string Request(string request)
{
// Step 1: Call the library method to generate data
var lib = new MyLibrary();
lib.GenerateDataAsync(() =>
{
// Step 2: Kick off a process that consumes the data created in Step 1
});
return "some kind of response";
}
}
public class MyLibrary
{
public async Task GenerateDataAsync(Action onDoneCallback)
{
try
{
using (var cmd = new SqlCommand("MyStoredProc", new SqlConnection("my DB connection string")))
{
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.CommandTimeout = 0;
cmd.Connection.Open();
// Asynchronously call the stored procedure.
await cmd.ExecuteNonQueryAsync().ConfigureAwait(false);
// Invoke the callback if it's provided.
if (onDoneCallback != null)
onDoneCallback.Invoke();
}
}
catch (Exception ex)
{
// Handle errors...
}
}
}
}
The above works in local tests, but when the code is deployed as a webservice Step 2 is never executed even though the Step 1 stored procedure completes and generates the data.
Any idea what we are doing wrong?
it is dangerous to leave tasks running on IIS, the app domain may be shut down before the method completes, that is likely what is happening to you. If you use HostingEnvironment.QueueBackgroundWorkItem you can tell IIS that there is work happening that needs to be kept running. This will keep the app domain alive for a extra 90 seconds (by default)
using System;
using System.Data.SqlClient;
using System.Threading.Tasks;
using System.Web.Services;
namespace Sample
{
[WebService(Namespace = "urn:Services")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class MyWebService
{
[WebMethod]
public string Request(string request)
{
// Step 1: Call the library method to generate data
var lib = new MyLibrary();
HostingEnvironment.QueueBackgroundWorkItem((token) =>
lib.GenerateDataAsync(() =>
{
// Step 2: Kick off a process that consumes the data created in Step 1
}));
return "some kind of response";
}
}
public class MyLibrary
{
public async Task GenerateDataAsync(Action onDoneCallback)
{
try
{
using (var cmd = new SqlCommand("MyStoredProc", new SqlConnection("my DB connection string")))
{
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.CommandTimeout = 0;
cmd.Connection.Open();
// Asynchronously call the stored procedure.
await cmd.ExecuteNonQueryAsync().ConfigureAwait(false);
// Invoke the callback if it's provided.
if (onDoneCallback != null)
onDoneCallback();
}
}
catch (Exception ex)
{
// Handle errors...
}
}
}
}
If you want something more reliable than 90 extra seconds see the article "Fire and Forget on ASP.NET" by Stephen Cleary for some other options.
I have found a solution to my problem that involves the old-style (Begin/End) approach to asynchronous execution of code:
public void GenerateData(Action onDoneCallback)
{
try
{
var cmd = new SqlCommand("MyStoredProc", new SqlConnection("my DB connection string"));
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.CommandTimeout = 0;
cmd.Connection.Open();
cmd.BeginExecuteNonQuery(
(IAsyncResult result) =>
{
cmd.EndExecuteNonQuery(result);
cmd.Dispose();
// Invoke the callback if it's provided, ignoring any errors it may throw.
var callback = result.AsyncState as Action;
if (callback != null)
callback.Invoke();
},
onUpdateCompleted);
}
catch (Exception ex)
{
// Handle errors...
}
}
The onUpdateCompleted callback action is passed to the BeginExecuteNonQuery method as the second argument and is then consumed in the AsyncCallback (the first argument). This works like a charm both when debugging inside VS and when deployed to IIS.

How to use automatically generated proxy class?

I'd like to use a web service from a database to gather informations. Right now, I implemented to web service, turned it into a proxy class via wsdl.exe but I'm slightly irritated by the outcome. The normal way to call that class is new object -> method -> parameters ->happiness. This thing only consists of partial classes and wants strange parameters. I'm not even sure if I got the right method to get the wanted information.
This seems to be the needed method:
public UniProtId2DomainIdsRecordType[] UniProtId2DomainIds (UniProtId2DomainIdsRequestRecordType UniProtId2DomainIdsRequestRecord)
{
object[] results = this.Invoke("UniProtId2DomainIds", new object[] {
UniProtId2DomainIdsRequestRecord});
return ((UniProtId2DomainIdsRecordType[])(results[0]));
}
This seems to be one of the needed classes:
public partial class UniProtId2DomainIdsRequestRecordType
{
private string uniprot_accField;
/// <remarks/>
public string uniprot_acc
{
get
{
return this.uniprot_accField;
}
set
{
this.uniprot_accField = value;
}
}
}
(That's the whole class, generated by wsdl.exe -> https://www.dropbox.com/s/yg909ibdq02js5a/GetCath.cs)
But as soon as I try to use it as I think it should work... well... my experiments on this (none of them working):
UniProtId2DomainIdsRequestRecordType Uni2Cath = new UniProtId2DomainIdsRequestRecordType();
Uni2Cath.uniprot_acc = "P0A7N9";
UniProtId2DomainIdsRecordType[] UniProtId2DomainIds;
UniProtId2DomainIdsRecordType test = new UniProtId2DomainIdsRecordType();
test.uniprot_acc = "P0A7N9";
UniProtId2DomainIdsRecordType[] UniProtId2DomainIds(test);
All I need is to get a string like P0A7N9 to be passed to the server.
(The reference to this webservice: http://api.cathdb.info/api/soap/dataservices/wsdl#op.o159501052 )
Can someone give me a hint how to handle this, please?
The easiest way would be to add this web service as Service Reference to your project. Then you can call the different methods. Use this as the address: http://api.cathdb.info/api/soap/dataservices/wsdl
using (var ser = new DataServicesPortTypeClient())
{
var results = ser.UniProtId2DomainIds(new UniProtId2DomainIdsRequestRecordType
{
uniprot_acc = "P0A7N9"
});
if (results != null)
{
var geneName = results.gene_name;
var speciesName = results.species_name;
}
}
If you want to use your generated class do this:
using (var service = new DataServices())
{
var results = service.UniProtId2DomainIds(new UniProtId2DomainIdsRequestRecordType
{
uniprot_acc = "P0A7N9"
});
if (results != null && results.Length >0)
{
var geneName = results[0].gene_name;
var speciesName = results[0].species_name;
}
}
As John suggested in the comments, ASMX and wsdl.exe are deprecated technologies. You should be using Service References and svcutil.exe

WebMethod is not active/visible?

Ok I had one WebMethod in my web service which is working fine.
Then I wanted to add another one where I want to send whole object but when I trying to call this method from Windows Form its says method missing?
WebService code:
{
[WebMethod]
public int getNumber(int n)
{
return n * n * 100;
}
[WebMethod]
public string GetValues(string value)
{
return "OK";
}
}
Client code:
private void button1_Click_1(object sender, EventArgs e)
{
localhost.Service1 service2 = new localhost.Service1();
metadata detective = new metadata();
detective.CrimeID = txtCrimeID.Text;
detective.InvestigatorID = txtInvestID.Text;
detective.DataArtefactID = txtDataID.Text;
service2. **<== when I type here GetValues = "Menu.localhost.Service1 does not contain definition for GetValues"**
}
But if straight after "service2." i will start typing get, then method getNumber will be displayed as a possible choice. I dont uderstand Why one method is working fine but another one looks like not exist?
After modifying the webservice, the changes will not propogate to your winforms application until you update the reference to it. The available methods are stored in meta-data for the service when the reference is created.
Update your service reference.

Facebook SDK and threads (WebBrowser control)

This is probably more of a general c# and simple threading question than it is a Facebook SDK question, but I may be wrong. But I could really use some help. I am reusing the sample code that comes with the SDK which includes a FacebookLoginDialog class. I am currently using it like this. In my GetMessages, GetFriendRequests, and other Get* classes, I always try/catch calls like this:
try
{
var result = (IDictionary<string, object>)fb.Get("/me/inbox");
}
catch (FacebookOAuthException e)
{
FacebookSession.Login();
}
Here's my login method in my FacebookSession class
public static void Login()
{
var fbLoginDialog = new FacebookLoginDialog(APP_ID, EXTENDED_PERMISSIONS);
DialogResult dr = fbLoginDialog.ShowDialog();
DisplayAppropriateMessage(fbLoginDialog.FacebookOAuthResult);
}
And here is the constructor in my FacebookLoginDialog class (this is where I have the problem)
public FacebookLoginDialog(string appId, string[] extendedPermissions, bool logout)
{
try
{
var oauth = new FacebookOAuthClient { AppId = appId };
var loginParameters = new Dictionary<string, object>
{
{ "response_type", "token" },
{ "display", "popup" }
};
if (extendedPermissions != null && extendedPermissions.Length > 0)
{
var scope = new StringBuilder();
scope.Append(string.Join(",", extendedPermissions));
loginParameters["scope"] = scope.ToString();
}
var loginUrl = oauth.GetLoginUrl(loginParameters);
if (logout)
{
var logoutParameters = new Dictionary<string, object>
{
{ "next", loginUrl }
};
System.Uri uri =
new Uri("https://www.facebook.com/logout.php?next=" +
"https://www.facebook.com/connect/login_success.html&access_token=" +
FacebookSession._accessToken);
this.navigateUrl = uri;
}
else
{
this.navigateUrl = loginUrl;
}
InitializeComponent(); // crash here... sometimes
}
catch (Exception e)
{
//Log error message
}
}
Sorry for all the code, but now the problem. This code works fine the first time through. If I go to my facebook applications permissions page in Facebook and remove the app (that is, remove its permissions), while my desktop app here is NOT running, when I do start it up, it sees that it does not have permission and shows the login dialog. I can save the access_key and it will work just fine. But if I go to the facebook apps page and yank the permissions while my desktop app is running, then bad things happen. I get an error message about the activex control cannot be instantiated because the current thread is not in a single-threaded apartment. I have seen many posts here that say all you have to do is put [STAThread] above your main(), and my code has that. I have also tried creating a new thread to call the FacebookLoginDialog, but not only did that not work, but since my code is really not designed to run in multiple threads, that started causing more problems.
Is there a simple solution to all this, or do I need to redesign my code so that it properly runs in multiple threads? Or should I just live with the program crashing in those few instances when someone monkeys with the facebook permissions while my app is running?

web service accessing wrapper

hi i have to use a web service in my solution
I have a wrapper static class accessing web service as
public static class Authentication
{
public static bool VerifyPassword(int membershipID, string password)
{
PCIValidationResult result = CreatePciWebService().ValidatePassword(
membershipID, password);
LoginValidationResult loginValidationResult =
(LoginValidationResult)Enum.ToObject(
typeof(LoginValidationResult), result.ResultCode);
return true;
}
private static PCIWebService CreatePciWebService()
{
PCIWebService service = new PCIWebService();
service.Url = KioskManagerConfiguration.PciServiceUrl;
return service;
}
and I call this class in code
like
Authentication.VerifyPassword(23,"testUser");
First call of code is succeed And after 2nd call the code
I got " the operation has timed out" after 2-3 min. waiting ...
How to call a web service ?
Apart from always returning true, and possibly using using (if the service is IDisposable), I can't see anything obviously wrong.
Have you tried tracing it with fiddler or wireshark to see what is happening at the transport level?
You could try adding using, but while this may tidy things up I'm not sure it will fix this issue:
using(PCIWebService svc = CreatePciWebService()) {
PCIValidationResult result = svc.ValidatePassword(membershipID, password);
//...etc
}

Categories