ASMX Seems To Cache
I have the following ASMX web service:
// removed for brevity //
namespace AtomicService
{
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
[ScriptService]
public class Assets : WebService
{
private static readonly ILog Log = LogManager.GetLogger(typeof(Validation));
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public string CityCreate(string cityname, string state, string country,
decimal timezoneoffset, decimal lat, decimal lon)
{
var response = new Dictionary<string, string>();
if(string.IsNullOrEmpty(cityname) || (string.IsNullOrEmpty(country)))
{
response.Add("Response", "empty");
return JsonConvert.SerializeObject(response, Formatting.Indented);
}
int tzid;
int ctyid;
try
{
tzid = AtomicCore.TimezoneObject.GetTimezoneIdByGMTOffset(timezoneoffset);
var cty = AtomicCore.CountryObject.GetCountry(country);
ctyid = cty.CountryId;
}
catch (Exception)
{
response.Add("Response", "errordb");
return JsonConvert.SerializeObject(response, Formatting.Indented);
}
if(AtomicCore.Validation.DoesCityAlreadyExistByLatLon(cityname, country, lat, lon))
{
response.Add("Response", "exists");
return JsonConvert.SerializeObject(response, Formatting.Indented);
}
const string pattern = @"^(?<lat>(-?(90|(\d|[1-8]\d)(\.\d{1,6}){0,1})))\,{1}(?<long>(-?(180|(\d|开发者_运维百科\d\d|1[0-7]\d)(\.\d{1,6}){0,1})))$";
var check = new Regex(pattern, RegexOptions.IgnorePatternWhitespace);
bool valid = check.IsMatch(lat + "," + lon);
if(valid == false)
{
response.Add("Response", "badlatlon");
return JsonConvert.SerializeObject(response, Formatting.Indented);
}
BasicConfigurator.Configure();
Log.Info("User created city; name:" + cityname + ", state:" + state + ", countryid:" + ctyid + ", timezoneid:" + tzid + ", lat:" + lat + ", lon:" + lon + "");
//will return id of created city or 0.
var result = AtomicCore.CityObject.CreateCity(cityname, state, ctyid, tzid, lat.ToString(), lon.ToString(), string.Empty);
response.Add("Response", result > 0 ? "True" : "errordb");
return JsonConvert.SerializeObject(response, Formatting.Indented);
}
}
}
This is called by a JQuery $.ajax
call:
$.ajax({
type: "POST",
url: "http://<%=Atomic.UI.Helpers.CurrentServer()%>/AtomicService/Assets.asmx/CityCreate",
data: "{'cityname':'" + $('#<%=litCity.ClientID%>').val() + "','state':'" + $('#<%=litState.ClientID%>').val() + "','country':'<%=Session["BusinessCountry"]%>','timezoneoffset':'" + $('#<%=litTimezone.ClientID%>').val() + "','lat':'" + $('#<%=litLat.ClientID%>').val() + "','lon':'" + $('#<%=litLng.ClientID%>').val() + "'}",
contentType: "application/json",
dataType: "json",
success: function (msg) {
if (msg["d"].length > 0) {
var data = $.parseJSON(msg.d);
if (data.Response > 0) {
//everything has been saved, ideally we
//want to get the cityid and pass it back
//to the map page so we can select it...
alert('Hazzah!');
$(this).dialog('close');
} else {
if(data.Response == 'errordb')
{
alert("db");
}
if(data.Response == 'exists')
{
alert("exists");
}
if(data.Response == 'badlatlon')
{
alert("badlatlon");
}
if(data.Response == 'empty')
{
alert("empty");
}
$('#serviceloader').hide();
$('#<%=txtFindMyCity.ClientID%>:input').attr('disabled', false);
$('#erroroccured').show('slow');
$('#errortext').html("Unfortunately, we can't save this right now. We think this city may already exist within Atomic. Could you please check carefully and try again? If this is an obvious error, please contact us and we'll get you started.");
}
} else {
$('#serviceloader').hide();
$('#<%=txtFindMyCity.ClientID%>:input').attr('disabled', false);
$('#erroroccured').show('slow');
$('#errortext').html("Unfortunately, we can't save this right now. Our data service is not responding. Could you perhaps try again in a few minutes? We're very sorry. Please contact us if this continues to happen.");
}
},
error: function (msg) {
$('#serviceloader').hide();
$('#<%=txtFindMyCity.ClientID%>:input').attr('disabled', false);
$('#erroroccured').show('slow');
$('#errortext').html("Unfortunately, we can't save this right now. Perhaps something has gone wrong with some of our data services. Why not try again? If the problem persists, please let us know and we'll get you started.");
}
});
And despite this, I always receive { "Response" : "False" }
. I think this may be a cache problem - but I simply can't get the AJAX to run the service. When I go directly to asset.asmx and invoke the service, the CreateCity
method runs correctly.
This is a classic wood for the trees - I have looked at it too long and I'm giving up the will to live...
Thus, the question is: I'd like the CreateCity
service work correctly, when called by $.ajax
, and not receive a { "Response" : "False" }
response. Can anyone provide any direction, help or assistance on how to achieve this with the code I have provided? Please bear in mind that I believe that my service may be caching (hence the { "Response" : "False" }
response)...
Help, advice, flames and general comments welcomed...
You don't need to manually JSON serialize the response. This is automatically handled by script enabled services. Simply return a strongly typed object from your web method. Same for the input. Also you must ensure to properly URL encode the request parameters. So start by defining models:
public class City
{
public string Cityname { get; set; }
public string State { get; set; }
public string Country { get; set; }
public decimal Timezoneoffset { get; set; }
public decimal Lat { get; set; }
public decimal Lon { get; set; }
}
public class Response
{
public string Message { get; set; }
public bool IsSuccess { get; set; }
}
and then:
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
[ScriptService]
public class Assets : WebService
{
private static readonly ILog Log = LogManager.GetLogger(typeof(Validation));
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public Response CityCreate(City city)
{
var response = new Response();
// ... process and populate the return message,
// set the IsSuccess boolean property which will
// be used by the client (see next...)
return response;
}
}
and on the client side:
$.ajax({
type: 'POST',
url: '<%= ResolveUrl("~/Assets.asmx/CityCreate") %>',
contentType: 'application/json',
dataType: 'json',
data: JSON.stringify({
cityname: $('#<%=litCity.ClientID%>').val(),
state: $('#<%=litState.ClientID%>').val(),
country: '<%=Session["BusinessCountry"]%>',
timezoneoffset: $('#<%=litTimezone.ClientID%>').val(),
lat: $('#<%=litLat.ClientID%>').val(),
lon: $('#<%=litLng.ClientID%>').val()
}),
success: function (result) {
// result.d will represent the response so you could:
if (result.d.IsSuccess) {
...
} else {
...
}
};
});
You can add cache:false
to your %.ajax
call to make sure it isn't being cached. Have you popped a breakpoint on the service to double check what's being passed through from your jQuery?
精彩评论