2011-12-14 89 views
9

好的模型,可以说我有像这样一个URL,它通过HTTP动词GET映射到控制器的动作我有如下:如何绑定URL参数属性名称不同

GET /foo/bar?sort=asc&r=true 

我怎样才能结合这对我对我的控制器操作模式Bar我有如下:

class Bar { 
    string SortOrder { get; set; } 
    bool Random { get; set; } 
} 

public ActionResult FooBar(Bar bar) { 
    // Do something with bar 
    return null; 
} 

注意,属性名不会也未必匹配URL参数的名称。另外,这些是可选的url参数。

+1

我只是添加一个类与匹配的属性名称,但我很感兴趣,看看你是否可以配置模型联编程序绑定到任意的属性名称。也许有一些属性使用... – dotjoe 2011-12-14 16:18:11

+1

我无法得到它,为什么属性无法匹配的URL参数? – gdoron 2011-12-14 16:29:34

回答

7

模型联编程序将它从视图中获取的参数与名称中的动作相匹配,因此如果它们不匹配,绑定将不起作用。

选项你有:

  1. 匹配输入名称的模型属性的名称...但你说你不能这样做,(对于一些未知的原因)。
  2. 编写自定义模型活页夹。 *
  3. 使用具有前缀的Bind属性 - 尽管它仍会强制您输入名称接近模型属性名称。

所以基本上,你不能做到你想要的。


更新:

您的评论的性能可以匹配参数名写的,所以不是写自定义属性,也许会成功做了绑定,只写一个视图模型(该VM fromMVC ...)调整url参数名称。

编写自定义的模型绑定不建议用MVC团队:

一般情况下,我们建议人们不要写自定义模型粘合剂,因为他们难以得到的权利和他们很少需要
here

9

它不支持开箱即用,但你可以这样做:

class BarQuery : Bar { 

    public string sort { get { return SortOrder; } set { SortOrder = value; } } 
    public bool r { get { return Random; } set { Random = value; } } 
} 

public ActionResult FooBar(BarQuery bar) { 
    // Do something with bar 
} 

您可以实现自定义IModelBinder,但手动映射更容易。


如果你可以改变的酒吧类,你可以使用这个属性:

class FromQueryAttribute : CustomModelBinderAttribute, IModelBinder { 

    public string Name { get; set; } 

    public FromQueryAttribute() { } 

    public FromQueryAttribute(string name) { 
     this.Name = name; 
    } 

    public override IModelBinder GetModelBinder() { 
     return this; 
    } 

    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { 
     return controllerContext.HttpContext.QueryString[this.Name ?? bindingContext.ModelName]; 
    } 
} 

class Bar { 

    [FromQuery("sort")] 
    string SortOrder { get; set; } 

    [FromQuery("r")] 
    bool Random { get; set; } 
} 

public ActionResult FooBar(Bar bar) { 
    // Do something with bar 
    return null; 
} 
1

您可以实现IModelBinder到您的传入参数映射到您选择的对象所提供的名称定义传入的参数。否则,你将不得不依靠参数顺序和/或类型来推断正确的绑定,这似乎是一个非常糟糕的选择。

3

我很久以前有同样的问题,并使用安德拉什佐尔坦这个栈解决方案:对物业Asp.Net MVC 2 - Bind a model's property to a different named value

我设置ModelBinder的属性上我的课和BindAlias:

[ModelBinder(typeof(DefaultModelBinderEx))] 
    public class MyModel 
    { 
     [Required] 
     [BindAlias("new")] 
     public int? Amount { get; set; } 

如果你不能改变或不能访问你的模型文件来设置属性,你仍然可以创建一个自定义模型绑定器,或者制作一个特定的对象,而不是你将映射到你的模型(AutoMapper是有用的)

1

There没有免费的MVC.Net Mo删除绑定功能,可以给你开箱即用的功能。当我需要做这样的事情时,它真的让我思考我的建模,这几乎总是让我为我的视图绑定创建一个ViewModel,为我的存储库存储创建一个EntityModel。

我喜欢使用AutoMapper在这些不同类型之间进行转换。使用AutoMapper的最好的部分是,它可以让你不必为控制器中的每个Action而反复编写映射逻辑。只需在初始化部分使用AutoMapper设置一次,并在将来执行此类操作即可。

Mapper.Map<Bar>(barViewModel); 
相关问题