gpt4 book ai didi

c# - 如何替换某些段的值以保留其他段的值?

转载 作者:太空狗 更新时间:2023-10-29 23:40:03 26 4
gpt4 key购买 nike

继续我之前的一个问题 ( Unexpected route chosen while generating an outgoing url ),请考虑以下路线(无默认值,无约束):

"{controller}/{month}-{year}/{action}/{user}"

假设在通过匹配此路由的传入 url 呈现某些页面时(因此请求上下文包含每个路由段的值),我需要生成一个仅更改 monthyear,保留所有其他段的准确值。

根据规则,我在链接的问题中提到(即 路由系统将仅重用在 URL 模式中早于提供的任何参数出现的段变量的值。),如果我仅通过匿名对象指定新的 monthyear,我将丢失 user 段的值(即路由不会甚至匹配)。

我知道有两种方法可以克服这个问题:

  1. 完全不要指定匿名对象;但在 context.RouteData.Values 中设置必要的段值;生成所需的 url 后,返回原始值,以便使用原始请求段值执行其余页面渲染;这看起来像这样:

    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;
    }
    }
    }
  2. 根据当前请求上下文,使用 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));
    }

第二个选项似乎更简短,而第一个选项不创建额外的字典,操纵请求上下文。

哪种方式更好?或者也许我正在做/理解错误的事情?

Sanderson S., Freeman A. - Pro ASP.NET MVC 3 Framework(第 3 版) 表示不要依赖段值重用,但要在确切位置指定所有需要的值,并且时间。

我展示了我找到的执行此任务的方法,但是如果被替换的路段出现在路线的较早位置,什么是替换路段值并保留其他路段值的正确(或更好)方法?

编辑

基于 Jani Hyytiäinen 的回答。所讨论的路线只是一个例子。目标 mvc 应用程序包含不同的路由,有些可能比这个更复杂。所以我正在寻找的方法应该能够与它们中的任何一个一起使用。我会说这个扩展方法只知道,它必须更改 monthyear,同时保留 all 其他段。 other 段的数量是任意的。因此,对所有这些进行硬编码根本不是一个可能的解决方案。此外,除了请求上下文本身,我还有当前段值的来源。

最佳答案

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 时,这里的空值检查是您的问题最少的。要么那个,要么你有一个程序员在做一些非常时髦的事情,你确实希望应用程序在那里吹嘘它所有的荣耀,让他们知道他们正在做一些不起作用的事情,他们应该在它进入之前就停下来生产。

您可能还想对此处的任何其他内容进行额外检查,但实际上,此方法的职责到此为止。它应该接受一个日期并返回一个路由 url 作为 MvcHtmlString。期间。

从性能的角度来看,您可以在生成 url 时在此处明确定义特定的路由名称,但要使其有意义,您需要有相当大的路由集合。考虑到您将在此方法和路由配置之间创建隐藏的依赖关系。有人更改路线名称的那一天,应用程序崩溃了,很难找到原因。

您可能还想使用 RouteValueDictionary,但没有理由。如果我没记错的话,UrlHelper 无论如何都会在内部使用对象。即使我记错了,它也能很好地为你转换。

引用资料:“在确切的时间和地点指定所有需要的值”,Sanderson S.,Freeman A. - Pro ASP.NET MVC 3 Framework

http://msdn.microsoft.com/en-us/library/dd505226(v=vs.108).aspx

关于c# - 如何替换某些段的值以保留其他段的值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14229456/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com