我无法在生成或重定向到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?
答案 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()
。