2

我们的系统有一组已知的“合同类型”,它们有一个代码和一个名称。

public struct ContractType {
  public string Code { get; set; }
  public string Name { get; set; }
}

我有一个使用这样的方法的 MVC 控制器。

[HttpGet]
public ActionResult Search(SearchOptions options) {
   // returns search results
}

SearchOptions包含许多参数(包括一个数组ContractType

public class SearchOptions {
  public ContractTypes[] Contracts { get; set; }
  // other properties
}

我希望 asp.net MVC 自动将合同类型代码转换为SearchOptions模型上的合同类型数组。例如,我希望 MVC 模型绑定器采用这样的查询字符串......

http://abc.com/search?contracts=ABC&contracts=XYZ&foo=bar

并填充SearchOptions,使其看起来像以下数据结构

{
  Contracts : [
    { Code : "ABC", Name: "ABC Contract Name" },
    { Code : "XYZ", Name: "XYZ Contract Name" }
  ],
  // other properties
}

我有一个可用的方法,它将接受合同类型代码并返回适当的 ContractType。

public ContractType GetContractTypeByCode(string code) {
 // code which returns a ContractType
}

我不清楚我是否需​​要使用自定义模型绑定器或价值提供者。任何帮助表示赞赏。

4

1 回答 1

3

我认为你应该使用 ModelBinder。像这样的东西

public class SearchOptionsDataBinder : DefaultModelBinder
{
  public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
  {
    if (bindingContext.ModelType == typeof(SearchOptions))
    {
      var baseResult = (SearchOptions)base.BindModel(controllerContext, bindingContext);
      var request = controllerContext.HttpContext.Request;

      baseResult.Contracts = request.QueryString
                                    .GetValues("contracts")
                                    .Select(GetContractTypeByCode)
                                    .Where(c => !string.IsNullOrEmpty(c.Code))
                                    .ToArray();
      return baseResult;
    }

    return base.BindModel(controllerContext, bindingContext);        
  }
} 

然后将自定义模型绑定器添加到 Application_Start:

ModelBinders.Binders.Add(typeof(SearchOptions), new SearchOptionsDataBinder());
于 2013-11-08T19:27:58.280 回答