假设我有Dictionary<string, string>
并且我想用字典中的值更新对象,就像MVC中的模型绑定一样......没有MVC你会怎么做?
答案 0 :(得分:4)
您可以使用DefaultModelBinder来实现此目的,但您需要将System.Web.Mvc程序集引用到您的项目中。这是一个例子:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.Linq;
using System.Web.Mvc;
public class MyViewModel
{
[Required]
public string Foo { get; set; }
public Bar Bar { get; set; }
}
public class Bar
{
public int Id { get; set; }
}
public class Program
{
static void Main()
{
var dic = new Dictionary<string, object>
{
{ "foo", "" }, // explicitly left empty to show a model error
{ "bar.id", "123" },
};
var modelState = new ModelStateDictionary();
var model = new MyViewModel();
if (!TryUpdateModel(model, dic, modelState))
{
var errors = modelState
.Where(x => x.Value.Errors.Count > 0)
.SelectMany(x => x.Value.Errors)
.Select(x => x.ErrorMessage);
Console.WriteLine(string.Join(Environment.NewLine, errors));
}
else
{
Console.WriteLine("the model was successfully bound");
// you could use the model instance here, all the properties
// will be bound from the dictionary
}
}
public static bool TryUpdateModel<TModel>(TModel model, IDictionary<string, object> values, ModelStateDictionary modelState) where TModel : class
{
var binder = new DefaultModelBinder();
var vp = new DictionaryValueProvider<object>(values, CultureInfo.CurrentCulture);
var bindingContext = new ModelBindingContext
{
ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, typeof(TModel)),
ModelState = modelState,
PropertyFilter = propertyName => true,
ValueProvider = vp
};
var ctx = new ControllerContext();
binder.BindModel(ctx, bindingContext);
return modelState.IsValid;
}
}
答案 1 :(得分:2)
你可以这样做,但显然你仍然需要引用System.Web.Mvc。它或多或少是构建ModelBinder的问题,也许是DefaultModelBinder
,然后使用适当的参数调用它 - 但不幸的是,这些参数与Web场景密切相关。
根据您的确切需求,推出基于简单反射的解决方案可能更有意义。