【问题标题】:How to pass Model and json object to controller Action如何将模型和 json 对象传递给控制器​​动作
【发布时间】:2012-05-22 00:44:43
【问题描述】:

我寻找这个问题的解决方案很长时间,但我找不到任何东西。我已将强类型定义为我正在使用的控制器/视图的模型;问题是模型引用了其他复杂类型,所以我需要部分更新该模型的部分。例如,在页面的一个选项卡中,我部分获得了另一个视图,该视图带来了带有一些选择的网格;另一部分带来另一部分;所以在用户选择他们的选项并提交后,我需要将所有这些小块发送到 post 操作。

我已经创建了我需要的 JSON 对象并将其发送到控制器。在行动中,我成功获得了模型,但 JSON 并没有出现在行动中。那么如何将该 JSON 作为控制器操作的附加参数传递给视图?

我也已经用 fiddler 检查了请求,并且正在发送 JSON。对象是否在特殊集合中传递?


当然。视图期望或被强类型化为模型,在这种情况下是“提供者”实体。该实体具有原始类型和复杂类型。因为实体仍在创建过程中,所以当达到创建后操作时,我需要传递部分对象来完成实体。 以下是模型的一部分:

public class Provider2 : IProvider
{
    public int Id { get; set; }
    public bool IsApproved { get; set; }
    public string RejectionNotes { get; set; }
    public string Name { get; set; }
    public string Phone { get; set; }
    public string Fax { get; set; }
    public string Email { get; set; }
    public int OfficeAddressId { get; set; }
    public virtual Address Address { get; set; }
    public virtual ICollection<Chain> ProviderChain { get; set; }
    public virtual ICollection<ProviderContact> ProviderContacts { get; set; }
    public virtual ICollection<ExaminationPrice> ExaminationPrices { get; set; }
}

整数、字符串等简单类型没有问题。 如您所见,有集合和复杂类型,这些类型是从部分视图中检索的,并且那一刻是单独的实体,因此我需要在提交时将它们包装在 json 或其他对象(例如 JSON)中并获取它达到创建操作的那一刻:

[HttpPost]
public ActionResult Create(Provider provider, Another object to be passed???)
{
    if (ModelState.IsValid)
    {
        _repository.Save(provider);
        return RedirectToAction("Index");
    }
    return View(provider);
}

原始类型和地址属性在模型上映射,所以它们没有问题,但集合没有映射,所以这就是我尝试传递一个附加对象(如 json)来包装所有部分的原因从纯 HTML 到 javascript 对象,因为它们没有直接映射到模型。

所以,通过这个 javascript 我将我需要的数据发送到视图并发送它,但显然该操作没有接收到 json 对象。

  $(function () {
        $("#ButtonSave").click(function () {
            var prices = getPrices();

            if (prices != null) {
                $.ajax({
                    url: '/Provider/Create',
                    type: 'POST',
                    dataType: 'json',
                    data: prices,
                    contentType: 'application/json; charset=utf-8',
                    success: function (data) {
                        alert('Success');
                    }
                });
            }
        });
    });

    function getPrices() {
        var elements = '[';        
        var rows = $("#selectedElementsGrid tr.selectable").each(function () {
            var idValue = '{price : { "Id":' + $(this).find(".id").val() + ',';
            var nameValue = ' "Name":"' + $(this).find(".name").text() + '",';
            var priceValue = ' "Price":"' + $(this).find(".price").val() + '"} },';
            elements = elements + idValue + nameValue + priceValue;
        });
        elements = elements.substring(0, elements.length - 1) + ']';
        return JSON.stringify(elements);
    }

提前致谢!

【问题讨论】:

  • 我把你的问题看了 3 遍,还是不明白你在问什么。您能否提供代码的相关部分来帮助说明?
  • 当然。视图期望或被强类型化为模型,在这种情况下是“提供者”实体。这个实体有原始类型和复杂类型:
  • 让我换个说法。 在动作中,我成功获取了模型,但是 JSON 没有出现在动作中。 如果你已经有了模型,为什么还需要 JSON?
  • 我添加了一些代码来解释更多场景。谢谢 dabaseman!
  • 问题出在集合上,信息存在于纯 html 中,因为它独立但属于单个流。

