当请求中没有属性时,DefaultModelBinder行为
本文关键字:DefaultModelBinder 行为 属性 请求 | 更新日期: 2023-09-27 18:04:11
我有一个如下的模型:
public class TestViewModel
{
string UpdateProperty { get; set; }
string IgnoreProperty { get; set; }
ComplexType ComplexProperty { get; set; }
}
,
public class ComplexType
{
long? Code { get; set; }
string Name { get; set; }
}
我的控制器动作:
public Edit(int id, FormColleciton formCollection)
{
var model = service.GetModel(id);
TryUpdateModel(model);
//...
}
当调用Edit动作时,我有一个formCollection参数,其中只包含UpdateProperty的键/值。
调用TryUpdateModel UpdateProperty正确设置后,IgnoreProperty保持不变,但ComplexProperty被设置为null,即使它之前有一个值。
TryUpdateModel()应该只修改作为请求一部分的属性吗?如果情况并非如此,那么解决这个问题的最佳方法是什么?所以ComplexProperty只有在请求中包含时才会被修改?
在Darin指出上面的测试用例没有显示出问题之后,我添加了一个场景,这个场景确实发生了这个问题:
public class TestViewModel
{
public List<SubModel> List { get; set; }
}
public class SubModel
{
public ComplexType ComplexTypeOne { get; set; }
public string StringOne { get; set; }
}
public class ComplexType
{
public long? Code { get; set; }
public string Name { get; set; }
}
控制器动作:public ActionResult Index()
{
var model = new TestViewModel
{
List = new List<SubModel> {
new SubModel{
ComplexTypeOne = new ComplexType{Code = 1, Name = "5"},
StringOne = "String One"
}
}
};
if (TryUpdateModel(model)) { }
return View(model);
}
发送此请求:
/Home/Index?List[0].StringOne=test
更新子模型。StringOne属性,但将ComplexTypeOne设置为null,即使它不包含在请求中。
这是预期的行为吗(除非使用复杂类型的可枚举对象,否则不会发生这种情况)?如何最好地解决这个问题?
您的测试用例一定有问题,因为我无法复制它。下面是我的尝试:
模型(注意我使用了公共属性):
public class TestViewModel
{
public string UpdateProperty { get; set; }
public string IgnoreProperty { get; set; }
public ComplexType ComplexProperty { get; set; }
}
public class ComplexType
{
public long? Code { get; set; }
public string Name { get; set; }
}
控制器:
public class HomeController : Controller
{
public ActionResult Index()
{
var model = new TestViewModel
{
IgnoreProperty = "to be ignored",
UpdateProperty = "to be updated",
ComplexProperty = new ComplexType
{
Code = 1,
Name = "5"
}
};
if (TryUpdateModel(model))
{
}
return View();
}
}
现在我发送以下请求:/home/index?UpdateProperty=abc
,并且在条件中只有UpdateProperty被修改为来自查询字符串的新值。所有其他属性,包括复杂属性,都保持不变。
还要注意,FormCollection
动作参数是无用的。