Android -- How to access data in an ASP.NET database via app? - c#

I have a Windows web server already set up with a website (unlimited application pools) and I want to be able to access a database on that server via the Android app I'm developing. How can I do this? Can someone point me to a tutorial or give code example of how this cross-platform (Android/Java to ASP.NET/C#) communication can be done?
(I'm trying to create a leader board or global scoreboard for my Android game on my server.)
Thanks.

Your app should expose a webservice.
There is no native support for .net soap based webservices. But you can use the ksoap android port:
http://code.google.com/p/ksoap2-android/
which allows an android app to consume a .net asmx webservice.
However the deserialisation of complex on the client side involves lot of code writing for every object you want so pass to the client.
I tried it for a project and there were some problems I ran into (either I could get result back to the client but the parameters i passed where always null or the other way - I could pass arguments but the result was null).
Here is an example I posted for getting an int: How to call a .NET Webservice from Android using KSOAP2?
However, from my current knowlege I would suggest using a .asmx webservice that returns a json string and use a java json serialiser to parse the output. The advantages:
Write less code
Faster, since mobile devices don't always have good internet connections and the xml overhead from soap is bigger than json.
Quickstart:
Create a new asmx Webservice in your .net webapp.
Include a reference to System.Web.
Decorate your webservice class with [ScriptService] and your method with [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
[ScriptService]
public class WebService1 : System.Web.Services.WebService
{
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public string HelloAndroid()
{
return "Hello Android";
}
}
(I think you have to add a reference to System.Web.Extension.dll which is available since .net 3.5).
Your webservice will still return XML (so you can use it with a soap client) unless you make a HTTPPost request with content-type "application/json".
use this code to contact the webservice from android:
private JSONObject sendJsonRequest(string host, int port,
String uri, JSONObject param)
throws ClientProtocolException, IOException, JSONException
{
HttpClient httpClient = new DefaultHttpClient();
HttpHost httpHost = new HttpHost(host, port);
HttpPost httpPost = new HttpPost(uri);
httpPost.addHeader("Content-Type", "application/json; charset=utf-8");
if (param != null)
{
HttpEntity bodyEntity = new StringEntity(param.toString(), "utf8");
httpPost.setEntity(bodyEntity);
}
HttpResponse response = httpClient.execute(httpHost, httpPost);
HttpEntity entity = response.getEntity();
String result = null;
if (entity != null) {
InputStream instream = entity.getContent();
BufferedReader reader = new BufferedReader(
new InputStreamReader(instream));
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null)
sb.append(line + "\n");
result = sb.toString();
instream.close();
}
httpPost.abort();
return result != null ? new JSONObject(result) : null;
}
if your webservice methods looks like this:
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public User GetUser(string name, int age)
{
return new User { Name = name, Age = age; }
}
You can call it this way from android:
public void getUser() {
// if you put a json object to the server
// the properties are automagically mapped to the methods' input parameters
JSONObject param = new JSONObject();
param.put("name", "John Doe");
param.put("age", 47);
JSONObject result = sendJsonRequest("server", 80,
"http://server:80/service1.asmx/GetUser", param);
if (result != null) {
JSONObject user = new JSONObject(result.getString("d"));
// .net webservices always return the result
// wrapped in a parameter named "d"
system.out.println(user.getString("name"));
system.out.println(user.getInt("age").toString());
}
}
Handling server exceptions on the client side:
Add this class to your project:
import org.json.JSONException;
import org.json.JSONObject;
public class JSONExceptionHelper {
private static final String KEY_MESSAGE = "Message";
private static final String KEY_EXCEPTIONTYPE = "ExceptionType";
private static final String KEY_STACKTRACE = "StackTrace";
public static boolean isException(JSONObject json) {
return json == null
? false
: json.has(KEY_MESSAGE) &&
json.has(KEY_EXCEPTIONTYPE) &&
json.has(KEY_STACKTRACE);
}
public static void ThrowJsonException(JSONObject json) throws JSONException {
String message = json.getString(KEY_MESSAGE);
String exceptiontype = json.getString(KEY_EXCEPTIONTYPE);
String stacktrace = json.getString(KEY_STACKTRACE);
StringBuilder sb = new StringBuilder();
sb.append(exceptiontype);
sb.append(": ");
sb.append(message);
sb.append(System.getProperty("line.separator"));
sb.append(stacktrace);
throw new JSONException(sb.toString());
}
}
Now replace the return statement from the sendJSONRequest with:
JSONObject json = result != null ? new JSONObject(result) : null
if (JSONExceptionHelper.isException(json))
JSONExceptionHelper.ThrowJsonException(json);
return json;
Please note: The exception is passed to the client only if connection comes from localhost.
Otherwise you get an http error 500 (or 501? I can't remember). You have to configure your IIS to send error 500 to the client.
Try it out and create a webservice that always throws an exception.

Sounds like a job for Web Services.
Start by creating a Web Service on the Windows web server, you can do this with ASP.NET (or maybe this might be more current).
On the Java side you can call the webservice and use the results that you get back. I think this question may help you get started on this side.

In case you have trouble writing web methods which return array of objects, you may want to refer here:
ksoap android web-service tutorial
Hope it helps.

Related

Using WCF Web Service to output database information on client side using c#

I have created a WCF Web Service using this walk through:
http://mikesknowledgebase.com/pages/Services/WebServices-Page2.htm
It returns data from a local SQL Server. The WCF Web Service takes a string parameter, and returns it back, as a string in JSON format.
I have now created a client website where i want to use the WCF Services as my data source to output the information in the database through a grid view or something similar. How do i do this? I assume i have to use some c#.
Service.cs:
public class Service : IService
{
private object cds;
public List<cdInfo> GetCDinfo()
{
try
{
CdDataClassesDataContext dc = new CdDataClassesDataContext();
List<cdInfo> results = new List<cdInfo>();
foreach (cd cD in dc.cds)
{
results.Add(new cdInfo()
{
Id = cD.Id.ToString(),
artist = cD.artist,
genre = cD.genre,
title = cD.title,
date = cD.date
});}
return results;
}
catch (Exception ex)
{
// Return any exception messages back to the Response header
OutgoingWebResponseContext response = WebOperationContext.Current.OutgoingResponse;
response.StatusCode = System.Net.HttpStatusCode.InternalServerError;
response.StatusDescription = ex.Message.Replace("\r\n", "");
return null;}}}
Hopefully this link will help you in consuming WCF service.
https://msdn.microsoft.com/en-us/library/bb412178(v=vs.110).aspx

Consuming .asmx service in asp.net web api application

I am consuming the .asmx service in my asp.net web api application like this :
[
but this service returns nothing, but in turn writes response in HTTP response object like this:
` [WebMethod(EnableSession = true)]
[ScriptMethod(UseHttpGet = true, ResponseFormat = ResponseFormat.Json)]
public void GetResearchDocsBySector(int pageCode, int resultsPerPage, string subTypeIds, int timeframe)
{
JavaScriptSerializer js = new JavaScriptSerializer();
IRatingsDirectDataMgr dataMgr = RemoteUtil.GetRemote();
List<ResearchDocumentDisplay> results = dataMgr.GetSolrResults(pageCode, resultsPerPage, subTypeIds, timeframe, false);
List<ResearchDocumentWidgetDisplay> resultList = new List<ResearchDocumentWidgetDisplay>();
foreach (var item in results)
{
var obj = ObjMapper<ResearchDocumentDisplay, ResearchDocumentWidgetDisplay>.Map(item);
obj.ArticleTypeName = Constants.TypeMappings[obj.ArticleTypeId];
resultList.Add(obj);
}
HttpContext.Current.Response.Write(js.Serialize(resultList));
}`
I want to consume the result obtained from the service in my webapi application in json format how can we go about it ?
Note : I can't change the .asmx service code at all !!
Set GetResearchDocsBySector to return your List rather than having a void return type and injecting it into the Current http content. TO do this you will need to mark ResearchDocumentWidgetDisplay as Serialisable which you do by adding [Serialisable] above your class ResearchDocumentWidgetDisplay.

How to create web service with C# and parse SOAP message on Android?

Although Ksoap2 is a good library to handle SOAP messages in Android application development, it is not well documented. I've read a lot of blog posts and Q&As but information is often incomplete. Is it possible to provide a complete example of:
How to create simple web service using C#?
How to consume a webmethod on this web service on Android and parse the returned SOAP message to generate a ListView?
You can find how to create simple web service on google very easily.
I want to show you how to get data from .net web service:
first, you have to use ksoap2 library for getting data in android.
http://code.google.com/p/ksoap2-android/ download and copy into project>libs folder
second, you have to use asynctask for calling web service because you have to use asynctask for long time process in android.
If you download and copy ksoap2 library into project, lets get started.
//import ksoap2
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.PropertyInfo;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
public class Example extends Activity {
//define your web service namespace
private static final String NAMESPACE = "http://tempuri.org/";
//web service URL
private static final String URL = "http://www.example.com/webservice1.asmx";
//variables
private String username;
private String password;
private String userID;
public class ExampleAS extends AsyncTask<String,String,String>{
private ProgressDialog dialog = new ProgressDialog(Example.this);
String ParamUserName;
String ParamPassword;
public ExampleAS(String ParamUserName,String ParamPassword){
this.ParamUserName=ParamUserName;
this.ParamPassword=ParamPassword;
}
#Override
protected void onPreExecute() {
dialog.setMessage("Loading...");
dialog.show();
}
#Override
protected String doInBackground(String... params) {
ExampleFunc(ParamUserName,ParamPassword);
return userID;
}
protected void onPostExecute(String userID){
label.setText(userID);
dialog.dismiss();
}
}
private String ExampleFunc(String ParamUserName,String ParamPassword){
PropertyInfo uName = new PropertyInfo();
uName.name= "USERNAME"; //It must be same with your webservice's parameter name
uName.setValue(ParamUserName); //Parameter value
uName.type = PropertyInfo.STRING_CLASS; //Parameter type
PropertyInfo pass = new PropertyInfo();
pass.name= "PASSWORD"; //It must be same with your webservice's parameter name
pass.setValue(ParamPassword); //Parameter value
pass.type = PropertyInfo.STRING_CLASS; //Parameter type
SoapObject request = new SoapObject(NAMESPACE, "Login"); //Namespace,Webservice method name
request.addProperty(uName);
request.addProperty(pass);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.bodyOut=request;
envelope.dotNet = true;
envelope.setOutputSoapObject(request);
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
androidHttpTransport.debug = true;
try {
androidHttpTransport.call("http://tempuri.org/Login", envelope);
SoapObject response = (SoapObject) envelope.getResponse();
Object property = response.getProperty(0);
if(property instanceof SoapObject){
SoapObject users = (SoapObject) property;
userID = users.getProperty("user_id").toString();
}
}
catch (Exception e) {
e.printStackTrace();
}
return userID;
}
Don't copy and build it, It may not working because I write it on here. You should change some field for your request or getting data from web service.
You must call asynctask in onCreate
forexample;
new ExampleAS("admin","1234").execute();
finally, you should follow my another post :Get List from .net Web Service on Android

How to return 302 redirect from Web service environment

I am in a restful service environment and we are using ServiceStack as our service Framework. At this moment, I need to do a redirect directly from the service and as soon as I try to do it from my Get method it fails because I think my Get function looks somethinglike this:
public override object OnGet(ShareDTO request)
{
HttpContext.Current.Response.Redirect(#"http://www.google.com");
return new object();
}
May be because first it is trying to redirect and then it is trying to return a value but this is just wild guess. I am not sure if it is even possible in service environment because all the time whenever I have used Response.Redirect, it was always always a .NET aspx page and never tried in service environment.
Any thoughts?
The easiest way is to just return a custom HttpResult, e.g:
public object Any(Request request)
{
return HttpResult.Redirect("http://www.google.com");
}
Which is equivalent to the more explicit:
return new HttpResult
{
StatusCode = HttpStatusCode.Found,
Headers =
{
{ HttpHeaders.Location, "http://www.google.com" },
}
};
Alternatively you can write directly to the Response, either in a Request Filter or within a Service, e.g:
public object Any(Request request)
{
base.Response.StatusCode = 302;
base.Response.AddHeader(HttpHeaders.Location, "");
base.Response.EndRequest();
return null;
}

Android connecting - WCF Service should return JSON

Iam connecting my Android app to a wcf service, and in my Log.i I can see that it return data correct, The only thing I want to handle it as JSON but my service sends as XML-(I think): this is how the code in the app looks like:
if (entity != null)
{
InputStream instream = entity.getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(instream));
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null){
sb.append(line + "n");
}
String result = sb.toString();
Log.i(TAG,result);
instream.close();
JSONObject json=new JSONObject(result);
JSONArray nameArray=json.names();
JSONArray valArray=json.toJSONArray(nameArray);
and my example method looks like this, I don't know how to return correct JSON data from the WCF webserivce:
/// <returns>An enumeration of the (id, item) pairs. Returns null if no items are present</returns>
protected override IEnumerable<KeyValuePair<string, SampleItem>> OnGetItems()
{
// TODO: Change the sample implementation here
if (items.Count == 0)
{
items.Add("A", new SampleItem() { Value = "A" });
items.Add("B", new SampleItem() { Value = "B" });
items.Add("C", new SampleItem() { Value = "C" });
}
return this.items;
}
This is the error I get:
09-12 17:11:04.924: WARN/System.err(437): org.json.JSONException: Value <ItemInfoList of type java.lang.String cannot be converted to JSONObject
Add:
[WebGet(ResponseFormat = WebMessageFormat.Json)]
As an attribute over your WCF service method. Change WebGet to WebInvoke if you are not using GET requests to call the service.
This looks like the code from WCF REST Starter Kit, the REST Collection template, so it should already support both XML and JSON. It's the service URI you specify on the client side that returns either XML or JSON representation. By default it sends XML but if you put "?format=json" at the and of the service URI it sends the resource in JSON format.
You can get helpful information by using built-in description of the service returned in ATOM (if I remember well) with /help after service URI
something like:
http://localhost/servicetest/Service.svc/help
This is how the wcf serivce method looks like: this returns a collection of values. I added the [WebGet(ResponseFormat = WebMessageFormat.Json)] but still it is not working.
[WebGet(ResponseFormat = WebMessageFormat.Json)]
protected override IEnumerable<KeyValuePair<string, SampleItem>> OnGetItems()
{
// TODO: Change the sample implementation here
if (items.Count == 0)
{
items.Add("A", new SampleItem() { Value = "A" });
items.Add("B", new SampleItem() { Value = "B" });
items.Add("C", new SampleItem() { Value = "C" });
}
return this.items;
}

Categories