Can I change URL of content? - umbraco

I have created some contents. I have noticed URL of content is generated automatically based on name of content. Can you please guide me if I can edit URL or enter a custom URL ?
Thanks

You can do it in 2 ways:
1
Setup these rules in UrlRewrite.config in /config folder in your umbraco websites root. To add new rule:
<add name="produktidrewrite"
virtualUrl="^~/product/(.*).aspx"
rewriteUrlParameter="ExcludeFromClientQueryString"
destinationUrl="~/product.aspx?productid=$1"
ignoreCase="true" />
2.
Or you can add a custom route in your code. Create a new class which inherit from Umbraco.Core.ApplicationEventHandler. Then overwrite ApplicationStarted to add your rules. Like this:
protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
{
//Custom route
RouteTable.Routes.MapRoute(
"SomeName",
"Something/{action}/{id}",
new
{
controller = "MyController",
action = "Index",
id = UrlParameter.Optional
});
}

Related

Creating folder in view where I can put my other views

I just got a question about the controller management.
I just try to get folder in my view/{copntroller}/newFolder/currentView.
I was trying to use maprouting, but that doesn't work well(doesn't work at all :D).
I just try to put this code in "RouteConfig.cs"
routes.MapRoute(
name: "Admin",
url: "{controller}/{Folder}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
Here is a picture of current
Routing doesn't change Views location search. It change Url routing (Read like: Understand what Controller method call when user sends request, but not what View use to render).
If you want change your default View search locations you should redefine ViewEngine like this:
public class CustomViewEngine : RazorViewEngine //Here you inherit from current ViewEngine
{
public CustomViewEngine()
{
ViewLocationFormats = new[]
{
//That's your Views loactions
"~/Views/{1}/Create/{0}.cshtml",
"~/Views/{1}/Edit/{0}.cshtml",
};
}
}
Here {0} - is Your Contoller method name (Action), {1} - Controller name.
You can define many different locations and ViewEngine will search in defined order.
The last thing you should do is register your CustomViewEngine in global.asax.cs method Application_Start() like this:
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new CustomViewEngine());

Creating multilingual not found page in MVC

We have a multilingual website that has content in four languages.Every language is understood by the language name that we add at the first of our url.
This is our routeConfig.cs:
routes.MapRoute(
name: "Default",
url: "{lang}/{controller}/{action}/{id}/{title}",
defaults: new { lang = "fa", controller = "Home", action = "Index", id = UrlParameter.Optional,title = UrlParameter.Optional }
and this is generated the url: /en/ContactUs/Index
Also, in our controllers we get the language name from url and change the currentCulture and currentUiCulture based on it.
Now, we want to have a not found page in all of the languages. Normally, to make it happen we add an error contoller and a NotFound action and view, then we add this section in our web.config:
<customErrors mode="On" defaultRedirect="error">
<error statusCode="404" redirect="error/notfound" />
<error statusCode="403" redirect="error/forbidden" />
</customErrors>
We have added a NotFound page that we use .resx files in it to make rtl/ltr and to show the messages in four languages.
But the problem here is that in a multilingual website we are not allowed to use this address "error/notfound" because there is no languagename in it and we don't know how to add the language name in redirect="error/notfound" in the web.config file to create something like "en/error/notfound" or "fa/error/notfound".
every help would be highly appreciated
First of all, have a look at this answer for info about localizing your site via URL.
Next, <customErrors> is a catch-all for ASP.NET error messages. But in general, you have control over a 404 (routing miss) within ASP.NET MVC by using a catch-all route. In this case, you can simply localize the catch-all route and get rid of this configuration in web.config.
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Localized-Default",
url: "{lang}/{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
constraints: new { lang = new CultureConstraint(defaultCulture: "fa", pattern: "[a-z]{2}") }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { lang = "fa", controller = "Home", action = "Index", id = UrlParameter.Optional }
);
// Catch-all route (for routing misses)
routes.MapRoute(
name: "Localized-404",
url: "{lang}/{*url}",
defaults: new { controller = "Error", action = "PageNotFound" },
constraints: new { lang = new CultureConstraint(defaultCulture: "fa", pattern: "[a-z]{2}") }
);
routes.MapRoute(
name: "Default-404",
url: "{*url}",
defaults: new { lang = "fa", controller = "Error", action = "PageNotFound" }
);
}
}
ErrorController
public class ErrorController : Controller
{
public ActionResult PageNotFound()
{
Response.CacheControl = "no-cache";
Response.StatusCode = (int)HttpStatusCode.NotFound;
return View();
}
}
That takes care of the route misses within ASP.NET. For those that don't hit ASP.NET (assuming you are hosting using IIS), you should use the <httpErrors> section of web.config rather than <customErrors>. <httpErrors> is localizable via the prefixLanguageFilePath setting.
Optional string attribute.
Specifies the initial path segment when generating the path for a custom error. This segment appears before the language-specific portion of the custom error path. For example, in the path C:\Inetpub\Custerr\en-us\404.htm, C:\Inetpub\Custerr is the prefixLanguageFilePath.
<configuration>
<system.webServer>
<httpErrors errorMode="DetailedLocalOnly" defaultResponseMode="File" >
<remove statusCode="404" />
<error statusCode="404"
prefixLanguageFilePath="C:\Contoso\Content\errors"
path="404.htm" />
</httpErrors>
</system.webServer>
</configuration>
Which means you would need to set up a file structure with language prefix, and use static files as targets.
C:\Contoso\Content\errors\fa\404.htm
C:\Contoso\Content\errors\en\404.htm
AFAIK, this unfortunately means you need to have physical files at these locations. However, you could have the content of these pages setup to do both a meta-refresh redirect and a JavaScript redirect to the correct controller action.
<html>
<head>
<title>404 Not Found</title>
<meta http-equiv="refresh" content="1;http://www.example.com/fa/Error/PageNotFound" />
</head>
<body>
<!-- Add localized message (for those browsers that don't redirect). -->
<script>
//<!--
setTimeout(function () {
window.location = "http://www.example.com/fa/Error/PageNotFound";
}, 1000);
//-->
</script>
</body>
</html>
The customErrors section in web.config is the static data about some status-code and how they will be handled. The responsibility of this section can be generated dynamically by the Application_EndRequest method in Global.asax.
protected void Application_EndRequest()
{
if (Context.Response.StatusCode == 404)
{
Response.Clear();
var routeData = new RouteData();
HttpContextBase currentContext = new HttpContextWrapper(HttpContext.Current);
var lang = RouteTable.Routes.GetRouteData(currentContext).Values["lang"];
routeData.Values["lang"] = lang;
routeData.Values["controller"] = "CustomError";
routeData.Values["action"] = "NotFound";
IController customErrorController = new CustomErrorController();
customErrorController.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));
}
}
I believe you can use a session variable to hold current user's ui-culture data.
I don't see a point but, if you don't want to do that, you can follow this tutorial to generate your own routes for MVC custom error page handling.
http://setiabud.blogspot.com.tr/2013/04/handling-404-error-in-aspnet-mvc.html

