Передача пустого массива js контроллеру дает null

вот моя модель, которая является прокси-классом WCF

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

передача объекта структуры JSON ниже с MyEmpls as empty array к контроллеру MVC.

["Id":12, "MyEmpls":[], "OrgName":"Kekran Mcran"]

контроллер

[HttpPost]
public ActionResult SaveOrg(MyModel model)
{
  //model.MyEmpls is null here
}

Я жду mode.MyEmpls как пустой массив c#, а не null. Кто-нибудь может мне помочь? Этого нужно написать пользовательскую модель связующего для этого?

7 ответов


Я думаю, что некоторые из других ответов пропустили смысл вопроса: почему связыватель модели MVC по умолчанию связывает пустой массив Json с null вместо пустого массива C#?


вы получаете значение null, так как это значение по умолчанию для ссылочного типа В 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>();
    }
}

вы получите пустой список, когда пустой массив будет передан из 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];
    }
}

Если вы получаете модели.MyEmpls как null, то вы можете создать условие на стороне сервера, чтобы остановить создание исключения, как:

if(model.MyEmpls !=null){
...
}

и вы получаете его null, потому что ваш MyEmpls является массивом пользовательского класса, и вы отправляете только [].

надеюсь, это поможет вам.


попробуйте создать модель связующего, как показано ниже

public class MyModelBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        try
        {                
            var request = controllerContext.HttpContext.Request;

            return new MyModel
            {
                MyEmpls = request[] ?? new Employees[0],
                Id = request["Id"] ?? "",
                OrgName = request["OrgName"] ?? ""

            };
        }
        catch 
        {
            //do required exception handling
        }
    }
}

в Application_Start зарегистрируйте модель binder

ModelBinders.Binders.Add(typeof(MyModel), new MyModelBinder())

и измените контроллер как

[HttpPost]
public ActionResult SaveOrg([ModelBinder(typeof(MyModelBinder))] MyModel model)
{
  //model.MyEmpls is null here
}

[HttpPost]
public ActionResult SaveOrg(MyModel model)
{
    var serializer = new JavaScriptSerializer();
    var stream = System.Web.HttpContext.Current.Request.InputStream;
    var reader = new StreamReader(stream);
    stream.Position = 0;
    var json = reader.ReadToEnd();
    model= serializer.Deserialize<MyModel>(json);
    //model.MyEmpls is [] here
}

JavaScriptSerializer десериализует пустые массивы должным образом. Таким образом, вы можете игнорировать переданную модель и перестроить ее из потока входных запросов. Вероятно, не правильный способ, но если вам нужно сделать это только один раз, это сэкономит некоторые усилия. Вам понадобится справочная система.Сеть.Увеличение.


поведение инициализации массива C# по умолчанию-null not empty array

поэтому, если вы отправляете пустой массив, вы не будете инициировать пустой массив, но вы инициализируете инициализацию по умолчанию в null

см. следующую ссылку http://www.dotnetperls.com/null-array


вы можете определить сеттер, который проверяет, является ли значение null

public class MyModel
{
    private _myEmpls{get;set;}
    public Employees[] MyEmpls{
     get{return _myEmpls;}
     set{_myEmpls=(value==null?new List<Employees>():value);}
    }

    public int Id{get;set;}
    public OrgName{get;set;}
}