映射动态视图模型,不包括某些字段

时间:2011-03-28 18:54:43

标签: c# asp.net-mvc mapping viewmodel automapper

  

可能重复:
  What is the best way to map two objects of the same type excluding some fields?

嗨,伙计们,
在我的asp.net MVC2中,我使用视图模型将域对象传递回我的视图 其中一些视图模型具有其他字段(属性),我将其用作搜索参数。 我的大多数视图都显示了一个搜索栏,允许用户输入搜索条件并提交搜索,以及一个包含数据的网格 我希望能够向用户显示最后一次搜索,用以前的搜索填充我的视图的字段(文本框,组合框等),如果有的话。 我试图概括我的所有代码,所以我不必为每个视图定制所有内容。

现在我有一个基本控制器负责创建一个类型化的视图模型 为简单起见,我将简化我的代码:

public abstract class BaseController : Controller
{
    private readonly IViewModelFactory ViewModelFactory;

    public BaseController()
    {
    ViewModelFactory = new ViewModelFactory();
    }

    protected T CreateViewModel<T>() where T : BaseViewModel, new()
    {
    var viewModel = this.ViewModelFactory.Create<T>();
    return (viewModel);
    }
}

所以现在我可以在一个动作中创建我的viewmodel:

[HttpGet]
public ActionResult Index()
{
    var viewModel = CreateViewModel<ViewModels.OrdersViewModel>();
    viewModel.OrderNumber = "";
    viewModel.FromDate = DateTime.Today;
    viewModel.ToDate = DateTime.Today.AddMonths(6);

    return View(viewModel);
}

如您所见,我已使用默认值设置搜索字段。 现在,我想在用户POST表单时将搜索字段保存在缓存中。 我正在这样做。

我已经实现了自定义属性:

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
public class FilterFieldAttribute: Attribute
{
} 

我想应用于我的视图模型的某些成员:

public class OrdersViewModel : BaseViewModel
{
...

    [FilterField]
    [DisplayName("Order Number:")]
    public string OrderNumber { get; set; }

    [FilterField]
    [DisplayName("From date:")]
    public DateTime FromDate { get; set; }

    [FilterField]
    [DisplayName("To date:")]
    public DateTime ToDate { get; set; }

    [DisplayName("Status:")]
    public int Status { get; set; }

    ...
}   

现在我正在考虑委托我的 BaseController 在用户提交数据时设置缓存中的字段,并在用户加载页面时从缓存中获取。

将负责保存搜索参数的控制器操作将执行以下操作:

[HttpPost]
public ActionResult Fetch(string OrderNumber, DateTime FromDate, DateTime ToDate)
{
this.CacheViewModel<ViewModels.OrdersViewModel>(new ViewModels.OrdersViewModel() { 
                OrderNumber = OrderNumber,
                FromDate = FromDate,
                ToDate = ToDate,
                SelectedOrderStatus = OrderStatus
                }, Session.SessionID);

我稍微修改了我的BaseController类:

public abstract class BaseController : Controller
{
    private readonly IViewModelFactory ViewModelFactory;

    public BaseController()
    {
    ViewModelFactory = new ViewModelFactory();
    }

    protected T CreateViewModel<T>() where T : BaseViewModel, new()
    {
    var viewModel = this.ViewModelFactory.Create<T>();

    // ADDED THIS:
    viewModel = UpdateFromCache<T>(viewModel, Session.SessionID); 

    return (viewModel);
    }
}

UpdateFromCache方法将循环遍历视图模型的所有成员,以查找具有FilterField属性并将填充新视图模型的成员。 我把这段代码放在一起:

private T UpdateFromCache<T>(T viewModel, string SessionId) where T : BaseViewModel
{
    string Key = SessionId + typeof(T).ToString();
    var myCache = System.Web.HttpContext.Current.Cache;
    if (myCache.Get(Key) != null)
    {
        T previousViewModel = myCache.Get(Key);

    FilterFieldAttribute filterAttribute;
        Type type = typeof(T);

        foreach (PropertyInfo propInfo in type.GetProperties())
        {
            foreach (FilterFieldAttribute attr in propInfo.GetCustomAttributes(typeof(FilterFieldAttribute), false))
            {
                filterAttribute = attr as FilterFieldAttribute;
                if (filterAttribute != null)
                {
                    string propertyName = propInfo.Name;

            // UPDATE viewModel (parameter) with previousViewModel (retrieve from cache)
                }
            }
        }
        viewModel.IsFetchedFromCache = true;
    }
    return (viewModel);
}

但我不知道如何将从缓存中检索到的对象复制到作为参数传递的viewmodel中 由于我使用Automapper,我可能会用它来实现相同的结果......但我不知道该怎么做。

0 个答案:

没有答案