将空的js数组传递给控制器​​会给出null

Bil*_*lla 33 c# asp.net-mvc wcf json model-binding

这是我的模型,它是一个WCF代理类

public class MyModel
{
    public Employees[] MyEmpls{get;set;}
    public int Id{get;set;}
    public OrgName{get;set;}
}
Run Code Online (Sandbox Code Playgroud)

将下面的json结构对象传递MyEmpls as empty array给MVC控制器.

["Id":12, "MyEmpls":[], "OrgName":"Kekran Mcran"]
Run Code Online (Sandbox Code Playgroud)

调节器

[HttpPost]
public ActionResult SaveOrg(MyModel model)
{
  //model.MyEmpls is null here
}
Run Code Online (Sandbox Code Playgroud)

我期待mode.MyEmpls作为空c#数组而不是null.有人可以帮我吗?我们需要为此编写自定义模型绑定器吗?

Ric*_*ban 31

我认为其他一些答案已经错过了问题的含义:为什么默认的MVC模型绑定器将空的Json数组绑定为null而不是空的C#数组?

好吧,我不能告诉你为什么他们这样做,但我可以告诉你它发生在哪里.可以在CodePlex上找到MVC的源代码:http://aspnetwebstack.codeplex.com/SourceControl/latest.您正在寻找的文件是ValueProviderResult.cs,您可以在其中看到:

    private static object UnwrapPossibleArrayType(CultureInfo culture, object value, Type destinationType)
    {
        if (value == null || destinationType.IsInstanceOfType(value))
        {
            return value;
        }

        // array conversion results in four cases, as below
        Array valueAsArray = value as Array;
        if (destinationType.IsArray)
        {
            Type destinationElementType = destinationType.GetElementType();
            if (valueAsArray != null)
            {
                // case 1: both destination + source type are arrays, so convert each element
                IList converted = Array.CreateInstance(destinationElementType, valueAsArray.Length);
                for (int i = 0; i < valueAsArray.Length; i++)
                {
                    converted[i] = ConvertSimpleType(culture, valueAsArray.GetValue(i), destinationElementType);
                }
                return converted;
            }
            else
            {
                // case 2: destination type is array but source is single element, so wrap element in array + convert
                object element = ConvertSimpleType(culture, value, destinationElementType);
                IList converted = Array.CreateInstance(destinationElementType, 1);
                converted[0] = element;
                return converted;
            }
        }
        else if (valueAsArray != null)
        {
            // case 3: destination type is single element but source is array, so extract first element + convert
            if (valueAsArray.Length > 0)
            {
                value = valueAsArray.GetValue(0);
                return ConvertSimpleType(culture, value, destinationType);
            }
            else
            {
                // case 3(a): source is empty array, so can't perform conversion
                return null;
            }
        }
        // case 4: both destination + source type are single elements, so convert
        return ConvertSimpleType(culture, value, destinationType);
    }
}
Run Code Online (Sandbox Code Playgroud)

有趣的部分是"案例3":

else
{
    // case 3(a): source is empty array, so can't perform conversion
    return null;
}
Run Code Online (Sandbox Code Playgroud)

您可以通过在构造函数中初始化模型上的数组来回避此问题.在我快速阅读源代码时,我无法告诉你为什么他们不能返回一个空数组或为什么他们决定不这样做,但它应该有趣的阅读.

  • 请注意,在 MVC Core 中,此行为已更改为空 JSON 数组绑定到空集合的预期行为。 (2认同)

Jam*_*mes 29

您将获得一个空值,因为这是C#中引用类型的默认值.为了获得一个空数组,您需要使用构造函数初始化模型中的数组.但是,由于您需要在初始化时定义数组的大小,因此使用其他类型的集合可能会更好,例如List:

public class MyModel
{
    public List<Employees> MyEmpls{get;set;}
    public int Id{get;set;}
    public OrgName{get;set;}

    public MyModel() 
    {
         MyEmpls = new List<Employees>();
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,当从json传递空数组时,您将获得一个空列表.

如果你真的必须使用一个数组,只需用一个大小初始化它:

public class MyModel
{
    public Employees[] MyEmpls{get;set;}
    public int Id{get;set;}
    public OrgName{get;set;}

    public MyModel() 
    {
         MyEmpls = new Employees[//enter size of array in here];
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 空和空意味着非常不同的东西.就我而言 - 指定模型的更改.Null表示忽略此属性,保持原样.空意味着删除所有元素. (2认同)