为什么我动态添加(返回)jQuery处理程序失败?

时间:2016-09-08 21:34:48

标签: jquery ajax rest asp.net-web-api http-status-code-404

当点击一个按钮时,我正在替换页面上的html - 包括css和jQuery在内的一切。 jQuery(按钮单击事件处理程序)第一次工作,但之后没有工作;事实上,它会引发异常。

这个静态ajax jquery回调代码包含:

url: '@Url.RouteUrl(routeName: "QuadrantData", routeValues: new { httpRoute = true, unit = "un", begdate = "bd", enddate = "ed" })'
      .replace("un", encodeURIComponent(_unit))
      .replace("bd", encodeURIComponent(_begdate))
      .replace("ed", encodeURIComponent(_enddate)),

...在运行时转换为此内容:

url: '/api/un/bd/ed'
      .replace("un", encodeURIComponent(_unit))
      .replace("bd", encodeURIComponent(_begdate))
      .replace("ed", encodeURIComponent(_enddate)),

此代码是按钮事件处理程序中ajax调用的一部分。如上所述,它在第一次单击按钮时工作正常,但在响应该单击替换html(和css和jquery)之后,我得到以下内容:

HTTP Error 404.0 - Not Found
The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.

Most likely causes:
The directory or file specified does not exist on the Web server.
The URL contains a typographical error.
A custom filter or module, such as URLScan, restricts access to the file.

Things you can try:
Create the content on the Web server.
Review the browser URL.
Check the failed request tracing log and see which module is calling SetStatus. For more information, click here.

Detailed Error Information:
Module     IIS Web Core
Notification       MapRequestHandler
Handler    StaticFile
Error Code     0x80070002
Requested URL      http://localhost:52194/@Url.RouteUrl(routeName: "QuadrantData", routeValues: new { httpRoute = 
true, Abuelosit = "un", begdate = "2016-08-28", enddate = "2016-08-31" })?_=1473366761632
Physical Path      C:\Projects\ProActWebReports\ProActWebReports\@Url.RouteUrl(routeName: "QuadrantData", routeValues: 
new { httpRoute = true, Abuelosit = "un", begdate = "2016-08-28", enddate = "2016-08-31" })

Logon Method       Anonymous
Logon User     Anonymous
Request Tracing Directory      C:\Users\cshannon\Documents\IISExpress\TraceLogFiles\PROACTWEBREPORTS

More Information:
This error means that the file or directory does not exist on the server. Create the file or directory and try the request again.

已删除哪些资源?哪个“服务器上不存在文件或目录”?实际上,在异常消息中看起来非常可疑的是:

*Abuelosit = "un", begdate = "2016-08-28", enddate = "2016-08-31"* 

应该是:

*unit = "Abuelos", begdate = "2016-08-28", enddate = "2016-08-31"* 

...所以似乎“Abuelos”和“单位”在某种程度上变得混乱/混乱 - Abuelosit =“un”应该 unit =“Abuelos”。如果这是问题,我该如何纠正?

BTW,调用的REST方法(第一次单击按钮)是:

[HttpGet]
[Route("{unit}/{begdate}/{enddate}", Name = "QuadrantData")] 
public HttpResponseMessage GetQuadrantData(string unit, string begdate, 
    string enddate)
{
    _unit = unit;
    _beginDate = begdate;
    _endDate = enddate;
    string beginningHtml = GetBeginningHTML();
    string bodyBeginningHtml = GetBodyBeginHTML();
    string top10ItemsPurchasedHtml = GetTop10ItemsPurchasedHTML();
    string pricingExceptionsHtml = GetPricingExceptionsHTML();
    string forecastedSpendHtml = GetForecastedSpendHTML();
    string deliveryPerformanceHtml = GetDeliveryPerformanceHTML();
    string endingHtml = GetEndingHTML();
    String HtmlToDisplay = string.Format("{0}{1}{2}{3}{4}{5}{6}",
        beginningHtml,
        bodyBeginningHtml,
        top10ItemsPurchasedHtml,
        pricingExceptionsHtml,
        forecastedSpendHtml,
        deliveryPerformanceHtml,
        endingHtml);

    return new HttpResponseMessage()
    {
        Content = new StringContent(
            HtmlToDisplay,
            Encoding.UTF8,
            "text/html"
        )
    };
}

更新

对于后人来说,这是旧代码(已注释掉)和来自里卡多的新代码:

首先,在Index.cshtml(原始html)中:

//$("#btnGetData").click(function () {
$("body").on( "click", "#btnGetData", function() {

在Controller代码中,我动态生成html以替换前一个:

//builder.Append("$(\"#btnGetData\").click(function () {");
builder.Append("$(\"body\").on( \"click\", \"#btnGetData\", function() {");

现在效果很好。

2 个答案:

答案 0 :(得分:0)

根据我的经验,如果AJAX请求第一次正常工作并且第二次失败并且您使用AJAX请求中的新HTML替换原始HTML,则意味着原始点击处理程序已经消失。

如果您将点击处理程序附加到按钮,请执行以下操作:

$("button.someAction").click(function() {
    $.ajax("/api/a/b/c");
    // etc.
});
一旦AJAX请求完成,它们就会消失。当您单击不再具有事件处理程序的按钮时,它会尝试向服务器提交一些内容并获得一个奇怪的URL。

您应该使用.on()而不是click()为其分配。 .on()应该分配给在新请求中替换其内部的容器,如下所示。

$("#container").on( "click", "button.someAction", function() {
  $.ajax("/api/a/b/c");
});

这样,按钮上的操作将通过所有请求进行维护。

希望它有所帮助。

答案 1 :(得分:0)

你的问题在这里:

url: '@Url.RouteUrl(routeName: "QuadrantData", routeValues: new { httpRoute = true, unit = "un", begdate = "bd", enddate = "ed" })'
      .replace("un", encodeURIComponent(_unit))
      .replace("bd", encodeURIComponent(_begdate))
      .replace("ed", encodeURIComponent(_enddate)),

上面的代码,第一次被解释并正确地成为您期望的URL。

第二次将其视为字符串

该网址包含该字符串您的API网址:

Requested URL      http://localhost:52194/@Url.RouteUrl(routeName:
"QuadrantData", routeValues: new { httpRoute = 
true, Abuelosit = "un", begdate = "2016-08-28", 
enddate = "2016-08-31" })?_=1473366761632

这就是为什么" Unit = abuelos"成为" abuelosit"。因为你取代了" un"和单词" unit"包含" un"。所以"单位"成为" abuelosit" (正如"独特"将成为" abuelosique")。

您需要每次都解析@variable ,或者将其保存在某处,以防万一,我还建议您使用一些更独特的字符串:

var baseUrl = '@Url...unit="_Xx_un_xX_"...

然后你可以每次复制baseUrl:

url = baseUrl.replace('_Xx_un_xX_', encodeURIComponent(_unit)...