传递'TimeStamp'变量通过AJAX调用从cshtml页面到控制器

本文关键字:cshtml 控制器 变量 TimeStamp 传递 AJAX 调用 | 更新日期: 2023-09-27 17:53:11

我是新来的EF在MVC。我需要在应用程序中实现并发检查。

我是按照MSDN帮助关于内置支持并发处理EF: http://www.asp.net/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application

但在我的例子中,我做的是局部更新,所以我使用AJAX调用服务器端方法来完成。在这个服务器端方法中,我需要实现并发性检查。

按照教程,我在代码中做了必要的修改:

首先在DB中创建时间戳列:

ALTER TABLE dbo.Job
ADD RowVersion rowversion NULL;

在实体类:

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

在我的Mapping类(使用fluent api):

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

在我的视图模型类:

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

in my view file:

@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)

在这里,我总是得到' null '为' byte[] rowVersion ',不管我是否在AJAX调用中发送值作为参数(我在我的代码片段中保留了注释,我粘贴在这里)。

我已经检查过了,列正在DB中更新,每次成功的插入/更新执行,视图模型也在每个页面加载上从DB中获取这个RowVersion列的最新值。

在这里的MSDN示例中,他们已经提交了表单,但我正在使用AJAX调用,除了我试图保持每个方面相同。

发送整个视图模型对象可能会为我做这项工作,但我不需要整个对象来执行我的部分更新(我还没有尝试过)。

我如何将rowVersion传递给ajax调用?

传递'TimeStamp'变量通过AJAX调用从cshtml页面到控制器

您应该将其作为字符串发送,并将其转换回服务器上的字节数组。这是因为HTML页面以base64格式将其作为字符串存储在input标记(类型为hidden)中。在c#端做个小改动就可以解决这个问题。

视图:不需要改变你现有的代码,HiddenFor的默认行为,当一个byte[]被传入是转换为一个base64字符串

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,这通常用于create

我在你的sql中看到一个错误,这可能会对现有数据产生意想不到的问题。列RowVersion应该被标记为NOT NULL,因为即使在现有表上,当指定rowversion类型时,Sql Server也会用一个值填充所有现有记录。

ALTER TABLE dbo.Job
ADD RowVersion rowversion NOT NULL