如何替换某些分段';保护他人的价值观

本文关键字:保护 价值观 分段 何替换 替换 | 更新日期: 2023-09-27 17:51:01

要继续我之前的一个问题(生成传出url时选择了意外路线(,请考虑以下路线(无默认值,无限制(:

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

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

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

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

  1. 根本不要指定匿名对象;而是在CCD_ 6中设置必要的分段值;生成所需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(第三版(表示不要依赖分段值重用,而是要在确切的时间和地点指定所需的所有值。

我展示了我发现的完成这项任务的方法,但如果被替换的段在路线中出现得更早,那么替换段的值并保留其他值的正确(或更好(方法是什么?

编辑

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

如何替换某些分段';保护他人的价值观

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进行一些null检查,但当你有一个没有HttpContext的RequestContext时,这里的null检查是你最小的问题。要么这样,要么你让一个程序员做一些非常时髦的事情,你确实希望应用程序在那里大放异彩,让他们知道他们正在做一些不起作用的事情,他们应该在它投入生产之前就停止。

您可能还需要在这里对其他内容进行额外的检查,但实际上,这种方法的责任到此为止。它应该接受一个日期,并以MvcHtmlString的形式返回一个路由url。时期

从性能角度来看,在生成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