Building URLs in for MVC apps *and* supporting apps - asp.net-mvc-3

MVC has great tools for building urls inside an MVC app by using routing. Routing by controller and action lets us avoid hard coding urls in markup.
But we have a bunch of ancillary services that need to create urls for marketing emails.
For instance, our email marketing campaigns may need to build a url for an offer. The MVC app knows how to build the url to the offer detail, but is there a clever way of doing this for the service app? Can we/should we move routing into a separate dll and reference it from one place?
Success stories/horror stories are appreciated.

it sounds like you should be using a catchall url to lookup actions you can manage in a DB such as:
Route like this
routes.MapRoute(
"MailCampaigns",
"/mailcampaigns/{*url}",
new {controller = "MailCampaigns", action = "Incoming" }
);
public ActionResult Incoming(string url)
{
//parse the url and perform actions accordingly
var actionInfo = repository.Query<ActionInfo>().Where(x => x.Url == url).SingleOrDefault();
return Redirect(actionInfo.TargetUrl);
}

Related

MVC RedirectToRoute in Global asax not working on hybrid site

I recently rebuilt our webforms site as a hybrid mvc3/webforms website, with the newer code being replace with mvc. In the past, there was some code in the Application_Error method of the global asax file redirecting users to a 404
LifespeakExceptions.Log404();
HttpContext.Current.Server.Transfer("~/404.aspx");
However, when I tried to replace this with a route, it couldn't seem to find it - for example I tried this in the registermvc3routes file
routes.MapRoute(
"404", // Route name
"pagenotfound",
new { controller = "Utilities", action = "Error404Page" }
);
and I added this in global asax
LifespeakExceptions.Log404();
Response.RedirectToRoute("404");
However, it can't seem to find this route, even though I know it exists -- calling it directly correctly works. Could this be because it's a hybrid site?

Web API get route values

Is there any way to statically get route values from a service method (outside of a controller) that is running in a Web API context? For example, I can do the following in ASP.NET MVC:
var mvcHandler = HttpContext.Current.Handler as MvcHandler;
var routeValues = mvcHandler.RequestContext.RouteData.Values;
I'd like to find the equivalent version of this code for Web API.
When I try to debug a sample Web API request and look at HttpContext.Current.Handler it is of type HttpControllerHandler, but this type doesn't have any properties to access route data.
EDIT
To try to help provide some more information. The code I am trying to read the value from is inside of a factory class I have that builds a custom object for my application.
You can use GetRouteData() extension on HttpRequestMessage. You would need to include System.Net.Http namespace to get this.
System.Web.Http.Routing.IHttpRouteData routeData = Request.GetRouteData();
I was able to find a solution that would get the route values for either an MVC request or a Web API request.
HttpContext.Current.Request.RequestContext.RouteData

Centralized Authorization of Controllers and Actions (ASP.NET MVC 3)

Are there any possible security issues or pitfalls to, within a custom AuthorizeAttibute (registered globally), apply authorization based on the controller type and action being called?
e.g. (not real code)
string controllerFullName=_filterContext.ActionDescriptor.ControllerDescriptor.ControllerType.FullName;
string minRequiredRole = GetControllerMinRequiredRole(controllerFullName);
if(User.MeetsRoleRequirement(minRequiredRole))
{
//give access
}
else
{
//no you're not allowed
}
The main issue is with Authorization caching - so there are a few things to know. Check out the links I've posted here:
Creating a AuthorizeAttribute - what do I need to know?
Look at the code to the existing attribute and how it handles caching to ensure you arent causing the same issue the base attribute prevents.

Best way to deal with renaming a controller

Working with ASP.NET MVC3, site is in beta and customer decided to rename one of the controllers.
http://domain.com/foo[/*] -> http://domain.com/bar[/*]
What is the most straightforward way to handle redirecting so I don't break any foo bookmarks?
Keep the old controller around so the old URLs still work.
Or add a rewrite rule. Something like:
domain.com/foo(/[_0-9a-z-]+)
to:
domain.com/bar{R:1}
URL Rewrite in IIS
http://technet.microsoft.com/en-us/library/ee215194(WS.10).aspx
http://www.iis.net/download/URLRewrite
If you are using MVC.NET you probably already have URL Rewrite installed.
Another option would be to register a specific route for the old controller name in the Global.asax.cs.
routes.MapRoute(
"RenamedController", // Route name
"[OldControllerName]/{action}/{id}", // URL with parameters
new { controller = "[NewControllerName]", action = "Index", id = "" } // Parameter defaults
);
Add that before the standard default route, and your new controller should respond to both old and new names.
A 302 redirect would be fine, if you can figure out how to do that in IIS. This screenshot suggests it's not that arduous. Alternately, if you're using Castle Windsor you may want to register an interceptor that uses HttpResponse.Redirect()
REST standard suggests the best way to handle this issue is by returning a 301(Moved permanently request). Stack Overflow Post REST Standard
In .Net I recommend using Controller.RedirectToActionPermanent in your controller. See: ASP.NET, .NET Core
Code Example(should work for both ASP and Core):
public class MyController : ControllerBase
{
public IActionResult MyEndpoint(string routeValues1, string routeValues2)
{
return RedirectToActionPermanent("action", "controller", new { value1 = routeValues1, value2 = routeValues2 });
}
}
using MapRoute doesn't make sense in this case. MapRoute is really meant to provide a custom routing solution throughout the system. Its not really meant to deal with individual Redirects. As far as I'm aware it doesn't actually inform the user they are being redirected. See: Creating Custom Routes (C#)

Introducing MVC into ASP.Net - 404 error

I have an existing ASP.Net Application, into which I am attempting to introduce MVC2.
Hopefully I can remember the steps, but what I did was the following:
Created a dummy MVC2 project.
Compared and merged .csproj, resulting in the Add Item commands showing MVC2 items.
Compared and merged the web.config
Compared and merged the global.asax.cs
Added Models, Views and Controllers directories
Added HostController with Index action and Index.aspx (no logic)
Amended route to make /Host/Index the default
So now, when I access the application via the root address http://localhost/MyApp it all works.
But, when I access http://localhost/MyApp/Host/Index I get a 404 error. I get the same result for any of the Controller/Actions I created. The only way I can get them to appear is to use the defaults in the routing configuration. I installed Phill Haack's route debugger and it's doing nothing. Obviously there's some problem with my routing, but I can't figure it out.
Any ideas what I've missed?
Bah... turns out that this is to do with IIS 5.1 and MVC routing.
I resolved it by using the following Routes in my application (note the .aspx extensions).
routes.MapRoute("Root", "", new { controller = "Host", action = "Index" });
routes.MapRoute("Default", "{controller}/{action}.aspx", new { controller = "Host", action = "Index" });
Means I can't have clean routes, but at least it works.

Resources