在向客户端发送数据时,我使用DataContractJsonSerializer为我的模型数据创建JsonResult。我的模型表示要在数据表中显示的数据,我希望仅在JSON中更改模型属性的名称,以便通过线路为每个数据表行发送更简洁的属性名称。现在,我试图通过JSON将数据表单元格值发送到服务器的控制器操作方法。要发回的字段的名称仍然是短名称,模型绑定似乎不喜欢这样。我该怎么做才能使模型绑定工作并保留通过JSON发送备用属性名称的能力?
型号:
[DataContract()]
public class UsageListModel {
[DataMember(Name = "results")]
public IEnumerable<UsageModel> Usages { get; set; }
}
[DataContract()]
public class UsageModel {
[DataMember(Name = "job")]
public string JobId { get; set; }
[DataMember(Name = "dt")]
public DateTime UsageDate { get; set; }
[DataMember(Name = "qty")]
public int Quantity { get; set; }
[DataMember(Name = "uom")]
public string UnitOfMeasure { get; set; }
[DataMember(Name = "nts")]
public string Notes { get; set; }
}
答案 0 :(得分:2)
它不是那么优雅,但我通常只是通过创建一个具有那些短名称属性的中间类(我称之为ViewModel)来实现这一点,并且可以在它与实际模型之间来回转换。虽然看起来工作繁忙,但ViewModel可以超越此限制 - 例如,如果需要,您可以使用它轻松缓存客户端信息,或者在测试中准确地序列化/反序列化客户端的内容。 / p>
答案 1 :(得分:0)
我仍然不相信MVC没有提供一些更简单的方法来使用自定义属性(甚至是.NET数据协定属性)进行绑定。鉴于它没有...你最好的选择是实现自己的 IModelBinder 。使用反射获取属性的 DataMember 名称,并在绑定上下文中查找这些值。
以下是关于模型绑定的一个很好的参考:http://msdn.microsoft.com/en-us/magazine/hh781022.aspx
维护自定义绑定器的一般方法:http://lostechies.com/jimmybogard/2009/03/18/a-better-model-binder/
修改强>
处理已定义类型的通用模型绑定器。要将其添加到您的应用程序,请在global.asax中添加以下行:
ModelBinders.Binders.Add(typeof(UsageModel), new CustomModelBinder<UsageModel>());
和活页夹:
public class CustomModelBinder<T> : IModelBinder
{
public override bool IsMatch(Type t)
{
return t == typeof(T);
}
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
Type t = typeof(T);
var entity = (bindingContext.Model ?? Activator.CreateInstance(t));
// Cycle through the properties and assign values.
foreach (PropertyInfo p in t.GetProperties())
{
string sourceKey;
// this is what you'd do if you wanted to bind to the property name
// string sourceKey = p.Name;
// TODO bind sourceKey to the name in attribute DataMember
Type propertyType = p.PropertyType;
// now try to get the value from the context ...
ValueProviderResult valueResult = bindingContext.ValueProvider.GetValue(sourceKey);
if (valueResult != null)
{
bindingContext.ModelState.SetModelValue(sourceKey, valueResult);
p.SetValue(entity, valueResult.ConvertTo(propertyType), null);
}
}
return entity;
}
}
答案 2 :(得分:0)
我在浏览this other question时偶然发现了这个问题的潜在答案。
直到现在我才意识到这一点,但显然你可以为方法参数添加属性。我们举一个简单的例子:
public ActionResult SomeMethod(string val) {
return View(val);
}
如果您调用此URL - / MyController / SomeMethod?val = mytestval - 那么您将在模型中找回“mytestval”,对吧?所以现在你可以这样写:
public ActionResult SomeMethod([Bind(Prefix="alias")] string val) {
return View(val);
}
现在这个URL会产生相同的结果:/ MyController / SomeMethod?alias = mytestval。
无论如何,我仍然不确定这是否会回答你的问题,但我觉得这很有趣。