2013-03-15 37 views
1

我有一個創建視圖和編輯視圖,幾乎完全相同。它們都包含級聯下拉列表。第二個列表的值是正在創建或編輯的數據的一部分。第一個下拉列表僅僅是第二個列表中值的過濾器。使用相對URL的Ajax Jquery post

這兩個視圖都使用相同的腳本,它爲第一個下拉列表中的更改事件附加一個處理程序。處理程序向控制器中的方法發佈帖子。

當我運行創建視圖並更改第一個下拉列表時,它工作正常。第二個列表已更新。當我在編輯視圖中嘗試時,出現500內部服務器錯誤。

我看過Firebug。我在處理程序中休息了一會兒。它在選擇時會在兩種情況下被調用。發送的數據看起來是相同的($(this).serialize()看起來相同)。
螢火蟲控制檯說: 所需的防僞表格字段" __RequestVerificationToken "不存在。 我沒有看到我需要一個調用此方法,但當然有其他方法(操作)需要一個。

雖然昨天之前我從來沒有用過Firebug,但如果知道如何,可能還有很多可以檢查的東西。 (我對MVC和網絡應用程序一般都是全新的。)

我也在我的控制器方法中有一個突破。它僅在創建視圖中調用時纔會被觸發。

在絕望中,我嘗試將呼叫類型更改爲GET而不是POST。這導致一個名爲叫做不同名稱的控制器方法(HttpGet EDIT),我覺得這至少令人不安。

我覺得我調用的方法沒有找到(在編輯中)。相反,嘗試使用其他方法(我不知道哪一種方法),並且該方法需要防僞標記。

編輯: 的新鮮空氣的夾持,我意識到,我當然知道哪些動作被調用:這是HttpPost編輯操作(這需要一個防僞標記)。這當然是正常的提交行爲。調試器中的快速運行證實了這一點。由於這個原因,這次通話失敗的事實很明顯。但爲什麼這個動作被調用呢?

更新: Firebug控制檯指示正在調用不同的操作。在創建案例中是.../_ an_alphanumeric_literal_/Order/PopulateAvtalDDL,這正是我想要的。在編輯案例中,它是.../_ an_alphanumeric_literal_/Order/編輯/PopulateAvtalDDL。這是一個路由問題嗎?如果是這樣,我仍然不明白。兩個調用是由相同的劇本量身定做的,我只有一個路由設置(基本爲MVC 4的缺省路由):

routes.MapRoute(
      name: "Default", 
      url: "_an_alphanumeric_literal_/{controller}/{action}/{id}", 
      defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } 
     ); 

UPDATE: 我終於找到了一些相關的信息:Relative URLs in AJAX requests。 然後它是一個路由問題。如果我將腳本URL從相對的PopulateAvtalDDL改爲絕對的/_an_alphanumeric_literal_/Order/PopulateAvtalDDL,它可以在兩個視圖中使用。引用鏈接中的答案指出,路徑與瀏覽器中的當前URL相關。在我的情況下,是http://localhost:51852/_an_alphanumeric_literal_/Order/Edit/6?markedOrderId=0http://localhost:51852/_an_alphanumeric_literal_/Order/Create?markedOrderId=0。當構建相對URL時,最後一個段被替換。在創建案例創建,但在編輯的情況下它是(編輯的數據的ID)。我明白髮生了什麼事!

我當時的解決辦法:

添加過濾器周圍DDL(在兩個視圖)一個div設置的網址:<div id="kundDDL" data-url="@Url.Action("PopulateAvtalDDL", "Order")">。然後在腳本中訪問該URL url: $('#kundDDL').data('url')

這裏是爲創建視圖的代碼:

@model AssetMgmt.Models.OrderEditVM 
@using AssetMgmt.Models; 

@{ 
    ViewBag.Title = MsgString.LblCreateNew + " order"; 
} 

<h2>@ViewBag.Title</h2> 


@using (Html.BeginForm(null, null, FormMethod.Post)) 
{ 
    @Html.ValidationSummary(true) 
    @Html.AntiForgeryToken() 

    @Html.HiddenFor(m => m.MarkedOrderId) 

    <fieldset> 
     <legend>Filter</legend> 

     <div class="editor-label"> 
      @Html.LabelFor(m => m.KundId) 
     </div> 
     <div class="dropdownlist"> 
      @Html.DropDownListFor(m => m.KundId, Model.KundDropDown, string.Empty) 
     </div> 
     <div class="dropdown-validation-error"> 
      @Html.ValidationMessageFor(model => model.KundId) 
     </div> 
    </fieldset> 

    <fieldset> 
     <legend>Orderdata</legend> 

     <div id="avtalDDL"> 
      @Html.Partial("_AvtalDDL") 
     </div> 

     <div class="editor-label"> 
      @Html.LabelFor(model => model.Ordernummer) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.Ordernummer) 
      @Html.ValidationMessageFor(model => model.Ordernummer) 
     </div> 

     <div class="editor-label"> 
      @Html.LabelFor(model => model.Beställare) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.Beställare) 
      @Html.ValidationMessageFor(model => model.Beställare) 
     </div> 

     <div class="editor-label"> 
      @Html.LabelFor(model => model.Orderdatum) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.Orderdatum) 
      @Html.ValidationMessageFor(model => model.Orderdatum) 
     </div> 

     <p> 
      <input type="submit" value="@MsgString.LblSave" /> 
     </p> 
    </fieldset> 
} 
<div> 
    @Html.ActionLink(MsgString.LblBack, "Index", new { markedOrderId = Model.MarkedOrderId }) 
