2012-10-08 39 views
1

假設我有一個Dictionary<string, string>,我想用字典中的值更新一個對象,就像MVC中的模型綁定一樣......如果沒有MVC,你會怎麼做?模型綁定可能沒有mvc?

+0

是的。請更具體一些。你想完成什麼?將字典映射到對象而不使用框架。在非mvc場景中重新使用System.Web.Mvc中找到的modelbinder?還有別的嗎? – driis

+0

是在非mvc場景中重新使用System.Web.Mvc中找到的modelbinder。 –

回答

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; 
    } 
} 
2

你可以這樣做,但顯然你仍然需要引用System.Web.Mvc。這或多或少地構成ModelBinder,可能是DefaultModelBinder,然後用適當的參數調用它 - 但不幸的是,這些參數與web場景非常緊密地綁定。

根據您的確切需求,推出自己的簡單反射解決方案可能更有意義。