2012-12-05 36 views
0

我知道如何創建這樣當它進入我的Web API控制器動作,填充模型,反映查詢字符串變量模型類。是不依賴於查詢字符串參數ASP.NET MVC的Web API模型

然而,就是有辦法讓這個我不是鎖定在查詢字符串變量名稱作爲我的模型類的屬性?

例子:

public class MyModel { 
    public string o {get;set;} 
} 

public class MyController { 
    public string Get(MyModel model) { 

    } 
} 

然後,如果我的查詢字符串的樣子: GET http://domain.com/?o=12345

有沒有辦法來命名模型屬性「命令」之類的東西,而不是「O」,然後它已經從「O =」值填充?

+1

2完全不同的答案 - 迫不及待地嘗試他們出來,並找出哪一個標誌!愛堆! –

回答

1

您可以創建將數據綁定到建模爲您希望自定義模型粘合劑。要使用它,你應該:

public string Get([ModelBinder(typeof(MyComplexTypeModelBinder))]MyModel model) 
{ 
... 
} 

要創建自定義的模型綁定你可以從IModelBinder或DefaultModelBinder繼承。

public class MyComplexTypeModelBinder : IModelBinder 
{ 

    public Object BindModel(ControllerContext controllerContext, 
          ModelBindingContext bindingContext) 
    { 
    if (bindingContext == null) 
     throw new ArgumentNullException("bindingContext"); 

    // Create the model instance (using the ctor you like best) 
    var obj = new MyComplexType(); 

    // Set properties reading values from registered value providers 
    obj.Order = FromPostedData<string>(bindingContext, "o"); 
    ... 
    return obj; 
} 


private T FromPostedData<T>(ModelBindingContext context, String key) 
{ 
    // Get the value from any of the input collections 
    ValueProviderResult result; 
    context.ValueProvider.TryGetValue(key, out result); 

    // Set the state of the model property resulting from 
    context.ModelState.SetModelValue(key, result); 
    // Return the value converted (if possible) to the target type 
    return (T) result.ConvertTo(typeof(T)); 
} 
0

此方案的解決方案是自定義IValueProvider。這ASP.NET MVC擴展點是正確的地方,在這裏我們可以彌合QueryString鍵進入Model.Property名。在與ModelBinder相比,這將目標正是我們所需要(而不是引入後的問題的時候,連其他值提供商(FORM)無意中包含關鍵...)

有很好的教程如何引入自定義IValueProvider

並且有一個簡單的例子,它能夠爲模型「訂單」屬性提供值,來作爲查詢字符串「O」鍵:

// Factory 
public class MyValueProviderFactory : ValueProviderFactory 
{ 
    public override IValueProvider GetValueProvider(ControllerContext ctx) 
    { 
    return new MyValueProvider(ctx); 
    } 
} 

提供商

// Provider 
class MyValueProvider : IValueProvider 
{ 
    protected HttpRequestBase Request { get; set; }  
    public MyValueProvider(ControllerContext ctx) 
    { 
    Request = ctx.HttpContext.Request; 
    } 

    // our custom logic to test QueryString keys, and expected prefixes 
    public bool ContainsPrefix(string prefix) 
    { 
    var containsSpecial = 
     "Order".Equals(prefix, StringComparison.OrdinalIgnoreCase) 
     && Request.QueryString.AllKeys.Contains("o" 
        , StringComparer.InvariantCultureIgnoreCase); 
    return containsSpecial; 
    } 

    // Handling "Order" key 
    public ValueProviderResult GetValue(string key) 
    { 
    if (!ContainsPrefix(key)) 
    { 
     return null; 
    } 
    var values = Request.QueryString.GetValues("o"); 

    if (values.Any()) 
    { 
     return new ValueProviderResult(values, values.First() 
            , CultureInfo.CurrentCulture); 
    } 
    return null; 
    } 
} 

而在global.asax,我們必須把它注射:

protected void Application_Start() 
{ 
    ValueProviderFactories.Factories.Add(new MyValueProviderFactory()); 
    ... 
相關問題