Adding area to mvc project

I have an mvc project and I added a new area with the name BEK
and BEKAreaRegistration.cs was created.
public class BEKAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "BEK";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"BEK_default",
"BEK/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
}
}
and my global.asax file is as follows:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RouteTable.Routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
RouteTable.Routes.IgnoreRoute("{*allAspx}", new { allAspx = #".*\.aspx(/.*)?" });
RouteTable.Routes.IgnoreRoute("{*allAsmx}", new { allAsmx = #".*\.asmx(/.*)?" });
RouteTable.Routes.IgnoreRoute("{*allAshx}", new { allAshx = #".*\.ashx(/.*)?" });
RouteTable.Routes.IgnoreRoute("Services/{*pathInfo}");
RouteTable.Routes.IgnoreRoute("");
RouteTable.Routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
but when i try to go to BEK/Home/Index page I get an error page. What else should I do?
This is the error:
The resource cannot be found. Description: HTTP 404. The resource
you are looking for (or one of its dependencies) could have been
removed, had its name changed, or is temporarily unavailable. Please
review the following URL and make sure that it is spelled correctly.
Requested URL: /LMS_WEB_APP/BEK/Home
-------------------------------------------------------------------------------- Version Information: Microsoft .NET Framework Version:4.0.30319;
ASP.NET Version:4.0.30319.18213
When you add BEK Area.
MVC will create These for you.
Mvc will not create any Controller and Actions and Views.
So, you do have to do that manually that which controllers, actions and views you want to add.
So, now you do have to Add the Controller by Right Clicking on Controller and Add Controller.
After Adding the Controller.
You can do right click on the Action and Add View like this to add the View :
Ok....
So, you do have Both Controller and Action and Views required.
Now you might have to Resolve the Controller Duplicacy, if any, which i had told you earlier.
Happy Coading...
I think problem is that, You have Same Name controller in Both Area and and application. Like You have Home Controller in Normal Application and Also in AREA
And, it is causing the Duplicate Declaration of Same Controller.
The way doing that is, specifying the NAMESPACE of the Controller Like the Following :
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"BEK_default",
"BEK/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional },
new string[] { "MyAppName.Areas.BEK.Controllers" } // specify the new namespace
);
}
If not that Case, Please post the Error Message you are getting.

MVC Razor View not found if filename contains a dot

I have problems accessing a route, if it contains a dot. For reproducing, create a default MVC4 WebApi application. Take the default route...
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
write the controller as follows...
public class HomeController : Controller
{
public ActionResult Index(string id)
{
if (id == null)
{
return View();
}
else
{
return PartialView(id);
}
}
}
and create two files "test.cshtml" and "test.menu.cshtml" next to the existing "index.cshtml".
Opening /home/index/test works as expected. It brings back the contents of "test.cshtml".
However, opening /home/index/test.menu brings back a 404 error.
Why does this happen? And how can it be avoided?
The 404 error that you are seeing is from IIS. The module for MVC routing is never getting control.
Adding the following option to the modules section of the <system.webServer> section in web.config will make sure that the MVC routing gets attempted and should fix your problem:
runAllManagedModulesForAllRequests="true"
in my web.config there was no existing modules section so I added the following line to the <system.webServer> section:
<modules runAllManagedModulesForAllRequests="true" />
And now it works for me.

asp mvc using dashes in controller names and routing?

i have two questions. i'm fairly new to MVC and love the new way the controller and views are set up, but i can't figure out how to do the following:
1) make a url like www.homepage.com/coming-soon
for this type of url what is the right way to do it? do you create a controller named ComingSoonController and somehow magically insert a dash via routing? note i do NOT want underscores as that's not in the best interest of SEO. or is coming-soon some action name on some other controller that is not in the URL and use the [ActionName("name-with-dash")] attribute?
2) facebook, linkedin and twitter have urls like www.facebook.com/[profile name]. how would this be done in MVC? obviously the [profile name] is dynamic. and the code would obviously live in a controller called, say, profiles. so it seems to me that you would have to make MVC smart enough to know when that second part of the URL is a profile name and NOT a controller, and route it to the right action on the profiles controller? is this easier than it sounds?
1) It depends if coming-soon is dynamic part or not. I'll presume it is and would suggest something like this:
Global.asax
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute(
"Page", // Route name
"{pageName}", // URL with parameters
new { controller = "Home", action = "Page"} // Parameter defaults
);
}
public class HomeController : Controller
{
public ActionResult Page(string pageName)
{
return View();
}
}
2) You can resolve this same way as I've shown above, but keep in mind that order of routes is important. And that first one that matches wins. If you want two actions that have different logic but similar url structure www.mysite.com/coming-soon and www.mysite.com/{profile name}, presuming that first url has static part and the later dynamic you could do something like this:
Global.asax
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute(
"Coming-soon", // Route name
"coming-soon", // URL with parameters
new { controller = "Home", action = "ComingSoon" } // Parameter defaults
);
routes.MapRoute(
"Profiles", // Route name
"{profileName}", // URL with parameters
new { controller = "Home", action = "Profile"} // Parameter defaults
);
}
public class HomeController : Controller
{
public ActionResult ComingSoon()
{
return View();
}
public ActionResult Profile(string profileName)
{
return View();
}
}
You could create a custom route handler be allow hyphens in the urls:
Create a new handler
public class HyphenatedRouteHandler : MvcRouteHandler{
protected override IHttpHandler GetHttpHandler(RequestContext requestContext)
{
requestContext.RouteData.Values["controller"] = requestContext.RouteData.Values["controller"].ToString().Replace("-", "_");
requestContext.RouteData.Values["action"] = requestContext.RouteData.Values["action"].ToString().Replace("-", "_");
return base.GetHttpHandler(requestContext);
}
}
...and the new route:
routes.Add(
new Route("{controller}/{action}/{id}",
new RouteValueDictionary(
new { controller = "Default", action = "Index", id = "" }),
new HyphenatedRouteHandler())
);
MVC Hyphenated urls
I've developed an open source NuGet library for the first problem which implicitly converts EveryMvc/Url to every-mvc/url.
Dashed urls are much more SEO friendly and easier to read. (More on my blog post)
NuGet Package: https://www.nuget.org/packages/LowercaseDashedRoute/
To install it, simply open the NuGet window in the Visual Studio by right clicking the Project and selecting NuGet Package Manager, and on the "Online" tab type "Lowercase Dashed Route", and it should pop up.
Alternatively, you can run this code in the Package Manager Console:
Install-Package LowercaseDashedRoute
After that you should open App_Start/RouteConfig.cs and comment out existing route.MapRoute(...) call and add this instead:
routes.Add(new LowercaseDashedRoute("{controller}/{action}/{id}",
new RouteValueDictionary(
new { controller = "Home", action = "Index", id = UrlParameter.Optional }),
new DashedRouteHandler()
)
);
That's it. All the urls are lowercase, dashed, and converted implicitly without you doing anything more.
Open Source Project Url: https://github.com/AtaS/lowercase-dashed-route
When it comes to the second problem, you can do this either by making your own routes or handling not found with a custom error handling mechanism, but the routing will be faster if you restrict the profile urls to concur to some rules (like don't have any slashes) so that you can distinguish it from other urls much more easily, like from content file urls i.e. .css .js etc.

Resources