【问题标题】:Using unobtrusive JavaScript, parameter isn't null, but its values are使用不显眼的 JavaScript,参数不是 null,但它的值是
【发布时间】:2013-02-16 16:18:20
【问题描述】:

当我的 JavaScript 与我的 cshtml 文件位于同一页面时,这是有效的:

function SaveEntity() {
    // more code here
    alert(entity.FirstName);  // this shows that entity's properties have values
    $.post('/Home/Save', { entity: entity }, SaveComplete);
}

该代码现在位于单独的 Index.js 文件中。在我的控制器中,实体参数不为空,但它的所有值都是。为什么现在会发生这种情况?

控制器签名:

public ActionResult Save(Entity entity)
{ // method here }

编辑 - Fiddler 截图

编辑

这是 Entity 类,由 Entity Framework 生成:

public partial class Entity
{
    public Entity()
    {
        this.Contacts = new HashSet<Contact>();
    }

    public int EntityId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Address { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string ZipCode { get; set; }
    public string Company { get; set; }
    public string LastModifiedUser { get; set; }
    public Nullable<System.DateTime> LastModifiedTime { get; set; }
    public string Notes { get; set; }

    public virtual ICollection<Contact> Contacts { get; set; }
}

编辑

完整的 Index.js,带有完整的 SaveEntity() 方法:

var _currentEntities;

    $(function () {
        // Hide the ID column (column 1)
        $('#tableContacts').dataTable({
            "aoColumnDefs": [
                { "bSearchable": false, "bVisible": false, "aTargets": [0] }
            ],
            "bLengthChange": false, // don't show the number of records to show per page
            "bFilter": false,  // don't show the search/filter box
            "iDisplayLength": 5
        });

        $('#waitImage').hide();
        // Show the letters of the alphabet, with a link to call GetEntries() for each of them.
        for (var i = 65; i <= 90; i++) {
            $('#headerAlphabet').append('<a href=\"#\" onclick=\"GetEntries(\''
                + String.fromCharCode(i) + '\')\">'
                + String.fromCharCode(i) + '</a> ');
        }
    });

            function GetEntries(firstLetter) {
                // code here
            }

            function EntriesReceived(entities) {
                // code here
            }

            function DisplayPerson(entityId) {
                // code here
            }

        function SaveEntity() {
            // Grab our entity
            var entity;
            for (var i = 0; i < _currentEntities.length; i++) {
                if (_currentEntities[i].EntityId == $('#txtEntityId').val()) {
                    entity = _currentEntities[i];
                    break;
                }
            }

            entity.FirstName = $('#txtFirstName').val();
            entity.LastName  = $('#txtLastName').val();
            entity.Address   = $('#txtAddress').val();
            entity.City      = $('#txtCity').val();
            entity.State     = $('#txtState').val();
            entity.ZipCode   = $('#txtZipCode').val();
            entity.Company   = $('#txtCompany').val();
            entity.Notes     = $('#txtNotes').val();

            alert(entity.FirstName);

            $.post('/Home/Save', { entity: entity }, SaveComplete);
        }

            function SaveComplete(saveStatus) {
                alert(saveStatus);
            }

            function CancelChanges() {
                alert('Cancel will be done here.');
            }

【问题讨论】:

  • 愚蠢的问题,但您确实将代码包装在 $(document).ready(function () {... 中,对吧?
  • 我没有。有必要吗?
  • 是的,否则你的页面没有完全加载,并不是所有的javascript都被实例化、执行了。
  • 但是在页面加载并且用户进行更改并点击保存按钮之前,不会调用该方法。警报显示entity 确实设置了它的名字。那么,鉴于此,我仍然需要包装它吗?
  • 好吧,不是必须的,但是如果没有看到该页面的所有 js,就很难判断。不过,您可以尝试包装它并进行测试。您描述的症状看起来像是 javascript 没有完全加载的地方

标签: c# javascript jquery asp.net-mvc-4


【解决方案1】:

首先,在进行任何类型的 ajax 提交时,您都希望在 Http 调试器(如 Fiddler)中查看实际请求。你想看看它是否真的发布了你认为的值。这将帮助您确定问题出在您的 javascript 中还是在服务器上。现在,你不知道。

请参阅:ThisThis

其次,您应该发布您的服务器端实体定义。

编辑:

这似乎是 jQuery 默认序列化对象的方式存在问题,该方式使用括号表示法,不适用于默认模型绑定器。您必须使用 Dave 提到的传统:true 参数。

更多关于Here。以下将解决您的问题。 $.param 方法与 true 参数一起使用时将强制执行传统序列化。

$.post('/Home/Save', $.param(entity, true), SaveComplete);. 

【讨论】:

  • 我现在和fiddler一起看看。我发布了 Entity 类的定义。谢谢。
  • 使用 Fiddler 时,在 Inspectors 选项卡的 Body 部分中,我看到了实体及其所有值。由于我不熟悉 Fiddler,所以我不确定这是什么意思。
  • @BobHorn - 发布 fiddler 检查器窗口的屏幕截图,显示您的帖子值。
  • 我刚刚发布了它。 +1 提示和帮助,顺便说一句。
  • 我可以试试。不过我确实做出了改变。当我将 JavaScript 移到它自己的页面时,这条线不再起作用:$.post('@Url.Action("Save")', entity, SaveComplete); 所以我用$.post('/Home/Save', { entity: entity }, SaveComplete);替换它
【解决方案2】:

我犹豫了,b/c 我的回答没有说​​明为什么这会在 View 中起作用,但在 js 文件中会失败。但我会使用 ajax 与 post 调用来设置 json 和传统的:

 

$.ajax({
    type: 'POST',
    url: '/Home/Save',
    dataType: 'json',
    traditional: true,
    data: entity , //$.toJSON(data),
    success: function (data) {
          SaveComplete(data);
    }
});

【讨论】:

  • 谢谢。我可以试一试。你对$.toJSON(Data)的评论,我应该这样做而不是data: entity吗?
  • @BobHorn,不,这不是来自我复制和粘贴的其他代码。大多数编码错误都来自那个陷阱;)只需使用数据:实体。如果失败,我们可能会尝试 toJson。无论哪种方式,我都确信这是一个编码问题。
  • 小费+1,尽管我还没有机会尝试。感谢帮助...
  • 您的建议已将true 传递给SaveComplete()。有没有办法恢复我的方式,以便SaveComplete() 从控制器方法中获取结果?
  • @BobHorn,是的,您可以从 .ajax() 中获取数据。查看我修改后的答案。
猜你喜欢
  • 2021-09-05
  • 2022-06-14
  • 1970-01-01
  • 2021-06-24
  • 2021-10-28
  • 2021-11-12
  • 2022-01-03
  • 2022-01-20
  • 1970-01-01
相关资源
最近更新 更多