簡體   English   中英

通過AJAX調用將cshtml頁面中的'TimeStamp'變量傳遞給控制器

[英]passing the 'TimeStamp' variable from cshtml page to controller via AJAX call

我是MVC中的EF新手。 我需要在應用程序中實現並發檢查。

我正在關注有關EF中並發處理的內置支持的MSDN幫助: http : //www.asp.net/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency在ASP.NET MVC應用程序中使用實體框架

但就我而言,我正在進行部分更新,因此我使用AJAX調用服務器端方法來執行此操作。 在此服務器端方法中,我需要實現並發檢查。

在學習完本教程之后,我對代碼進行了必要的更改:

首先,在數據庫中,我創建了timestamp列:

ALTER TABLE dbo.Job
ADD RowVersion rowversion NULL;

在實體類中:

[Timestamp]
public byte[] RowVersion { get; set; }

在我的Mapping類中(使用流利的api):

this.Property(t =>     
    t.RowVersion).HasColumnName("RowVersion").IsConcurrencyToken();

在我的視圖模型類中:

[Timestamp]
public byte[] RowVersion { get; set; }

在我的視圖文件中:

@Html.HiddenFor(x => x.RowVersion)

在JS文件中(ajax調用):

function UpdateJobTransferStatus(jobTransferStatusId, newJobTransferSatusId, currentAction, statusName) {
    var hdnJobId = $("#JobId").val();
    //var hdnRowVersion = $("#RowVersion").val();
    var hdnAccountingId = $("#hdnAccountingSystemId").val();
    $.ajax(
           {
               type: "GET",
               url: ResolveUrl("~/Api/Job/UpdateJobTransferStatus"),
               dataType: "json",
               contentType: "application/json; charset=utf-8",
               data: { jobId: hdnJobId, currentAction: currentAction, jobTransferStatusId: newJobTransferSatusId, accountingSystemId: hdnAccountingId },//,rowVersion: hdnRowVersion },
               success: function (data) {
                   GetPreviousOrNextStatus(jobTransferStatusId, currentAction, statusName, hdnAccountingId);
               },
               error: function (result) {

               }
           });

}

最終在我的控制器中(在我的ajax調用中):我按照MSDN添加了名稱空間( using System.Data.Entity.Infrastructure;

[System.Web.Http.HttpGet]
public HttpResponseMessage UpdateJobTransferStatus(int jobId, int currentAction,
    int jobTransferStatusId, short accountingSystemId, byte[] rowVersion)

在這里,無論我是否在AJAX調用中將值作為參數發送,我總是得到' byte[] rowVersion '的' null '(我粘貼在代碼段的注釋中)。

我已經檢查過,每次成功執行插入/更新操作都會在DB中更新該列,並且視圖模型也在每次頁面加載時從DB獲取該RowVersion列的最新值。

在MSDN示例中,他們已經提交了表單,但是我使用AJAX調用來完成,除了我試圖使各個方面保持相同。

發送整個視圖模型對象可能為我完成了工作,但是我不需要整個對象來執行我的部分更新(盡管我沒有嘗試過)。

如何將rowVersion傳遞給ajax調用?

您應該將其作為字符串發送,並將其轉換回服務器上的字節數組。 這是因為HTML頁面將它作為字符串存儲在base64格式的input標簽(隱藏類型)中。 在c#端稍作改動即可解決該問題。

查看:無需更改現有代碼,傳入byte[]時, HiddenFor的默認行為是將其轉換為Base 64字符串

C#代碼

[System.Web.Http.HttpGet]
public HttpResponseMessage UpdateJobTransferStatus(int jobId, int currentAction, int jobTransferStatusId, short accountingSystemId, string rowVersion){
    var rowVersionBytes = System.Convert.FromBase64String(rowVersion); // convert to byte array
}

Javascript:

function UpdateJobTransferStatus(jobTransferStatusId, newJobTransferSatusId, currentAction, statusName) {
    var hdnJobId = $("#JobId").val();
    var hdnRowVersion = $("#RowVersion").val(); // this will be a string
    var hdnAccountingId = $("#hdnAccountingSystemId").val();
    $.ajax(
       {
           type: "GET",
           url: ResolveUrl("~/Api/Job/UpdateJobTransferStatus"),
           dataType: "json",
           contentType: "application/json; charset=utf-8",
           data: { jobId: hdnJobId, currentAction: currentAction, jobTransferStatusId: newJobTransferSatusId, accountingSystemId: hdnAccountingId, rowVersion: hdnRowVersion }
           success: function (data) {
               GetPreviousOrNextStatus(jobTransferStatusId, currentAction, statusName, hdnAccountingId);
           },
           error: function (result) {
           }
       });
}

最后,因為您實際上正在執行更新,所以它應該是HttpPost或HttpPut而不是HttpGet。

  • HttpGet僅應在檢索數據且未更改任何數據時使用。
  • 如果可以多次調用相同的修改而獲得完全相同的預期結果(也稱為冪等),則應使用HttpPut,通常用於更新。
  • 每次調用相同的調用會導致不同的結果(在服務器上或在響應中)時,應使用HttpPost,通常用於Creates

我在您的sql中看到另一個錯誤,這可能會導致現有數據出現意外問題。 RowVersion列應標記為NOT NULL因為即使在現有表上,當指定rowversion類型時,Sql Server也會使用值填充所有現有記錄。

ALTER TABLE dbo.Job
ADD RowVersion rowversion NOT NULL

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM