【问题标题】:Add parameter to all Incoming/Outgoing URL's向所有传入/传出 URL 添加参数
【发布时间】:2014-04-24 22:20:30
【问题描述】:

我在为每个生成的 URL 添加 URL 参数时遇到问题,或者在 ASP MVC 4 应用程序中重定向到。

我想生成一个 ID,并在整个应用程序的任何时候使用此 ID。在会话中存储 id 不是一种选择,因为单个会话可能同时打开多个浏览器窗口/选项卡(每个都有不同的 id)


路由配置

routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{customId}",
            defaults: new { controller = "Home", action = "Index", customid = UrlParameter.Optional }
        );

HomeController.cs

public class HomeController : Controller
{
    public ActionResult Index()
    {
        var customId = Guid.NewGuid();

        ControllerContext.RequestContext.RouteData.Values.Add("customId", customId);

        //How do I get this redirect to add customid to the url?
        //E.g. /Home/Start/{customId}
        return RedirectToAction("Start");
        //I could do this: But I want it this to happen for every URL, 
        //and I don't want to replicate this code everywhere
        //return RedirectToAction("Start", new { customId = customId });
    }

    public ActionResult Start()
    {
        object customId;

        //Redirect Loop
        if (!Request.RequestContext.RouteData.Values.TryGetValue("customId", out customId))
        {
            //To generate the ID
            return RedirectToAction("Index");
        }

        ViewData["customId"] = Guid.Parse(customId.ToString());

        return View();
    }

    public ActionResult Next()
    {
        object customId;

        //Redirect Loop
        if (!Request.RequestContext.RouteData.Values.TryGetValue("customId", out customId))
        {
            //To generate the ID
            return RedirectToAction("Index");
        }

        ViewData["customId"] = Guid.Parse(customId.ToString());

        return View();
    }
}

我不仅希望 ID 自动插入到任何重定向结果中,而且在呈现视图时 @Url.Action()@Html.ActionLink() 还应该将 ID 添加到生成的 URL 中。

Start.cshtml

@*Both of these should generate an href="~/Home/Next/{customId}"*@
@Html.ActionLink("Go to Next", "Next", "Home")
<a href="@Url.Action("Next", "Home")">Go to Next</a>

如何在 ASP MVC 中为所有传出路由自动添加 ID?

【问题讨论】:

  • 这可能会有所帮助。 stackoverflow.com/a/1067211/853295
  • @garethb 是的(如代码注释中所述),确实有效。然而,这个 ID 将在多个控制器和视图中使用,并且必须添加一个带有 customId 的匿名类型(并且记住这样做!)是一种痛苦! :-)
  • 抱歉,错过了! :)

标签: c# asp.net asp.net-mvc asp.net-mvc-4


【解决方案1】:

创建一个将 ID 添加到 OnActionExecuting 方法中的路由数据的操作过滤器?您可以通过过滤器上下文(和 viewbag)访问控制器。只要您的 viewbag 包含 customId,您就应该能够将其添加到路由数据中。至少这样你只需要记住在控制器上添加属性即可。

创建一个继承自 System.Web.Mvc.Controller 的基类并实现您自己的 RedirectToAction。然后让你的所有控制器从 MyControllerBase 继承。像这样。

public class MyControllerBase : Controller
{
    public RedirectToRouteResult RedirectToAction<TController>(Expression<Func<TController, object>> actionExpression)
    {
        var custId = ControllerContext.Controller.ViewBag["customId"];
        string controllerName = typeof(TController).GetControllerName();
        string actionName = actionExpression.GetActionName();

        return RedirectToAction(actionName, controllerName, new {cId = custId});
    }
}

第 2 部分: 我在每个视图上修改了 URL(我知道我在某处有代码!)的另一种方法,我需要 URL 从移动站点链接到完整的浏览器站点并从数据库中读取映射。所以在我的页脚中,我有以下内容:

<a id="fullSiteLink" href="<%= ViewData[AppConstants.MainSiteUrl] %>">Visit our Full Browser site</a><br />

然后我在基本控制器类和 onactionexecuting 中添加了一个过滤器(在操作之前),

public void OnActionExecuting(ActionExecutingContext filterContext)
{
    var mainSiteUrl = _mobileToMainRedirect.GetMainSiteUrl(filterContext.HttpContext.Request.Url);
    filterContext.Controller.ViewData.Add(AppConstants.MainSiteUrl, string.IsNullOrEmpty(mainSiteUrl) ? UrlHelperExtensions.FullBrowserSite(filterContext.HttpContext.Request.Url) : mainSiteUrl);
}

【讨论】:

  • 两者都是不错的选择。我最终使用全局过滤器在OnActionExecuted 中添加ID(在操作运行之后,结果执行之前)。这解决了RedirectToAction 问题。另一部分需要更新传出 URL。我最终通过将customId 插入MvcHandler.BeginProcessRequest 中的RouteData.Values 来实现这一点,要使其正常工作,您还需要在路由中使用customId。我会发布我的代码并接受这个:)
  • 如果您可以发布您的代码,那就太好了!我已经添加了过去的方法,但很高兴看到另一个解决方案!
【解决方案2】:

在黑暗中完成拍摄....

您可以设置路由,以便在未提供值时创建 Id。这样,如果该值存在,它将使用提供的值。否则,它将创建一个。

由于这是利用路由,因此即使使用以下方法,您也可以生成 Id: @Html.ActionLink("Go to Next", "Next", "Home")

routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{customid}",
            defaults: new { controller = "Home", action = "Index", customid = Guid.NewGuid() }
        );

注意:您可以用自己的 ID 生成器替换 Guid.NewGuid()

【讨论】:

  • 路由只创建一次。在此处设置默认值将更改整个应用程序的默认值。 (如果可能的话)它必须是一个代表,例如customId = () =&gt; Guid.NewGuid();
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-06-30
  • 1970-01-01
  • 2016-08-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多