标签: json asp.net-mvc-3 entity-framework-4.1


【解决方案1】:

深入研究了 MVC3 框架,我发现您可以向控制器操作传递任意数量的参数,这样做的关键是保持对模型和请求的良好处理。 我还发现实现这一点的最简单方法是通过 JSON,首先您使用所需的参数定义控制器操作:

[HttpPost]
public ActionResult AddContact(Contact contact, int Id)
{
    var globalType = _repository.FindOne(p => p.Id == Id);
    if (globalType.Contacts == null)
    {
        globalType.Contacts = new List<Contact>();
    }
    globalType.Contacts.Add(contact);
    return View("Index", globalType);
}

然后从标记中定义一个复杂的 JSON 来传递参数:

    var contact = { Id: $('#FieldId').val(),
            Notes: $('#ContactNotes').val(),
            Name: $('#ContactName').val(),
            Phone: $('#Phone').val(),
            Fax: $('#Fax').val(),
            Email: $('#Email').val(),
            OfficeAddress: { Country: $('#Country').val(), 
                    State: $('#State').val()
                    ZipCode: $('#ZipCode').val()
            }
        };                                

    $.ajax({
        url: '/Contact/Edit',
        contentType: 'application/json; charset=utf-8',
        type: 'POST',
        dataType: 'json',
        data: JSON.stringify(contact)
    })
    .success(function (result) {
        // Display the section contents.
        alert('Contact updated succesfully!');
        window.location.href = result.Url;
    })
    .error(function (xhr, status) {
         alert('The provider could not be updated.');
    });

请注意,Id 参数的调用方式与 action 方法中的相同。复杂类型由 MVC 框架自动推断,唯一的条件是属性必须命名相同。

实现相同结果的另一种方法是使用 2 种不同的 JSON 类型定义一个控制器操作,这是一个示例。

控制器动作:

[HttpPost]
public ActionResult AddContact(TypeA  typeA, TypeB typeB)
{
    //Some logic...
}

JSON:

    var _typeA = { Id: $('#FieldId').val(),
            Name: $('#ContactName').val()
        }; 

    var _typeB = { Id: $('#FieldId').val(),
            Name: $('#ContactName').val()
        }; 

    $.ajax({
        url: '/Controller/Action',
        contentType: 'application/json; charset=utf-8',
        type: 'POST',
        dataType: 'json',
        data: {typeA:JSON.stringify(_typeA)},{typeB:JSON.stringify(_typeB)}
    })
    .success(function (result) {
        // Display the section contents.
        alert('Contact updated succesfully!');
        window.location.href = result.Url;
    })
    .error(function (xhr, status) {
         alert('The provider could not be updated.');
    });

希望对你有帮助

【讨论】:

  • 在 RouteDictionary 上配置路由很重要,以便 MVC 根据参数正确解析要使用的控制器。
【解决方案2】:

您发布的 json 对象是字符串(您可以稍后使用 JavaScriptSerializer 的方法对其进行反序列化)。 我认为,您缺少的是您在 jquery ajax 调用中作为数据放置的价格变量的关键。 一个帖子通常由一个键值对列表组成,这也是允许服务器技术从发布的数据中重构和反对的原因。在您的情况下,只有价格变量。
尝试将其更改为 data:{PricesListAsString:prices},然后在服务器上将“要传递的另一个对象”更改为字符串 PriceListAsString。
当然你也可以在调试控制器的同时查看Request对象,看看posted值是如何传递给服务器的

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-01-11
    • 1970-01-01
    • 2011-09-05
    • 2018-11-30
    • 1970-01-01
    • 1970-01-01
    • 2021-03-01
    • 1970-01-01
    相关资源
    最近更新 更多