Ну, я наконец-то придумал дизайн, который, кажется, работает. Я написал расширение контроллера,
с помощью метода GetHomePage. Это расширение также может быть использовано в ваших представлениях. Вот как я это сделал:
public static class UserHelperExtension {
public static string GetHomePage(this ControllerBase controller, User user) {
return = "http://" + controller.ControllerContext
.HttpContext.Request
.ServerVariables["HTTP_HOST"] + "/"
+ GetHomePage(user);
}
//need this for views
public static string GetHomePage(string httphost, User user) {
return = "http://" + httphost + "/" + GetHomePage(user});
}
private static string GetHomePage(User user) {
if (user.IsInRole(Role.Admin))
return "/Admin/Home/Index";
if (user.IsInRole(Role.Editor))
return "/Editor/Home/Index";
if (user.IsInRole(Role.Reader))
return "/Reader/Home/Index";
return "/Home/Index";
}
}
Метод действия в контроллере выглядит следующим образом:
using Extensions;
...
public ActionResult SomethingHere() {
return Redirect(this.GetHomePage(user));
}
...
В представлении у меня есть это:
...
<%@ Import Namespace="Extensions"%>
<%=UserHelperExtension.GetHomePage(Request.ServerVariables["HTTP_HOST"], user)%>
...
Преимущество состоит в том, что я могу легко использовать этот метод "GetHomePage" в различных контроллерах,
или просматривает мое приложение, и логика в одном месте. Недостатком является то, что
Я бы предпочел иметь более безопасный тип. Например, в моих оригинальных тестах у меня был доступ к коллекции RouteValues:
public void User_should_redirect_to_role_home(Role role,
string area, string controller, string action) {
...
var result = (RedirectToRouteResult)userController.SomeThingHere();
Assert.That(result.RouteValues["area"],
Is.EqualTo(area).IgnoreCase);
Assert.That(result.RouteValues["controller"],
Is.EqualTo(controller).IgnoreCase);
Assert.That(result.RouteValues["action"],
Is.EqualTo(action).IgnoreCase);
...
}
Но теперь, когда я использую строку, так что она небезопасна, я проверяю RedirectResult.Url.
...
var result = (RedirectResult) userController.SomethingHere();
Assert.That(result.Url.EndsWith("/" + area + "/" + controller + "/" + action),
Is.True);
...