ASP.NET MVC参数绑定失败,适用于复杂类型

时间:2013-02-01 05:58:16

标签: asp.net-mvc binding asp.net-mvc-4 model-binding

我有ASP.Net的问题导致我把头发撕掉了。我可以使用不同的方法来获取模型的一部分,但没有一种方法可以绑定所有数据。

控制器操作签名

// Post: Profile/{customerId}/SetKnockOutQuestions/{profileId}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult SetKnockOutQuestions(Int32 customerId,
    Int32 profileId,
    Int32 parentProfileId,
    IEnumerable<ProfileKnockOutQuestionModel> questions)
{

ProfileKnockOutQuestionModel类的相关数据成员

public sealed class ProfileKnockOutQuestionModel {

    /// <summary>
    /// Parameterless constructor is required for auto-passing GET/POST data to controller actions.
    /// </summary>
    public ProfileKnockOutQuestionModel() { }


    [Required]
    [DisplayName("Lead Type Id")]
    public Int32 AdminLeadType { get; set; }

    //[Required]
    //[DisplayName("Question Type")]
    [UIHint("GridForeignKey")]
    public Int16 QuestionTypeId { get; set; }

    [Required]
    [DisplayName("Question Text")]
    public String QuestionText { get; set; }

    [Required]
    [DisplayName("Pass Answer")]
    public String Answer1Text { get; set; }

    [Required]
    [DisplayName("Fail Answer")]
    public String Answer2Text { get; set; }

    [Required]
    [DisplayName("Price")]
    [DataType(DataType.Currency)]
    [Range(0, Int16.MaxValue)]
    public Decimal Price { get; set; }

    public Int32 ProfileKnockOutQuestionId { get; private set; }

    public Int32 ProfileId { get; private set; }

    public Int32 ParentProfileId { get; private set; }

    public Int32 CustomerId { get; private set; }

    public Int32 AdminKnockOutQuestionId { get; private set; }

尝试以JSON编码的javascript代码发送数据

$.ajax({
    url: "/mvc/Profiles/78219/SetKnockOutQuestions/1605111",
    data: JSON.stringify({ questions: data,
        parentProfileId : 1605105 
    }),
    type: "POST",
    contentType: "application/json; charset=utf-8"
});

发送此数据(为简洁而修剪)

{
"questions":[
   {
     "AdminKnockOutQuestionId":8,
     "AdminLeadType":4,
     "Answer1Text":"Ya really!",
     "Answer2Text":"no wai",
     "CustomerId":78219,
     "ParentProfileId":1605105,
     "Price":2,
     "ProfileId":1605111,
     "ProfileKnockOutQuestionId":0,
     "QuestionText":"Really? Auto",
     "QuestionTypeId":0
   },

但是一旦我们进入动作,模型绑定器只绑定了字符串,价格和AdminLeadType。其余数据都是零。我注意到,在注意到所有正确解析的字段都包含它们并且没有任何更改后,我会尝试将[Required][DisplayName("")]属性添加到其余的数字字段中。

我试图将其发送的另一种方式是作为常规表格编码的帖子。

AXAJ javscript

$.ajax({
    url: "/mvc/Profiles/78219/SetKnockOutQuestions/1605111",
    data: { questions: data,
        parentProfileId : 1605105 
    },
    type: "POST",
});

这导致像下面的帖子一样(从Chrome的网络检查员复制/粘贴;我可以发布未解析的,网址编码的版本,但只是相信我的&符号等等都是有序的):< / p>

questions[0][AdminKnockOutQuestionId] = 8
questions[0][AdminLeadType] = 4
questions[0][Answer1Text] = Ya really!
questions[0][Answer2Text] = no wai
questions[0][CustomerId] = 78219
questions[0][ParentProfileId] = 1605105
questions[0][Price] = 2
questions[0][ProfileId] = 1605111
questions[0][ProfileKnockOutQuestionId] = 0
questions[0][QuestionText] = Really? Auto
questions[0][QuestionTypeId] = 0

这有相反的问题。什么都没有约束,因为模型状态吓坏了并且说所有字符串值都丢失了,即使我可以在Request对象的VS调试器视图中清楚地看到它们。

世界上我的模型绑定错误了什么?

2 个答案:

答案 0 :(得分:1)

您的房产有私人制定者。您不可能期望模型绑定器能够绑定它们。所以添加公共设置者:

public sealed class ProfileKnockOutQuestionModel 
{
    /// <summary>
    /// Parameterless constructor is required for auto-passing GET/POST data to controller actions.
    /// </summary>
    public ProfileKnockOutQuestionModel() { }

    [Required]
    [DisplayName("Lead Type Id")]
    public Int32 AdminLeadType { get; set; }

    //[Required]
    //[DisplayName("Question Type")]
    [UIHint("GridForeignKey")]
    public Int16 QuestionTypeId { get; set; }

    [Required]
    [DisplayName("Question Text")]
    public String QuestionText { get; set; }

    [Required]
    [DisplayName("Pass Answer")]
    public String Answer1Text { get; set; }

    [Required]
    [DisplayName("Fail Answer")]
    public String Answer2Text { get; set; }

    [Required]
    [DisplayName("Price")]
    [DataType(DataType.Currency)]
    [Range(0, Int16.MaxValue)]
    public Decimal Price { get; set; }

    /// <summary>
    /// Public setters are required for passing GET/POST data to controller actions.
    /// </summary>
    public Int32 ProfileKnockOutQuestionId { get; set; }

    /// <summary>
    /// Public setters are required for passing GET/POST data to controller actions.
    /// </summary>
    public Int32 ProfileId { get; set; }

    /// <summary>
    /// Public setters are required for passing GET/POST data to controller actions.
    /// </summary>
    public Int32 ParentProfileId { get; set; }

    /// <summary>
    /// Public setters are required for passing GET/POST data to controller actions.
    /// </summary>
    public Int32 CustomerId { get; set; }

    /// <summary>
    /// Public setters are required for passing GET/POST data to controller actions.
    /// </summary>
    public Int32 AdminKnockOutQuestionId { get; set; }

    ...
}

一旦你想绑定的所有属性都有公共设置器,你的AJAX请求就好了:

$.ajax({
    url: "/mvc/Profiles/78219/SetKnockOutQuestions/1605111",
    data: JSON.stringify({ 
        questions: data,
        parentProfileId : 1605105 
    }),
    type: "POST",
    contentType: "application/json; charset=utf-8"
});

答案 1 :(得分:0)

我认为我没有张过阵列,但我不知道为什么它不起作用。

我想提一些可能有用的事情:

首先,在您的第二次尝试中,我相信您必须使用ajax的传统参数,以便asp mvc接受它。

其次,我认为你不需要使用JSON.stringify发布JSON,所以你可能想尝试删除它。

最后,如果所有其他方法都失败了,那就制作一个像这样的新模型

public class ProfileQuestions
{
    public Int32 customerId {get;set;}
    public Int32 profileId {get;set;}
    public Int32 parentProfileId {get;set;}
    public IEnumerable<ProfileKnockOutQuestionModel> questions {get;set;}
}

并将您的操作更改为

public ActionResult SetKnockOutQuestions(
    ProfileQuestions profileQs)
{

我知道最后一个选项肯定会起作用