将参数添加到所有传入/传出URL

时间:2014-03-18 23:00:17

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

我无法在生成或重定向到ASP MVC 4应用程序的每个网址中添加网址参数。

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


RouteConfig

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?

2 个答案:

答案 0 :(得分:4)

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

OR

创建一个继承自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);
}

答案 1 :(得分:0)

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

您可以设置路线,以便在未提供值时创建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()