1

假设我有一个Dictionary<string, string>并且我想用字典中的值更新一个对象,就像 MVC 中的模型绑定......如果没有 MVC,你将如何做到这一点?

4

2 回答 2

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;
    }
}
于 2012-10-09T06:51:50.063 回答
2

你可以这样做,但显然你仍然需要引用 System.Web.Mvc。这或多或少是构造一个 ModelBinder 的问题,也许是DefaultModelBinder,然后使用适当的参数调用它 - 但不幸的是,这些参数与 Web 场景密切相关。

根据您的确切需求,推出您自己的基于反射的简单解决方案可能更有意义。

于 2012-10-08T20:32:41.023 回答