How to mask the controller and action name from th

2019-09-11 23:23发布

问题:

I want to display just the host url in the browser.

Example:

www.test.com/account/login or www.test.com/contact/index or www.test.com/order/details/12

to only display:

www.test.com

in browser

回答1:

First of all in terms of usability and in terms of SEO, what is considered "good content" is something that your users can link to.

If you build a "page" that has no URL path, then your users won't be able to link to it, share the link, etc. Search engines will also not be able to crawl it, so it will not get indexed.

There are some situations (security concerns) where this behavior may be desirable to prevent a resource from being shared between users.

The Standard Way

In that case, your best option would be to create a Single Page Application with the help of a JavaScript framework such as AngularJS (see this tutorial to get started). Your best option for interaction (exchanging data) with the server would be to use WebApi, but any "navigation" happens entirely in the browser.

The Non-Standard Way

Another option is to customize the routing in MVC so it can read the navigation from another part of the request and come up with some custom convention that determines what route values to generate from the request so MVC knows which controller action to call. You could do that with a custom RouteBase implementation.

Here is an example:

View

@using (Html.BeginForm())
{
    <input type="hidden" name="location-controller" value="Home" />
    <input type="hidden" name="location-action" value="Index" />

    <input type="submit" value="Home" />
}

@using (Html.BeginForm())
{
    <input type="hidden" name="location-controller" value="Home" />
    <input type="hidden" name="location-action" value="Contact" />

    <input type="submit" value="Contact" />
}

@using (Html.BeginForm())
{
    <input type="hidden" name="location-controller" value="Home" />
    <input type="hidden" name="location-action" value="About" />

    <input type="submit" value="About" />
}

PathlessRoute

using System.Web;
using System.Web.Mvc;
using System.Web.Routing;

namespace MvcApplication12
{
    public class PathlessRoute : RouteBase
    {
        public override RouteData GetRouteData(HttpContextBase httpContext)
        {
            RouteData result = null;
            var form = httpContext.Request.Form;

            // Skip any forms that are not part of our scheme
            if (form != null && form.HasKeys())
            {
                var controller = form["location-controller"];
                var action = form["location-action"];

                if (!string.IsNullOrWhiteSpace(action))
                {
                    // Default controller to "Home"
                    if (string.IsNullOrWhiteSpace(controller))
                    {
                        controller = "Home";
                    }

                    result = new RouteData(this, new MvcRouteHandler());
                    result.Values["controller"] = controller;
                    result.Values["action"] = action;

                    // TODO: Work out scheme to pass custom route values (such as "id")
                }
            }

            return result;
        }

        public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
        {
            return null;
        }
    }
}

Usage

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

        routes.Add("Pathless", new PathlessRoute());

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

Now when you click on the "Contact" submit button you will get the contact view, but the URL will not have a path indicating which page you are looking at.


You could improve things more by creating your own HTML helper extension method to render your form tags the same way you can use ActionLink to create hyperlinks.

@Html.ActionLinkPost(name: "Contact", action: "Contact", controller: "Home")

You could even style the buttons to look like hyperlinks or use some JavaScript to make real hyperlinks that post.


But if you go down this road, you are swimming in new waters and going against standard HTTP conventions (for example, you are navigating with POST, which is not standard). You can be sure you won't find much (if any) support on this approach around the web to overcome any pitfalls that you may run into.