2011-06-19 44 views
2

(我使用ASP.NET MVC 2)MVC RouteUrl沒有履行排除屬性

如何使用Url.RouteUrl(object)當我排除進入查詢字符串某些屬性?

具體來說,在我的Model對象被傳遞給我的視圖,我有一個字符串數組(技術上IEnumerable <字符串>)我想排除。

我認爲與排除的綁定屬性應該這樣做,但它不起作用。我試圖把[Bind(Exclude = "Sizes")]上我的課,但我不斷收到的URL看起來像這樣:

的http://本地主機/尺寸= System.String []將用於

回答

2

擴展方法和反思救援!

/// <summary> 
/// Add UrlHelper extension methods that construct outgoing URL's but 
/// remove route values that are excluded by the Bind attribute's 
/// Include or Exclude. The methods to mirror are those that take an 
/// object as an argument: 
/// 
/// public string Action(string actionName, object routeValues); 
/// public string Action(string actionName, string controllerName 
///     , object routeValues); 
/// public string Action(string actionName, string controllerName 
///     , object routeValues, string protocol); 
/// 
/// public string RouteUrl(object routeValues); 
/// public string RouteUrl(string routeName, object routeValues); 
/// public string RouteUrl(string routeName, object routeValues 
///      , string protocol); 
/// </summary> 
public static class UrlHelperExtensions 
{ 
    public static string Action(this UrlHelper helper, string actionName 
           , object routeValues, bool onlyBoundValues) 
    { 
     RouteValueDictionary finalRouteValues = 
      new RouteValueDictionary(routeValues); 

     if (onlyBoundValues) 
     { 
      RemoveUnboundValues(finalRouteValues, routeValues); 
     } 

     // Internally, MVC calls an overload of GenerateUrl with 
     // hard-coded defaults. Since we shouldn't know what these 
     // defaults are, we call the non-extension equivalents. 
     return helper.Action(actionName, routeValues); 
    } 

    public static string Action(this UrlHelper helper, string actionName 
           , string controllerName, object routeValues 
           , bool onlyBoundValues) 
    { 
     RouteValueDictionary finalRouteValues = 
      new RouteValueDictionary(routeValues); 

     if (onlyBoundValues) 
     { 
      RemoveUnboundValues(finalRouteValues, routeValues); 
     } 

     return helper.Action(actionName, controllerName, finalRouteValues); 
    } 

    public static string Action(this UrlHelper helper, string actionName 
           , string controllerName, object routeValues 
           , string protocol, bool onlyBoundValues) 
    { 
     RouteValueDictionary finalRouteValues = 
      new RouteValueDictionary(routeValues); 

     if (onlyBoundValues) 
     { 
      RemoveUnboundValues(finalRouteValues, routeValues); 
     } 

     return helper.Action(actionName, controllerName 
           , finalRouteValues, protocol); 
    } 

    public static string RouteUrl(this UrlHelper helper, object routeValues 
            , bool onlyBoundValues) 
    { 
     RouteValueDictionary finalRouteValues = 
      new RouteValueDictionary(routeValues); 
     if (onlyBoundValues) 
     { 
      RemoveUnboundValues(finalRouteValues, routeValues); 
     } 
     return helper.RouteUrl(finalRouteValues); 
    } 

    public static string RouteUrl(this UrlHelper helper, string routeName 
            , object routeValues, bool onlyBoundValues) 
    { 
     RouteValueDictionary finalRouteValues = 
      new RouteValueDictionary(routeValues); 
     if (onlyBoundValues) 
     { 
      RemoveUnboundValues(finalRouteValues, routeValues); 
     } 
     return helper.RouteUrl(routeName, finalRouteValues); 
    } 

    public static string RouteUrl(this UrlHelper helper, string routeName 
            , object routeValues, string protocol 
            , bool onlyBoundValues) 
    { 
     RouteValueDictionary finalRouteValues = 
      new RouteValueDictionary(routeValues); 

     if (onlyBoundValues) 
     { 
      RemoveUnboundValues(finalRouteValues, routeValues); 
     } 

     return helper.RouteUrl(routeName, finalRouteValues, protocol); 
    } 

    /// <summary> 
    /// Reflect into the routeValueObject and remove any keys from 
    /// routeValues that are not bound by the Bind attribute 
    /// </summary> 
    private static void RemoveUnboundValues(RouteValueDictionary routeValues 
              , object source) 
    { 
     if (source == null) 
     { 
      return; 
     } 

     var type = source.GetType(); 

     BindAttribute b = null; 

     foreach (var attribute in type.GetCustomAttributes(true)) 
     { 
      if (attribute is BindAttribute) 
      { 
       b = (BindAttribute)attribute; 
       break; 
      } 
     } 

     if (b == null) 
     { 
      return; 
     } 

     foreach (var property in type.GetProperties()) 
     { 
      var propertyName = property.Name; 
      if (!b.IsPropertyAllowed(propertyName)) 
      { 
       routeValues.Remove(propertyName); 
      } 
     } 
    } 
} 
1

所有匿名對象的屬性而AFAIK沒有辦法排除一些。 [Bind]屬性用於控制器動作參數,以指示應從模型綁定中排除或包含的模型綁定器屬性,但不用於構建url。您可能需要通過一個指定要一個屬性:

Url.RouteUrl(new { 
    Prop1 = Model.Prop1, 
    Prop2 = Model.Prop2, 
    action = "SomeAction", 
    controller = "SomeController" 
}) 

或只包括ID:

Url.RouteUrl(new { 
    id = Model.Id, 
    action = "SomeAction", 
    controller = "SomeController" 
}) 

,並有目標控制器動作來使用這個號碼,以獲取從模型一些持久性數據存儲。