</div> 

@section Scripts { 
    @Scripts.Render("~/bundles/jqueryval") 
    <script type="text/javascript" src="~/Scripts/jquery.maskedinput-1.3.1.min.js"></script> 
    <script type="text/javascript" src="~/Scripts/assetMgmtMasks.js"></script> 
    <script src="~/Scripts/assetMgmtOrderPopulateDDL.js" type="text/javascript"></script> 
} 

下面是編輯觀點:

@model AssetMgmt.Models.OrderEditVM 
@using AssetMgmt.Models; 

@{ 
    ViewBag.Title = MsgString.LblEdit + " order"; 
} 

<h2>@ViewBag.Title</h2> 

@using (Html.BeginForm(null, null, FormMethod.Post)) 
{ 
    @Html.ValidationSummary(true) 
    @Html.AntiForgeryToken() 

    @Html.HiddenFor(model => model.OrderId) 
    @Html.HiddenFor(model => model.Timestamp) 
    @Html.HiddenFor(model => model.MarkedOrderId) 

    <fieldset> 
     <legend>Filter</legend> 

     <div class="editor-label"> 
      @Html.LabelFor(m => m.KundId) 
     </div> 
     <div class="dropdownlist"> 
      @Html.DropDownListFor(m => m.KundId, Model.KundDropDown, string.Empty) 
     </div> 
     <div class="dropdown-validation-error"> 
      @Html.ValidationMessageFor(model => model.KundId) 
     </div> 
    </fieldset> 

    <fieldset> 
     <legend>Orderdata</legend> 

     <div id="avtalDDL"> 
      @Html.Partial("_AvtalDDL") 
     </div> 

     <div class="editor-label"> 
      @Html.LabelFor(model => model.Ordernummer) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.Ordernummer) 
      @Html.ValidationMessageFor(model => model.Ordernummer) 
     </div> 

     <div class="editor-label"> 
      @Html.LabelFor(model => model.Beställare) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.Beställare) 
      @Html.ValidationMessageFor(model => model.Beställare) 
     </div> 

     <div class="editor-label"> 
      @Html.LabelFor(model => model.Orderdatum) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.Orderdatum) 
      @Html.ValidationMessageFor(model => model.Orderdatum) 
     </div> 

     <p> 
      <input type="submit" value="@MsgString.LblSave" /> 
     </p> 
    </fieldset> 
} 

<div> 
    @Html.ActionLink(MsgString.LblBack, "Index", new { markedOrderId = Model.MarkedOrderId }) 
</div> 

@section Scripts { 
    @Scripts.Render("~/bundles/jqueryval") 
    <script type="text/javascript" src="~/Scripts/jquery.maskedinput-1.3.1.min.js"></script> 
    <script type="text/javascript" src="~/Scripts/assetMgmtMasks.js"></script> 
    <script src="~/Scripts/assetMgmtOrderPopulateDDL.js" type="text/javascript"></script> 
} 

腳本:

$(document).ready(function() { 
    //Kund select 
    $('#KundId').change(function() { 
     $.ajax({ 
      url: 'PopulateAvtalDDL', 
      type: 'post', 
      data: $(this).serialize(), 
      success: function (result) { 
       $('#avtalDDL').html(result); 
      }, 
      error: function (xhr, ajaxOptions, thrownError) { 
       alert(xhr.status); 
       alert(xhr.statusText); 
       alert(thrownError); 
      } 
     }); 
     return false; 
    }); 
}); 

控制方法的簽名:

[HttpPost] 
public PartialViewResult PopulateAvtalDDL(int kundId = 0) 

回答

0

我終於找到了一些相關信息:AJAX請求中的相對URL。這是一個路由問題。如果我將腳本URL從相對的PopulateAvtalDDL更改爲絕對/ _an_alphanumeric_literal_/Order/PopulateAvtalDDL,它可以在兩個視圖中使用。引用鏈接中的答案指出,路徑與瀏覽器中的當前URL相關。在我的情況下,這是
http://localhost:51852/_an_alphanumeric_literal_/Order/Edit/6?markedOrderId=0

http://localhost:51852/_an_alphanumeric_literal_/Order/Create?markedOrderId=0。當構建相對URL時,最後一個段被替換。在Create的Create情況下,但在Edit情況下它是6(編輯數據的ID)。

我當時的解決辦法:

添加過濾器周圍DDL(在兩個視圖)一個div設置的網址:
<div id="kundDDL" data-url="@Url.Action("PopulateAvtalDDL", "Order")">
然後在腳本訪問那個URL
url: $('#kundDDL').data('url')