views:

145

answers:

3

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

+1  A: 

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.

Wim Coenen
Great info, regardless of whether it solves his/her issue. I've never run into that gotcha before.
BioBuckyBall
A: 

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.

Skinniest Man
A: 

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.

Christian Hayter