C# 如何替换某些段';保护他人的价值观? 继续我的一个问题(),请考虑下面的路径(没有缺省,没有约束):
假设在通过与此路由匹配的传入url呈现某些页面时(因此请求上下文包含每个路由段的值),我需要生成一个只更改C# 如何替换某些段';保护他人的价值观? 继续我的一个问题(),请考虑下面的路径(没有缺省,没有约束):,c#,asp.net,asp.net-mvc,asp.net-mvc-3,asp.net-mvc-routing,C#,Asp.net,Asp.net Mvc,Asp.net Mvc 3,Asp.net Mvc Routing,假设在通过与此路由匹配的传入url呈现某些页面时(因此请求上下文包含每个路由段的值),我需要生成一个只更改month和year,保留所有其他段的精确值 根据规则,我在链接问题中提到过(即,路由系统将仅重用URL模式中早于提供的任何参数的段变量的值。),如果我仅通过匿名对象指定新的月和年,我将丢失用户段的值(即路线甚至不匹配) 我知道有两种方法可以克服这个问题: 完全不要指定匿名对象;但是在上下文.RouteData.values中正确设置必要的段值;生成所需url后,返回原始值,以便使用原始请求
month
和year
,保留所有其他段的精确值
根据规则,我在链接问题中提到过(即,路由系统将仅重用URL模式中早于提供的任何参数的段变量的值。),如果我仅通过匿名对象指定新的月
和年
,我将丢失用户
段的值(即路线甚至不匹配)
我知道有两种方法可以克服这个问题:
上下文.RouteData.values
中正确设置必要的段值;生成所需url后,返回原始值,以便使用原始请求段值执行rest页面呈现;这看起来像这样:
public static MvcHtmlString GetDateUrl(this RequestContext context,
DateTime date)
{
UrlHelper url = new UrlHelper(context);
object month = null, year = null;
if (context.RouteData.Values.ContainsKey("month"))
{
month = context.RouteData.Values["month"];
year = context.RouteData.Values["year"];
}
try
{
context.RouteData.Values["month"] = date.Month;
context.RouteData.Values["year"] = date.Year;
return MvcHtmlString.Create(
url.Action((string)context.RouteData.Values["action"]));
}
finally
{
if (month == null)
{
if (context.RouteData.Values.ContainsKey("month"))
{
context.RouteData.Values.Remove("month");
context.RouteData.Values.Remove("year");
}
}
else
{
context.RouteData.Values["month"] = month;
context.RouteData.Values["year"] = year;
}
}
}
RouteValueDictionary
,而不是匿名对象:
public static MvcHtmlString GetDateUrl(this RequestContext context,
DateTime date)
{
UrlHelper url = new UrlHelper(context);
var values = new RouteValueDictionary(context.RouteData.Values);
values["month"] = date.Month;
values["year"] = date.Year;
string action = (string)context.RouteData.Values["action"];
return MvcHtmlString.Create(url.Action(action, values));
}
月份
和年份
,同时保留所有其他段。其他段的数量是任意的。因此,硬编码所有这些都不是一个可能的解决方案。此外,除了请求上下文本身之外,我还有当前段值的来源
public static MvcHtmlString GetDateUrl(this RequestContext context, DateTime date)
{
var values = context.RouteData.values;
var data = new{
controller = values["controller"] ?? "Home";
action = values["action"] ?? "Index";
month = date.Month;
year = date.Year;
user = context.HttpContext.User.Identity.Name;
};
string url = UrlHelper.RouteUrl(data);
return MvcHtmlString.Create(url);
}
为什么要把它弄得更复杂?您可能会争辩说您希望对HttpContext执行一些空检查,但是当您有一个没有HttpContext的RequestContext时,这里的空检查是您的最小问题。要么这样,要么你让一个程序员做一些非常时髦的事情,你真的希望应用程序在那里大放异彩,让他们知道他们正在做一些不起作用的事情,他们应该在它投入生产之前就停下来
您可能还需要临时进行其他检查,但实际上,此方法的责任到此为止。它应该接受一个日期,并以MvcHtmlString的形式返回一个路由url。句号
从性能角度来看,在生成url时,您可以在此处显式定义特定的路由名称,但要做到这一点,您需要有相当大的路由集合。考虑到您将在这个方法和路由配置之间创建一个隐藏的依赖关系。有人更改路线名称的那一天,应用程序就会崩溃,很难找到原因
您可能还想使用RouteValueDictionary,但没有理由。如果我没记错的话,UrlHelper将在内部使用对象。即使我记错了,它也能帮你转换
参考资料:
“一定要在准确的时间和地点指定所需的所有值”,Sanderson S.,Freeman A.-Pro ASP.NET MVC 3框架
可能我没有说清楚,但最终我需要能够处理任何路由,即我永远不知道当前需要选择什么路由,或者请求上下文中有多少段。如果有一些额外的部分,你将如何克服它?任何可能组合的硬编码??不,当前的请求上下文内容应该是一个黑匣子。我也非常感激,如果投票人留下评论让我能够改进这篇文章。沉默的向下投票对我来说毫无意义……如果路由引擎可以提取值,那么您也可以。然后可以更改所需的值。但仅基于此RoutedData生成传出url并不是一件小事:您的解决方案每年都要硬编码。所以我不明白@Jani Hyytiäinen的答案有什么问题?这个问题也被否决了,因为你不清楚你到底在问什么。现在重读几遍,你问了一个简单的问题,你已经把它复杂化了。此外,“示例1”在逻辑上不一致,因为finally语句毫无意义。所以绝对不要这样做。@mattmanser 1)我硬编码
月
和年
,但不编码任何其他部分。这是重点,这个答案是错误的。2) 如果这是一个简单的任务,你能发布你的答案,向我解释一下这个简单性吗。3) 您还可以解释一下在示例1中发现的逻辑不一致性。它已经在一个真实的应用程序中进行了测试,效果很好。@mattmanser 4)当问题不清楚,被问到什么时,这个问题很难获得5票赞成票,而且绝对肯定会得到一条评论,要求几乎立刻重新解释这个问题。如果你不清楚什么,是什么阻止你要求我澄清这一点,并给我一个值得投票+接受+赏金的好答案?
public static MvcHtmlString GetDateUrl(this RequestContext context, DateTime date)
{
var values = context.RouteData.values;
var data = new{
controller = values["controller"] ?? "Home";
action = values["action"] ?? "Index";
month = date.Month;
year = date.Year;
user = context.HttpContext.User.Identity.Name;
};
string url = UrlHelper.RouteUrl(data);
return MvcHtmlString.Create(url);
}