2015-08-28 64 views
0

我有一個javascript函數,用於對我的控制器函數執行Ajax調用。 javascript足夠通用,我可以將它用於多個控件。我有兩個使用腳本的區域。一個工作,一個不工作。我相信這是被調用的MVC控制器的足跡。javascript調用了類似的MVC操作,AntiForgery可以在其中一個上工作,而不是其他工作

的JavaScript看起來像這樣:

$(Document).on("click",".delete-link",function (event) { 
    var deleteLink = $(this); 
    deleteLink.hide(); 
    var confirmButton = deleteLink.siblings(".delete-confirm"); 
    confirmButton.show(); 

    var cancelDelete = function() { 
     removeEvents(); 
     showDeleteLink(); 
    }; 

    var deleteItem = function() { 
     removeEvents(); 
     confirmButton.hide(); 
     var url = '/' + confirmButton.attr('data-delete-controller') + '/' + confirmButton.attr('data-delete-action') + '/' + confirmButton.attr('data-delete-id'); 
     $.post(
      url, 
      AddAntiForgeryToken({ id: confirmButton.attr('data-delete-id') })) 
      .done(function() { 
       var parentRow = deleteLink.closest(".removable-row");//"tr:first, li:first"); 
       parentRow.fadeOut('fast', function() { 
        parentRow.remove(); 
       }); 
      }).fail(function (data) { 
       alert("error"); 
      }); 
     return false; 
    }; 

    var removeEvents = function() { 
     confirmButton.off("click", deleteItem); 
     $(document).on("click", cancelDelete); 
     $(document).off("keypress", onKeyPress); 
    }; 

    var showDeleteLink = function() { 
     confirmButton.hide(); 
     deleteLink.show(); 
    }; 

    var onKeyPress = function (e) { 
     //Cancel if escape key pressed 
     if (e.which == 27) { 
      cancelDelete(); 
     } 
    }; 

    confirmButton.on("click", deleteItem); 
    $(document).on("click", cancelDelete); 
    $(document).on("keypress", onKeyPress); 

    return false; 
}); 

AddAntiForgeryToken = function (data) { 
    data.__RequestVerificationToken = $('input[name=__RequestVerificationToken]').val(); 
    return data; 
}; 

所以MVC視圖和控制器的行動,工作是這樣定義的:

<div class="row"> 
    @Html.HiddenFor(model => model.CustomFieldOptionId) 
    @Html.HiddenFor(model => model.CustomFieldId) 
    @Html.HiddenFor(model => model.SortOrder, new { @class = "SortOrder" }) 
    @Html.HiddenFor(model => model.IsActive) 

    @Html.ValidationMessageFor(model => model.OptionLabel, "", new { @class = "text-danger" }) 

    <div class="col-md-2"> 
     @Html.LabelFor(model => model.OptionLabel, htmlAttributes: new { @class = "control-label" }) 
    </div> 
    <div class="col-md-7"> 
     @Html.EditorFor(model => model.OptionLabel, new { htmlAttributes = new { @class = "form-control" } }) 
    </div> 
    <div class="col-md-3"> 
     <input type="button" value="Delete" class="btn delete-link" /> 
     <div class="btn btn-primary delete-confirm" style="display: none" 
      data-delete-id="@Model.CustomFieldOptionId" 
      data-delete-controller="customforms" 
      data-delete-action="_OptionEditorRowDelete">Confirm Delete</div> 
    </div> 
</div> 

控制器:

[HttpPost, ActionName("_OptionEditorRowDelete")] 
[ValidateAntiForgeryToken] 
public ActionResult _OptionEditorRowDelete(int id) 
{ 
    var custFieldOption = db.CustomFieldOptions.Find(id); 
    if (custFieldOption == null) return null; 
    custFieldOption.IsActive = false; 
    db.Entry(custFieldOption).State = EntityState.Modified; 
    db.SaveChanges(); 

    return null; 
} 

的一個不工作定義如下:

@foreach (var item in Model) { 
    <tr> 
     <td> 
      @Html.HiddenFor(modelItem => item.ProfileId) 
      @Html.DisplayFor(modelItem => item.ProfileIdentifierValue) 
     </td> 
     <td> 
      @Html.DisplayFor(modelItem => item.IsPrimary) 
     </td> 
     <td> 
      @Html.ActionLink("Edit", "profileemailsedit", new { id = item.ProfileIdentifierId }) | 
      @Html.ActionLink("Delete", "_ProfileEmailsDelete", new { id = item.ProfileIdentifierId }, new { @class = "delete-link" }) 
      <a class="delete-link" href="@Url.Action("_ProfileEmailsDelete", new { id = item.ProfileIdentifierId })">Delete</a> 
      <input type="button" value="Delete" class="btn delete-link" /> 
      <div class="btn btn-primary delete-confirm" style="display: none" 
       data-delete-id="@item.ProfileIdentifierId" 
       data-delete-controller="profiles" 
       data-delete-action="_ProfileEmailsDelete">Confirm Delete</div> 
     </td> 
    </tr> 
} 

控制器:

[HttpPost] 
[ValidateAntiForgeryToken] 
public ActionResult _ProfileEmailsDelete(int id) 
{ 
    var profIdentifier = db.ProfileIdentifier.Find(id); 
    if (profIdentifier == null) return null; 
    profIdentifier.IsActive = false; 
    db.Entry(profIdentifier).State = EntityState.Modified; 
    db.SaveChanges(); 

    return null; 
} 

正如你所看到的控制器非常相似。然而,_ProfileEmailsDelete得到的這個JavaScript錯誤:服務器500錯誤的

POST http://localhost:63595/profiles/_ProfileEmailsDelete/168 500 (Internal Server Error)

部分是:

[HttpAntiForgeryException]: The required anti-forgery form field "__RequestVerificationToken" is not present. at System.Web.Helpers.AntiXsrf.TokenValidator.ValidateTokens(HttpContextBase httpContext, IIdentity identity, AntiForgeryToken sessionToken, AntiForgeryToken fieldToken) at System.Web.Helpers.AntiXsrf.AntiForgeryWorker.Validate(HttpContextBase httpContext) at System.Web.Helpers.AntiForgery.Validate()

我不知道爲什麼防僞工作的一個,而不是其他。

回答

0

500錯誤是您的服務器的Ajax響應,而不是您的JavaScript。實際的問題並不在我身上,但大多數情況下,當我看到這種類型的行爲時,它最終會成爲導致它出現的視圖渲染中的東西。例如,試圖引用視圖中null值的集合的值將採取這種方式。使用瀏覽器開發工具的流量分析器功能有時可以幫助揭示真正的問題。

0

第一個例子是局部視圖。父視圖中有這樣的:

@Html.AntiForgeryToken() 

我補充說,該視圖的第二個例子,然後的JavaScript可以正確地獲得令牌傳遞回來的$ .post的命令。

相關問題