Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/32.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何替换某些段';保护他人的价值观? 继续我的一个问题(),请考虑下面的路径(没有缺省,没有约束):_C#_Asp.net_Asp.net Mvc_Asp.net Mvc 3_Asp.net Mvc Routing - Fatal编程技术网

C# 如何替换某些段';保护他人的价值观? 继续我的一个问题(),请考虑下面的路径(没有缺省,没有约束):

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后,返回原始值,以便使用原始请求

假设在通过与此路由匹配的传入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));
    }
    
  • 第二个选项似乎更简短,而第一个选项并不创建额外的字典,而是操纵请求上下文

    哪条路更好?或者也许我在做/理解一些错误的事情

    Sanderson S.,Freeman A.-Pro ASP.NET MVC 3 Framework(第三版)表示不要依赖于段值重用,而是在准确的位置和时间指定所需的所有值

    我展示了我发现的执行此任务的方法,但是如果被替换的线段在路线中提前出现,那么替换线段的值并保留其他值的正确(或更好)方法是什么

    编辑

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

    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);
    }