I use asmx web service writes in c# over android device.
I make connection and when in some web method I need integer or string like input param,all work great, but problem is when web method need date, I try to send date in many format but always I have problem to get answer.
I need to send date object, or like string? It is possible that web service view date like something else?
This is method for "communication" with web service:
public void connectSOAP()
{
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
String dateStr = "04/05/2010";
Date dateObj=null;
SimpleDateFormat curFormater = new SimpleDateFormat("dd/mmm/yyyy");
try
{
dateObj = curFormater.parse(dateStr);
}
catch (java.text.ParseException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
request.addProperty("dtFrom",dateObj);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.setOutputSoapObject(request);
envelope.dotNet = true;
try
{
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
androidHttpTransport.call(SOAP_ACTION, envelope);
if (envelope.getResponse() != null)
{
if (envelope.bodyIn instanceof SoapFault)
{
String str = ((SoapFault) envelope.bodyIn).faultstring;
Log.i("", str);
}
else
{
SoapObject resultsRequestSOAP = (SoapObject) envelope.bodyIn;
Log.d("WS", String.valueOf(resultsRequestSOAP));
}
};
}
catch (Exception e)
{
Log.d("WS","sss");
}
}
When i change web method(something with out date it work),I get response in log) But when is this way with date i just get catch ("sss" ) in log,i debug and find that it brake on:
androidHttpTransport.call(SOAP_ACTION, envelope);
But i not find anything about that in log except catch that i set...
For me this looks like the dateObj which you want to give to the webservice can not be parsed, thats why the exception occurre at this line:
androidHttpTransport.call(SOAP_ACTION, envelope);
But as your formatter has this format:
SimpleDateFormat curFormater = new SimpleDateFormat("dd/mmm/yyyy");
Maybe the (three!)"mmm" are causing the error?? I am pretty sure this will produce something like e.g. "Feb" for February and so on.. (e.g. "11/Feb/2014"):
Try something like:
SimpleDateFormat curFormater = new SimpleDateFormat("dd/mm/yyyy");
or
SimpleDateFormat curFormater = new SimpleDateFormat("dd/MM/yyyy");
Btw, to avoid localisation and interoperability issues, i often use DateTime objects accurately formatted to Strings for giving that objects over to WebService. Because many times i had problems by interoperability between e.g. .asmx Webservice and J2EE web service (e.g. the range of DateTime is not the same for J2EE and .NET and if it's a null/nil value you also run in troubles).
Related
Dears,
I know that the title seems popular and easy but what I'm facing is too strange.
Simply, I have a RESTful C# .NET 4.0 web service published on the server, and I want to consume it through Java in my Android application, easy?
The problem is: whenever I call the .NET web service and get the response, java could not parse the return string into Json.
Error message:
org.json.JSONException: Value {lhs:"1 Euro",rhs: "1.3711 U.S. dollars",error: "",icc: true} of type java.lang.String cannot be converted to JSONObject
at org.json.JSON.typeMismatch(JSON.java:111)
at org.json.JSONObject.<init>(JSONObject.java:158)
at org.json.JSONObject.<init>(JSONObject.java:171)
at com.itrack21.mobileapp.LoginActivity.getUserInfo(LoginActivity.java:151)
at com.itrack21.mobileapp.LoginActivity$1$1.run(LoginActivity.java:114)
at java.lang.Thread.run(Thread.java:841)
threadid=17: thread exiting with uncaught exception (group=0x4164d700)
Java Code:
public void getRate(String link) {
try {
URL url = new URL(link);
URLConnection connection = url.openConnection();
InputStream str = connection.getInputStream();
InputStreamReader reader = new InputStreamReader(str);
BufferedReader bufReader = new BufferedReader(reader);
String line=new String();
StringBuffer buffer = new StringBuffer();
while( (line=bufReader.readLine()) != null) {
buffer.append(line);
}
JSONObject obj = null;
try {
obj = new JSONObject(buffer.toString());
} catch (JSONException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
String rhs = "";
try {
rhs = obj.getString("rhs");
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.i("getRate","Converted Currency = " + rhs.toString());
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Debugging:
I did many debugging scenarios but with no luck, here I will use strangest one to describe the problem.
I use my java code to consume Google web service for currency converting using the following link http://www.google.com/ig/calculator?hl=en&q=1USD=?EUR and I got the response as follows: {lhs: "1 U.S. dollar",rhs: "0.726321906 Euros",error: "",icc: true}. And here my code is working perfectly.
I copy exact Json value return from Google web service and working fine with my code, and return it as a HARD CODED String in my RESTful C# service as follows:
C# Code:
public string GetInfo()
{
return "{lhs:\"1 Euro\",rhs: \"1.3711 U.S. dollars\",error: \"\",icc: true}";
}
I request my C# .NET web service using the same code used to invoke Google web service bu I got error listed above org.json.JSONException: Value {lhs:"1 Euro",rhs: "1.3711 U.S. dollars",error: "",icc: true} of type java.lang.String cannot be converted to JSONObject at org.json.JSON.typeMismatch(JSON.java:111).
When I copy and paste the return value into my code as a HARD CODE, it works just fine.
JSONObject obj = null;
try {
obj = new JSONObject("{lhs:\"1 Euro\",rhs: \"1.3711 U.S. dollars\",error: \"\",icc: true}");
} catch (JSONException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Many "Crazy" debugging scenario done including changing the server itself, but with no luck.
What I'm doing wrong?
Regards,
In JSON, you need to wrap the keys in quotation marks too. So for this:
{lhs: "1 U.S. dollar",rhs: "0.726321906 Euros",error: "",icc: true},
you will have to do this:
{"lhs": "1 U.S. dollar","rhs": "0.726321906 Euros","error": "","icc": "true"}
You can check your JSON online at : http://jsonlint.com/
After long debugging process, I got the cause, and then the solution. Here we go:
Visit Google Maps Web Service through Chrome browser, and you will get Json response. For debugging purpose, right click on page and select View page source. Note that the string of Json is pure Json with no additions.
When you repeat same procedure with the C# .NET response through Chrome browser, you will notice that the response is NOT pure Json, it is surrounded by this: <string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">{JSON String HERE}</string>.
Solution:
To remove this string surrounding the response, you have to return Json string as System.IO.Stream. Here the required code changes:
public System.IO.Stream GetInfo()
{
OutgoingWebResponseContext context = WebOperationContext.Current.OutgoingResponse;
context.ContentType = "text/plain";
return new System.IO.MemoryStream(ASCIIEncoding.Default.GetBytes("{lhs:\"1 Euro\",rhs: \"1.3711 U.S. dollars\",error: \"\",icc: true}"));
}
This solution works fine with me, but is it optimal solution? converting from object to Json, and then from Json string to bytes is little overhead, what do think? suggestions?
In my console application I added a service reference to http://www.ibanbic.be/IBANBIC.asmx .
The operations in it I need to use.
Now, this is my little piece of code, and from what I saw in tutorials, this should be enough to connect to it and get a value. But the only value I get is "String is Empty".
using (BANBICSoapClient WebService = new BANBICSoapClient())
{
string bban = "*****";
try
{
string resultIban = WebService.BBANtoIBAN(bban);
if (resultIban != string.Empty)
{
Console.WriteLine(resultIban);
}
else
{
Console.WriteLine("String is empty.");
}
}
catch(Exception msg)
{
Console.WriteLine(msg);
}
}
Console.ReadLine();
Can anyone give me some more information about what is wrong?
Are you passing a valid BBAN or just the string of asterixes? Do you have a sample of valid data?
Calling the web service with data I just mocked up, e.g. (12345, *) looks to return an empty string, so that's what it might return in the event of invalid data.
I write my logs to a text file as JSON. In the file the call obejct LogTime value is
"1378289277591".
*{"LogTime":"Date(1378290565240)"}*
Consider the code below:
Public Class Sync{
public async Task<CallModel> ConvertCallFileToCallObejct(string path)
{
try
{
using (var sr = new StreamReader(path))
{
string callText = await sr.ReadToEndAsync();
var call = new JavaScriptSerializer().Deserialize<CallModel>(callText);
return call;
}
}
catch (Exception exception)
{
Console.WriteLine(exception.Message);
}
}
}
I convert the Call File to Call Object:
var sync = new Sync();
CallModel call = sync.ConvertCallFileToCallObejct(e.FullPath).GetAwaiter().GetResult();
The problem is that Call.LogTime is 9/4/2013 10:29:25 AM but Using Chrome Console and new Date(1378290565240) the result is 9/4/2013 14:59:25 PM
What is the problem?
try below code
// JSON received from server is in string format
var jsonString = '{"date":1251877601000}';
//use JSON2 or some JS library to parse the string
var jsonObject = JSON.parse( jsonString );
//now you have your date!
alert( new Date(jsonObject.date) );
I'm not sure what your Time zone is but I would expect that its UTC datetime.
According to your profile, you live in Iran, where the timezone is UTC+3:30. However, in April, Iran uses daylight saving time so the real timezone is UTC+4:30.
This means that UTC time of 9/4/2013 10:29:25 AM is 9/4/2013 14:59:25 PM local time in Iran.
According to ECMA specification, the time given in your JSON string is treated as UTC time, and it is deserialized as such. You can check the return value of Call.LogTime expression which returns DateTimeKind.Utc. Thus, what you see in your C# code is UTC time.
Now, Chrome also sees this time as UTC time, however it seems to display it as local time, according to your timezone. I am not 100% sure, but I think that Chrome uses your list of preferred languages when choosing how to display date, so try to play with it - I have no idea what exactly it does, but I remember a similar problem when changing the language order affected how time was interpreted. OF course, it depends on what exactly you try to achieve - IMO, both values are correct, as it is the same time.
I crate one webservice using c#.For encrypting response, using the dll specified in this article
http://highcoding.blogspot.in/
WebMetod
[WebMethod]
[EncryptionExtension(Decrypt = DecryptMode.None, Encrypt = EncryptMode.Response, Target = Target.Body)]
[TracingExtension(TracingMode = TracingMode.Response, MethodName = "HelloWorld")]
public string HelloWorld() {
return "Hello World";
}
I created one webservice client using c# windows application.
ServiceReference1.ServiceSoapClient ob = new WindowsFormsApplication2.ServiceReference1.ServiceSoapClient();
string st = ob.HelloWorld();
Here i getting an error "End element 'Body' from namespace 'http://schemas.xmlsoap.org/soap/envelope/' expected"
Encryption is working.But i tried and dont able to find out a way to decrypt data at client side .Anyone know how to handle this in client?
At your proxy client code, add the 'EncryptionExtension' attribute to HelloWorld method
[EncryptionExtension(Decrypt = DecryptMode.Response, Encrypt = EncryptMode.None, Target = Target.Body)]
public string HelloWorld()
{
object[] results = this.Invoke("HelloWorld", new object[] { });
return ((string)(results[0]));
}
BEWARE, this proxy is auto-generated code. Every time you make changes to the webservice, it will be regenerated and your changes will be lost.
Best way to handling this situation is configuration soap extension through configuration. Please follow this link on how to do it.
http://fluentbytes.com/applying-soap-extension-client-proxy-without-altering-generated-proxy-code/
I have a simple webservice, which I want to access via a http post.
The webservice code is show below:
[WebMethod]
public int Insert(string userDate, string DeviceID)
{
bool output;
DateTime date;
output = DateTime.TryParse(userDate, out date);
if (!output)
{
// Throw an error
return -1;
}
int Device;
output = int.TryParse(DeviceID, out Device);
if (!output)
{
// Throw an Error
return -1;
}
UsersDatesBLL BLL = new UsersDatesBLL();
return BLL.Insert(Device, date);
}
I can access the service fine using internet explorer, the results are inserted to the database perfectly simply by calling: CountDownService.asmx/Insert?userDate=24/04/1980&DeviceID=3435
However when testing on Safari and Firefox the service always returns -1
Does anyone know the cause of this? Does Safari encode strings differently to IE?
Regards
Mick
Users can configure their UI language and culture in their browser. The browser passes this information as the Accept-Language HTTP header in requests to your webservice. That information may be used to set the "current culture" of the ASP.NET session that handles the request. It is available as the static property CultureInfo.CurrentCulture.
DateTime.TryParse will use that "current culture" to figure out which of the many datetime string formats it should expect - unless you use the overload where you explicitly pass a culture as the IFormatProvider. Apparently the browsers you are testing with are configured differently, so ASP.NET expects different datetime formats from each. If you want the datetimes to be parsed independently from the browser settings, then you should use CultureInfo.InvariantCulture as the format provider.
The first thing I would do as a debugging measure (assuming you can't just run a debugger on the server code) would be to make all three return paths return different values. That way you're not left guessing whether it was the DateTime.TryParse() call, the int.TryParse() call, or the BLL.Insert() call that failed.
If BLL.Insert() returns a -1 on failure, then I would change the first -1 to -3 and the second to -2. Like so:
output = DateTime.TryParse(userDate, out date);
if (!output)
{
// Throw an error
return -3; // ***** Changed this line
}
int Device;
output = int.TryParse(DeviceID, out Device);
if (!output)
{
// Throw an Error
return -2; // ***** Changed this line
}
I know it doesn't exactly answer the question, but it would at least help you track down which part is failing.
You are using the current culture to parse your DateTime and int values. The first thing to check is whether your various browsers are all configured to send the same culture to the web server in their HTTP request headers.
As a matter of style, you should avoid using culture-dependent formats for URL parameters. The most appropriate format to use is the fixed XML Schema format, like this:
[WebMethod]
public int Insert(string userDate, string DeviceID) {
DateTime date;
int device;
try {
date = XmlConvert.ToDateTime(userDate, XmlDateTimeSerializationMode.Local);
device = XmlConvert.ToInt32(DeviceID);
} catch (Exception) {
// Throw an error
return -1;
}
UsersDatesBLL BLL = new UsersDatesBLL();
return BLL.Insert(device, date);
}
And call it like this:
CountDownService.asmx/Insert?userDate=1980-04-24&DeviceID=3435
Another alternative is to use strongly-typed parameter values and let ASP.NET do the parsing for you, e.g.
[WebMethod]
public int Insert(DateTime userDate, int DeviceID) {
UsersDatesBLL BLL = new UsersDatesBLL();
return BLL.Insert(DeviceID, userDate);
}
DISCLAIMER - I have not tried this alternative myself, but it's worth a look, because it will make your life easier if you don't have to put parsing code into every web method.