【问题标题】:ASMX Seems To CacheASMX 似乎缓存
【发布时间】:2011-04-13 11:34:51
【问题描述】:

我有以下 ASMX 网络服务:

// 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);
        }
    }
}

这是由 JQuery $.ajax 调用调用的:

$.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.");
                            }
                        });

尽管如此,我总是收到{ "Response" : "False" }。我认为这可能是一个缓存问题——但我根本无法让 AJAX 运行该服务。当我直接进入asset.asmx并调用服务时,CreateCity方法运行正常。

这是树木的经典木材 - 我看了太久,我正在放弃生存的意志......

因此,问题是:我希望CreateCity 服务在被$.ajax 调用时能够正常工作,并且不会收到{ "Response" : "False" } 响应。任何人都可以就如何使用我提供的代码实现这一目标提供任何指导、帮助或帮助吗?请记住,我相信我的服务可能正在缓存(因此{ "Response" : "False" } 响应)...

欢迎帮助、建议、火焰和一般 cmets...

【问题讨论】:

  • 如果这是 MVC,我建议您需要一个 OutputCache 属性/@ 指令 - 默认情况下,它假定使用相同参数发出的相同请求应该返回相同的结果,除非您添加元数据进行更改那。我不知道这些是否适用于 ASMX。

标签: c# ajax web-services


【解决方案1】:

您不需要手动 JSON 序列化响应。这由启用脚本的服务自动处理。只需从您的 Web 方法返回一个强类型对象。输入相同。此外,您必须确保正确地对请求参数进行 URL 编码。所以从定义模型开始:

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; }
}

然后:

[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;
    }
}

在客户端:

$.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 {
             ...
        }
    };
});

【讨论】:

  • 优秀的答案。我要试试这个,看看这是否能解决我遇到的问题。非常感谢;)
  • 绝对很棒的答案。它也很完美:)谢谢! +1
【解决方案2】:

您可以将cache:false 添加到您的%.ajax 调用中,以确保它没有被缓存。您是否在服务上弹出断点以仔细检查您的 jQuery 传递的内容?

【讨论】:

  • 感谢大卫的回复,由于某种原因,我无法通过 VS2010 或附加进程来调试 .asmx。这可能与我目前打开的另一个问题有关:stackoverflow.com/questions/5611305/… ... Wood for the Trees David,wood for the trees! :)
  • 顺便说一句,我使用 Fiddler 查看来回传递的内容,一切似乎完全正常。事实上,我接受了请求及其值并直接调用了服务(/assets.asmx?op=CityCreate),它工作了......
  • 啊,我明白了。也对那个发表评论。 :)
  • 您不需要将cache: false 与 POST 请求一起使用,因为与 GET 请求相反,它们不应被浏览器缓存。
  • @Darin 啊,当然。在这种情况下,进入调试器建议仍然有效。 :)
猜你喜欢
  • 2016-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-05
  • 1970-01-01
相关资源
最近更新 更多