(我正在使用ASP.NET MVC 2.)
使用Url.RouteUrl(object)
时,如何排除某些属性进入查询字符串?
具体来说,在我传递给我的View的Model对象中,我有一个字符串数组(技术上IEnumerable< string>)我想要排除。
我认为带有Exclude的Bind属性应该这样做,但它不起作用。我尝试将[Bind(Exclude = "Sizes")]
放在我的课堂上,但我不断获得如下所示的网址:
的http://本地主机/尺寸= System.String []
答案 0 :(得分: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 :(得分: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"
})
并让目标控制器操作使用此id来从某个持久数据存储中获取模型。