- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想得越多,我就越相信可以编写一个使用这些 URL 定义的自定义路由:
{var1}/{var2}/{var3}
Const/{var1}/{var2}
Const1/{var1}/Const2/{var2}
{var1}/{var2}/Const
{*var1}/{var2}/{var3}
{var1}/{*var2}/{var3}
{var1}/{var2}/{*var3}
http://localhost/Show/Topic/SubTopic/SubSubTopic/123/This-is-an-example
{action}/{*topicTree}/{id}/{title}
GetRouteData()
应该像这样工作:
GetVirtuaPath()
方法。
最佳答案
最近问的比较急,一般都是自己解决问题。很抱歉,但这是我对我所询问的那种路线的看法。任何人发现它有任何问题:让我知道。
在 URL 中的任何位置使用全能段路由
/// <summary>
/// This route is used for cases where we want greedy route segments anywhere in the route URL definition
/// </summary>
public class GreedyRoute : Route
{
#region Properties
public new string Url { get; private set; }
private LinkedList<GreedyRouteSegment> urlSegments = new LinkedList<GreedyRouteSegment>();
private bool hasGreedySegment = false;
public int MinRequiredSegments { get; private set; }
#endregion
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="VivaRoute"/> class, using the specified URL pattern and handler class.
/// </summary>
/// <param name="url">The URL pattern for the route.</param>
/// <param name="routeHandler">The object that processes requests for the route.</param>
public GreedyRoute(string url, IRouteHandler routeHandler)
: this(url, null, null, null, routeHandler)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="VivaRoute"/> class, using the specified URL pattern, handler class, and default parameter values.
/// </summary>
/// <param name="url">The URL pattern for the route.</param>
/// <param name="defaults">The values to use if the URL does not contain all the parameters.</param>
/// <param name="routeHandler">The object that processes requests for the route.</param>
public GreedyRoute(string url, RouteValueDictionary defaults, IRouteHandler routeHandler)
: this(url, defaults, null, null, routeHandler)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="VivaRoute"/> class, using the specified URL pattern, handler class, default parameter values, and constraints.
/// </summary>
/// <param name="url">The URL pattern for the route.</param>
/// <param name="defaults">The values to use if the URL does not contain all the parameters.</param>
/// <param name="constraints">A regular expression that specifies valid values for a URL parameter.</param>
/// <param name="routeHandler">The object that processes requests for the route.</param>
public GreedyRoute(string url, RouteValueDictionary defaults, RouteValueDictionary constraints, IRouteHandler routeHandler)
: this(url, defaults, constraints, null, routeHandler)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="VivaRoute"/> class, using the specified URL pattern, handler class, default parameter values, constraints, and custom values.
/// </summary>
/// <param name="url">The URL pattern for the route.</param>
/// <param name="defaults">The values to use if the URL does not contain all the parameters.</param>
/// <param name="constraints">A regular expression that specifies valid values for a URL parameter.</param>
/// <param name="dataTokens">Custom values that are passed to the route handler, but which are not used to determine whether the route matches a specific URL pattern. The route handler might need these values to process the request.</param>
/// <param name="routeHandler">The object that processes requests for the route.</param>
public GreedyRoute(string url, RouteValueDictionary defaults, RouteValueDictionary constraints, RouteValueDictionary dataTokens, IRouteHandler routeHandler)
: base(url.Replace("*", ""), defaults, constraints, dataTokens, routeHandler)
{
this.Defaults = defaults ?? new RouteValueDictionary();
this.Constraints = constraints;
this.DataTokens = dataTokens;
this.RouteHandler = routeHandler;
this.Url = url;
this.MinRequiredSegments = 0;
// URL must be defined
if (string.IsNullOrEmpty(url))
{
throw new ArgumentException("Route URL must be defined.", "url");
}
// correct URL definition can have AT MOST ONE greedy segment
if (url.Split('*').Length > 2)
{
throw new ArgumentException("Route URL can have at most one greedy segment, but not more.", "url");
}
Regex rx = new Regex(@"^(?<isToken>{)?(?(isToken)(?<isGreedy>\*?))(?<name>[a-zA-Z0-9-_]+)(?(isToken)})$", RegexOptions.Compiled | RegexOptions.Singleline);
foreach (string segment in url.Split('/'))
{
// segment must not be empty
if (string.IsNullOrEmpty(segment))
{
throw new ArgumentException("Route URL is invalid. Sequence \"//\" is not allowed.", "url");
}
if (rx.IsMatch(segment))
{
Match m = rx.Match(segment);
GreedyRouteSegment s = new GreedyRouteSegment {
IsToken = m.Groups["isToken"].Value.Length.Equals(1),
IsGreedy = m.Groups["isGreedy"].Value.Length.Equals(1),
Name = m.Groups["name"].Value
};
this.urlSegments.AddLast(s);
this.hasGreedySegment |= s.IsGreedy;
continue;
}
throw new ArgumentException("Route URL is invalid.", "url");
}
// get minimum required segments for this route
LinkedListNode<GreedyRouteSegment> seg = this.urlSegments.Last;
int sIndex = this.urlSegments.Count;
while(seg != null && this.MinRequiredSegments.Equals(0))
{
if (!seg.Value.IsToken || !this.Defaults.ContainsKey(seg.Value.Name))
{
this.MinRequiredSegments = Math.Max(this.MinRequiredSegments, sIndex);
}
sIndex--;
seg = seg.Previous;
}
// check that segments after greedy segment don't define a default
if (this.hasGreedySegment)
{
LinkedListNode<GreedyRouteSegment> s = this.urlSegments.Last;
while (s != null && !s.Value.IsGreedy)
{
if (s.Value.IsToken && this.Defaults.ContainsKey(s.Value.Name))
{
throw new ArgumentException(string.Format("Defaults for route segment \"{0}\" is not allowed, because it's specified after greedy catch-all segment.", s.Value.Name), "defaults");
}
s = s.Previous;
}
}
}
#endregion
#region GetRouteData
/// <summary>
/// Returns information about the requested route.
/// </summary>
/// <param name="httpContext">An object that encapsulates information about the HTTP request.</param>
/// <returns>
/// An object that contains the values from the route definition.
/// </returns>
public override RouteData GetRouteData(HttpContextBase httpContext)
{
string virtualPath = httpContext.Request.AppRelativeCurrentExecutionFilePath.Substring(2) + httpContext.Request.PathInfo;
RouteValueDictionary values = this.ParseRoute(virtualPath);
if (values == null)
{
return null;
}
RouteData result = new RouteData(this, this.RouteHandler);
if (!this.ProcessConstraints(httpContext, values, RouteDirection.IncomingRequest))
{
return null;
}
// everything's fine, fill route data
foreach (KeyValuePair<string, object> value in values)
{
result.Values.Add(value.Key, value.Value);
}
if (this.DataTokens != null)
{
foreach (KeyValuePair<string, object> token in this.DataTokens)
{
result.DataTokens.Add(token.Key, token.Value);
}
}
return result;
}
#endregion
#region GetVirtualPath
/// <summary>
/// Returns information about the URL that is associated with the route.
/// </summary>
/// <param name="requestContext">An object that encapsulates information about the requested route.</param>
/// <param name="values">An object that contains the parameters for a route.</param>
/// <returns>
/// An object that contains information about the URL that is associated with the route.
/// </returns>
public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
{
RouteUrl url = this.Bind(requestContext.RouteData.Values, values);
if (url == null)
{
return null;
}
if (!this.ProcessConstraints(requestContext.HttpContext, url.Values, RouteDirection.UrlGeneration))
{
return null;
}
VirtualPathData data = new VirtualPathData(this, url.Url);
if (this.DataTokens != null)
{
foreach (KeyValuePair<string, object> pair in this.DataTokens)
{
data.DataTokens[pair.Key] = pair.Value;
}
}
return data;
}
#endregion
#region Private methods
#region ProcessConstraints
/// <summary>
/// Processes constraints.
/// </summary>
/// <param name="httpContext">The HTTP context.</param>
/// <param name="values">Route values.</param>
/// <param name="direction">Route direction.</param>
/// <returns><c>true</c> if constraints are satisfied; otherwise, <c>false</c>.</returns>
private bool ProcessConstraints(HttpContextBase httpContext, RouteValueDictionary values, RouteDirection direction)
{
if (this.Constraints != null)
{
foreach (KeyValuePair<string, object> constraint in this.Constraints)
{
if (!this.ProcessConstraint(httpContext, constraint.Value, constraint.Key, values, direction))
{
return false;
}
}
}
return true;
}
#endregion
#region ParseRoute
/// <summary>
/// Parses the route into segment data as defined by this route.
/// </summary>
/// <param name="virtualPath">Virtual path.</param>
/// <returns>Returns <see cref="System.Web.Routing.RouteValueDictionary"/> dictionary of route values.</returns>
private RouteValueDictionary ParseRoute(string virtualPath)
{
Stack<string> parts = new Stack<string>(virtualPath.Split(new char[] {'/'}, StringSplitOptions.RemoveEmptyEntries));
// number of request route parts must match route URL definition
if (parts.Count < this.MinRequiredSegments)
{
return null;
}
RouteValueDictionary result = new RouteValueDictionary();
// start parsing from the beginning
bool finished = false;
LinkedListNode<GreedyRouteSegment> currentSegment = this.urlSegments.First;
while (!finished && !currentSegment.Value.IsGreedy)
{
object p = parts.Pop();
if (currentSegment.Value.IsToken)
{
p = p ?? this.Defaults[currentSegment.Value.Name];
result.Add(currentSegment.Value.Name, p);
currentSegment = currentSegment.Next;
finished = currentSegment == null;
continue;
}
if (!currentSegment.Value.Equals(p))
{
return null;
}
}
// continue from the end if needed
parts = new Stack<string>(parts.Reverse());
currentSegment = this.urlSegments.Last;
while (!finished && !currentSegment.Value.IsGreedy)
{
object p = parts.Pop();
if (currentSegment.Value.IsToken)
{
p = p ?? this.Defaults[currentSegment.Value.Name];
result.Add(currentSegment.Value.Name, p);
currentSegment = currentSegment.Previous;
finished = currentSegment == null;
continue;
}
if (!currentSegment.Value.Equals(p))
{
return null;
}
}
// fill in the greedy catch-all segment
if (!finished)
{
object remaining = string.Join("/", parts.Reverse().ToArray()) ?? this.Defaults[currentSegment.Value.Name];
result.Add(currentSegment.Value.Name, remaining);
}
// add remaining default values
foreach (KeyValuePair<string, object> def in this.Defaults)
{
if (!result.ContainsKey(def.Key))
{
result.Add(def.Key, def.Value);
}
}
return result;
}
#endregion
#region Bind
/// <summary>
/// Binds the specified current values and values into a URL.
/// </summary>
/// <param name="currentValues">Current route data values.</param>
/// <param name="values">Additional route values that can be used to generate the URL.</param>
/// <returns>Returns a URL route string.</returns>
private RouteUrl Bind(RouteValueDictionary currentValues, RouteValueDictionary values)
{
currentValues = currentValues ?? new RouteValueDictionary();
values = values ?? new RouteValueDictionary();
HashSet<string> required = new HashSet<string>(this.urlSegments.Where(seg => seg.IsToken).ToList().ConvertAll(seg => seg.Name), StringComparer.OrdinalIgnoreCase);
RouteValueDictionary routeValues = new RouteValueDictionary();
object dataValue = null;
foreach (string token in new List<string>(required))
{
dataValue = values[token] ?? currentValues[token] ?? this.Defaults[token];
if (this.IsUsable(dataValue))
{
string val = dataValue as string;
if (val != null)
{
val = val.StartsWith("/") ? val.Substring(1) : val;
val = val.EndsWith("/") ? val.Substring(0, val.Length - 1) : val;
}
routeValues.Add(token, val ?? dataValue);
required.Remove(token);
}
}
// this route data is not related to this route
if (required.Count > 0)
{
return null;
}
// add all remaining values
foreach (KeyValuePair<string, object> pair1 in values)
{
if (this.IsUsable(pair1.Value) && !routeValues.ContainsKey(pair1.Key))
{
routeValues.Add(pair1.Key, pair1.Value);
}
}
// add remaining defaults
foreach (KeyValuePair<string, object> pair2 in this.Defaults)
{
if (this.IsUsable(pair2.Value) && !routeValues.ContainsKey(pair2.Key))
{
routeValues.Add(pair2.Key, pair2.Value);
}
}
// check that non-segment defaults are the same as those provided
RouteValueDictionary nonRouteDefaults = new RouteValueDictionary(this.Defaults);
foreach (GreedyRouteSegment seg in this.urlSegments.Where(ss => ss.IsToken))
{
nonRouteDefaults.Remove(seg.Name);
}
foreach (KeyValuePair<string, object> pair3 in nonRouteDefaults)
{
if (!routeValues.ContainsKey(pair3.Key) || !this.RoutePartsEqual(pair3.Value, routeValues[pair3.Key]))
{
// route data is not related to this route
return null;
}
}
StringBuilder sb = new StringBuilder();
RouteValueDictionary valuesToUse = new RouteValueDictionary(routeValues);
bool mustAdd = this.hasGreedySegment;
// build URL string
LinkedListNode<GreedyRouteSegment> s = this.urlSegments.Last;
object segmentValue = null;
while (s != null)
{
if (s.Value.IsToken)
{
segmentValue = valuesToUse[s.Value.Name];
mustAdd = mustAdd || !this.RoutePartsEqual(segmentValue, this.Defaults[s.Value.Name]);
valuesToUse.Remove(s.Value.Name);
}
else
{
segmentValue = s.Value.Name;
mustAdd = true;
}
if (mustAdd)
{
sb.Insert(0, sb.Length > 0 ? "/" : string.Empty);
sb.Insert(0, Uri.EscapeUriString(Convert.ToString(segmentValue, CultureInfo.InvariantCulture)));
}
s = s.Previous;
}
// add remaining values
if (valuesToUse.Count > 0)
{
bool first = true;
foreach (KeyValuePair<string, object> pair3 in valuesToUse)
{
// only add when different from defaults
if (!this.RoutePartsEqual(pair3.Value, this.Defaults[pair3.Key]))
{
sb.Append(first ? "?" : "&");
sb.Append(Uri.EscapeDataString(pair3.Key));
sb.Append("=");
sb.Append(Uri.EscapeDataString(Convert.ToString(pair3.Value, CultureInfo.InvariantCulture)));
first = false;
}
}
}
return new RouteUrl {
Url = sb.ToString(),
Values = routeValues
};
}
#endregion
#region IsUsable
/// <summary>
/// Determines whether an object actually is instantiated or has a value.
/// </summary>
/// <param name="value">Object value to check.</param>
/// <returns>
/// <c>true</c> if an object is instantiated or has a value; otherwise, <c>false</c>.
/// </returns>
private bool IsUsable(object value)
{
string val = value as string;
if (val != null)
{
return val.Length > 0;
}
return value != null;
}
#endregion
#region RoutePartsEqual
/// <summary>
/// Checks if two route parts are equal
/// </summary>
/// <param name="firstValue">The first value.</param>
/// <param name="secondValue">The second value.</param>
/// <returns><c>true</c> if both values are equal; otherwise, <c>false</c>.</returns>
private bool RoutePartsEqual(object firstValue, object secondValue)
{
string sFirst = firstValue as string;
string sSecond = secondValue as string;
if ((sFirst != null) && (sSecond != null))
{
return string.Equals(sFirst, sSecond, StringComparison.OrdinalIgnoreCase);
}
if ((sFirst != null) && (sSecond != null))
{
return sFirst.Equals(sSecond);
}
return (sFirst == sSecond);
}
#endregion
#endregion
}
/// <summary>
/// Represents a route segment
/// </summary>
public class RouteSegment
{
/// <summary>
/// Gets or sets segment path or token name.
/// </summary>
/// <value>Route segment path or token name.</value>
public string Name { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this segment is greedy.
/// </summary>
/// <value><c>true</c> if this segment is greedy; otherwise, <c>false</c>.</value>
public bool IsGreedy { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this segment is a token.
/// </summary>
/// <value><c>true</c> if this segment is a token; otherwise, <c>false</c>.</value>
public bool IsToken { get; set; }
}
/// <summary>
/// Represents a generated route url with route data
/// </summary>
public class RouteUrl
{
/// <summary>
/// Gets or sets the route URL.
/// </summary>
/// <value>Route URL.</value>
public string Url { get; set; }
/// <summary>
/// Gets or sets route values.
/// </summary>
/// <value>Route values.</value>
public RouteValueDictionary Values { get; set; }
}
关于asp.net-mvc - Asp.net MVC Route 类,支持 URL 中任何位置的全部参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2378222/
我正在尝试获取从过去的 startposition/location 到当前移动的 currentposition/location 的距离(以米为单位)。 我确实有工作正常的currentposit
所以我有一堆绝对覆盖的 div。用户通过在叠加层上拖动来创建方形 div。如果您要创建一个 div,然后放大和缩小,div 会保持在同一位置,因为它对叠加层是绝对的,如前所述。 然而问题就出在这里。您
我想找到 View 在显示屏幕上的位置。 为此,我使用了 view.getLeft() 、view.getBottom() 、view.getRight() 等方法> , view.getTop()。
我有一个看起来像这样的 View 层次结构(基于其他答案和 Apple 的使用 UIScrollView 的高级 AutoLayout 指南): ScrollView 所需的2 个步骤是: 为 Scr
所以我有一个名为 MARKS 的表,我有这些列 STUDENT_ID, CLASSFORM_NAME, ACADEMIC_YEAR, TERM, SUBJECT_NAME, TOTAL_MARKS
我有一个问题我无法理解,请帮助: 我开发了带有图像的 html 页面,并使用 jQuery UI 帮助使它们可拖动,我将这些图像位置设置为相对位置并给出了左侧和顶部像素,这是页面的链接 http://
我正在尝试创建一个 CSS 动画,它在 sprite 表中循环播放 16 个图像,给人一种幽灵“漂浮”的错觉。动画通过在 background-position 位置之间移动以显示不同状态的幽灵来实现
我正在创建这个网站的 WebView https://nearxt.com/打开时询问位置但是当我使用此链接在 flutter 中创建 webview 时那么它就无法定位我还在应用程序中定义了位置,但
我正在以编程方式创建一个需要跨越 2 个屏幕的窗口。正在创建的窗口的大小是正确的,但窗口大约从第一个屏幕的一半开始。我可以将它拖回第一个屏幕的开头,NSWindow 非常适合。 我只需要知道在窗口的起
位置“/”的匹配叶路由没有元素。这意味着默认情况下它将呈现一个空值,从而导致一个“空”页面 //App.js File import { BrowserRouter as Router, Routes
我有一个运行 Ubuntu 和 Apache 的 VPS 例如,假设地址是:5.5.5.5 在 VPS 上,我有一个名为 eggdrop 的用户(除了我的 root 用户)。 用户 eggdrop 有
我有一个 JLabel与 ImageIcon ,我使用 setIcon() JLabel中的函数. ImageIcon然后上来,坐在我的JLabel 的文字左侧.是否有可能拥有 ImageIcon在文
我的图中有节点,它们的 xlabels 位于它们的左上方。我怎样才能改变这个位置?我希望 xlabels 正好位于节点本身的旁边。 最佳答案 xlp是你想要的属性,但它没有做任何事情。 你不能改变位置
我对基本的 VIM 功能有疑问:(我尝试谷歌搜索但找不到答案) 如何列出所有自定义功能。(我做了 :function 并且不能找到我的自定义函数) 如何获得自定义函数列表中的函数(或它们的存储位置)。
我是 PHP 的新手,虽然我一直在搜索,但我不知道该怎么做。 我知道可以使用 Location("some page") 进行重定向。我还读到,只要没有向用户显示任何内容,它就可以工作。 我想做的是:
如果在 jgrowl.css 中位置更改为“center”,我如何将其覆盖为默认值,即“top-right” $.jGrowl(data, { header: 'data', an
我需要根据用户是否滑动屏幕顶部、屏幕中间或屏幕底部来触发不同的事件。我正在尝试找出最好/最简单的方法来做到这一点,因为我很确定没有办法从 UISwipeGestureRecognizer 获取位置。
我需要枚举用delphi编写的外部应用程序中使用的类 ,因此我需要访问VMT表以获取该信息,但是我找不到任何有关如何在exe(由delphi生成)文件中找到VMT(虚拟方法表)的位置(地址)的文档。
在 D2010 (unicode) 中是否有像 Pos 这样不区分大小写的类似函数? 我知道我可以使用 Pos(AnsiUpperCase(FindString), AnsiUpperCase(Sou
我正在尝试为我的reveal.js 演示文稿制作一个标题,该标题会粘贴在屏幕顶部。标题中的内容在每张幻灯片的基础上都是动态的,因此我必须将标记放在 section 标记中。 显然,如果标记在 sect
我是一名优秀的程序员,十分优秀!