【问题标题】:GetVirtualPath method in mvcmvc 中的 GetVirtualPath 方法
【发布时间】:2016-03-29 14:04:31
【问题描述】:

谁能解释一下虚拟路径是如何计算的? 根据 RouteData.Values 还是根据 url 模式?

我正在尝试删除一些路由数据值,但虚拟路径仍然没有改变。 我有一个问题,虚拟路径在 URL 的开头返回带有冗余斜杠,例如:/he/controller/action 文化之前的斜杠是多余的......

我正在使用如下自定义路由

    routes.Add("Default",
             new CustomRoute("{culture}/{controller}/{action}/{id}",
                 new
                 {
                     controller = "Desktop",
                     action = "Index",
                     culture = "he-IL",
                     guid = "",
                     id = UrlParameter.Optional
                 }));
  routes.Add("Wizard_" + wizard,
                        new CustomRoute("{guid}/{culture}/" + wizardName + "/{action}/{id}",
                        new
                        {
                            controller = wizard,
                            action = "Index",
                            culture = "he-IL",
                            guid = "",
                            id = UrlParameter.Optional
                        }));

问题是当使用 Url.Action(action, controller) 方法并且动作在向导控制器中时,所以动作的 URL 是向导格式,如 {guid}/{culture}/" + wizard + "/ {action}/{id} bu guid 值为空,返回的 URL 为 //he-il/controller/action 而不是 /he-il/controller/action

CustomRoute 类:

public class CustomRoute : Route
{
    private List<string> _wizards;

    public CustomRoute(string uri, object defaults)
        : base(uri, new RouteValueDictionary(defaults), new MvcRouteHandler())
    {
        _wizards = new List<string>();
        FillWizards(ref _wizards);
        DataTokens = new RouteValueDictionary();
    }

    public override RouteData GetRouteData(HttpContextBase httpContext)
    {
        bool hasGuid = httpContext.Request.RequestContext.RouteData != null 
            && httpContext.Request.RequestContext.RouteData.Values != null 
            && httpContext.Request.RequestContext.RouteData.Values.ContainsKey("guid") 
            && !httpContext.Request.RequestContext.RouteData.Values["guid"].ToString().Equals(Guid.Empty);

        var routeData = base.GetRouteData(httpContext);
        if (routeData == null)
            return null;

        bool isWizard = _wizards.Contains(routeData.Values["controller"].ToString());
        Debug.WriteLine("Controller: " + routeData.Values["controller"] + " action: " + routeData.Values["action"] + " Is wizard: " + isWizard + " has guid: " + hasGuid);
        if (isWizard && !hasGuid)
        {
            if (string.IsNullOrEmpty(routeData.Values["guid"].ToString()))
            {
                routeData.Values["guid"] = Guid.NewGuid().ToString("N");
            }
        }

        return routeData;
    }

    public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
    {
        VirtualPathData path;
        path = base.GetVirtualPath(requestContext, values);

        return path;
    }

    private void FillWizards(ref List<string> items)
    {
        var _configuration = ObjectFactory.GetInstance<IConfiguration>();
        List<string> wizards = _configuration.GetParamValue<string>("SessionUniqueWizards", "").Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList();

        items = wizards;
    }
}

【问题讨论】:

  • 请发布您的路由配置。您是否使用MapRoute 扩展方法?您是否使用自定义路线?从技术上讲,GetVirtualPath 可以使用自定义路由返回您想要的任何内容,因此请展示您的代码。
  • 好的,我正在更新我的问题
  • 请发布您的CustomRoute 课程的代码。

标签: asp.net-mvc asp.net-mvc-routing


【解决方案1】:

你的guid参数丢失的原因是因为

  1. 在您对Url.Action(action, controller) 的调用中没有guid 参数。
  2. 当前请求中(显然)没有guid 参数。也就是说,当前被命中的路由没有guid 路由值。
  3. 您已经为guid (guid = "") 指定了默认值。由于空字符串是您指定的默认值,因此空字符串是您默认获得的。

要正确构建 URL,guid 必须来自某个地方。 MVC always passes matching route values from the current request 在构建传出 URL 时,但由于并非所有 URL 都有 guid,因此您需要为上下文中不存在它的页面指定它:

Url.Action("Index", "Search", new { guid = "a565f84f9152495792d433f5bd26000f")

这是正常的做法。通常,如果您正在为 CRUD 操作构建链接,则您是在实体列表中进行的。

例如,对于Product 实体,您通常会在一个如下所示的列表中为每个Product 提供Edit ProductDelete Product 的链接:

<tr>
    <td>model.ProductName</td>
    <td>@Html.ActionLink("Product", "Edit", new { guid = model.ProductId })</td>
    <td>@Html.ActionLink("Product", "Delete", new { guid = model.ProductId })</td>
</tr>

通常还会有一个链接来添加没有标识符的新实体。

@Html.ActionLink("Product", "Add")

但从您的示例中不清楚如何创建“向导”。创建新标识符通常应该是 Add 方法的函数,而不是路由的函数。

但似乎存在一个问题,即您在路由中随机生成 GUID,因此不清楚您希望如何从一个请求到下一个请求保持此值。

【讨论】:

  • 是的,我知道,这实际上是我的问题,我在我的问题中写了它。如果使用 Url.Action 我不想使用 guid,那么如何使 GetVirtualPath 方法不创建空 guid?
  • 我可以删除 guid,以便在没有 guid 的情况下创建虚拟路径吗?
  • 你不能。看我的更新。目前尚不清楚您的工作流程应该如何工作。谁创造了“向导”?它是否作为实体输入到数据库中?它存储在会话中吗?如果未通过 GUID,应该发生什么?最重要的是,需要有一种方法可以访问路由范围之外的向导实体,以便可以使用其标识符正确生成 URL,但是您没有提供有关应用程序如何运行的足够详细信息应该能够提供完整的解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-21
相关资源
最近更新 更多