1

ユーザーに次のようなバニティ URL を提供したいと思います。

www.foo.com/sergio

どのようなルートを作成する必要がありますか?

次のコントローラーとアクションがあるとします。バニティ URL をそのコントローラーにマップするにはどうすればよいでしょうか?

public ActionResult Profile(string username)
{
    var model = LoadProfile(username);
    return View(model);
}

これが私が試したことと何が起こるかです:

オプション A:

すべての URL がこのルートでキャッチされます。つまり、入力したすべての URL は、 だけではなく Account コントローラーに誘導されますfoo.com/[USERNAME]。ダメ。

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
        "Profile",
        "{username}",
        new { controller = "Account", action = "Profile", username = UrlParameter.Optional }
    );

    routes.MapRoute(
        "Default", // Route name
        "{controller}/{action}/{id}", // URL with parameters
        new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
    );
}

オプション B:

デフォルト ルートはうまく機能しますが、プロファイルfoo.com/[USERNAME]にアクセスしようとすると HTTP 404 エラーが発生します。

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
        "Default", // Route name
        "{controller}/{action}/{id}", // URL with parameters
        new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
    );

    routes.MapRoute(
        "DentistProfile",
        "{username}",
        new { controller = "Account", action = "Profile", username = UrlParameter.Optional }
    );
}
4

2 に答える 2

1

1つの解決策は、カスタムルート制約を次のように使用することです。

public class VanityUrlContraint : IRouteConstraint
{
    private static readonly string[] Controllers =
        Assembly.GetExecutingAssembly().GetTypes().Where(x => typeof(IController).IsAssignableFrom(x))
            .Select(x => x.Name.ToLower().Replace("controller", "")).ToArray();

    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values,
                      RouteDirection routeDirection)
    {
        return !Controllers.Contains(values[parameterName].ToString().ToLower());
    }
}

として使用します

    routes.MapRoute(
        name: "Profile",
        url: "{username}",
        defaults: new {controller = "Account", action = "Profile"},
        constraints: new { username = new VanityUrlContraint() }
    );

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

このアプローチの欠点は、既存のコントローラー名と同じユーザー名のプロファイルビューが機能しないことです。たとえば、「asset」、「location」、「AssetController」などのユーザー名がある場合、「LocationController」はプロジェクトに存在し、「asset」のプロファイルビューは機能しません。 、「場所」は機能しません。

お役に立てれば。

于 2012-11-30T08:07:49.267 に答える
0

やってみました:

routes.MapRoute(
"YourRouteName",
"{username}",
new {controller="YourController", action="Profile", username=UrlParameter.Optional}
);

これにより、www.foo.com/{username}がトラップされます。ルートは追加した順序でチェックされるため、追加できます。

routes.MapRoute(
"default",
"{controller}/{action}/{input}",
new {controller="controller", action="action", input=UrlParameter.Optional}
);

最初に「デフォルト」の動作を維持します。

于 2012-11-27T18:09:44.193 に答える