Extending ASP.NET MVC 4 MvcHandler - asp.net

I'm trying to add some functionality to the default MvcHandler. What's happening is: I wanted to have dashed url's instead of Pascal Case url's. In other words if my controller is SomeController I wanted the URL to be /some-controller instead of /SomeController.
My best workaround was: I've created one mapping file URLMappings.xml which maps each controller to each desired URL. Then I've extended the default Route class to generate outgoing url's based on this and the default RouteHandler to understand the url's based on this. Well, this works fine because even if some mapping wasn't created then the framework will use the default behavior.
My point is: with this the routing system was understanding both kinds of Url's and this leads to duplicate content SEO problem. I wanted then to implement the following:
Get the controller value
See if on some mapping the controller name matches the value
If it matches, then there's some preferable URL than the one that was typed, should return 404.
I've searched on the web and the only way I've found to do this was to create a new IHttpHandler. However I don't want one from scratch, since I need all MVC functionality. I just want to put this logic on the ProcessRequest, however my overidden version of the method is not being executed.
Can someone give me some idea on how to deal with this ? Sorry if the question is silly or if it's not well detailed. If there's need for more information, just tell me.

You don't need a custom MvcHandler but a custom Route. There's a already NuGet package for this functionality called LowercaseRoutesMVC. Feel free to download it, explore the source code and adapt if necessary (to put the dash wherever you want to put it).

Related

Web API Help Samples - C#

ASP.NET Web API has an easy install Nuget help page with sample generator. It's easy to get it to generate and display sample requests, but not so easy it seems to get it to display sample responses (httpsampleresponses) so that when developers look at the help page they'd see examples of generated responses / not static/typed in responses, but actually generated. I've seen it done before on another project, but still having trouble figuring out how to do it. MSDN's YAO has a good blog but it's just not getting me all the way to success for some reason.
From what I've seen work live and based on what there is to read about it online, it's definitely in getting the HelpPageConfig file right in terms of the config.SetSampleResponses() set up. I've discovered the configuration file that sets the parameters for the SetSampleResponses() method, but still, nothing I try is working. It was suggested to me that I should create a custom type and use extension methods, but getting that to correspond and display what I need hasn't happened yet. I can get it to compile without errors, but it still doesn't show the generated response sample on the page. It was easy with the SetSampleForType piece to get a section to show up in the requests section, but it's the response part that has given me trouble.
Has anyone out there done this with the SetSampleResponses() successfully and is there any kind of trick you can clearly define for getting it to work? Do you have any tips on setting up a specific generic type and making that work?
I'm thinking this must be something really simple and I'm just not clicking to make it happen....
Thanks for any potential info...
SetSampleResponse extension on HelpPageConfig is for statically defining samples for you action.
config.SetSampleResponse("\"Hello World!\"", new MediaTypeHeaderValue("application/json"), "Values", "Get", "id");
if you are looking for generated sample for a particular type, have you tried using SetSampleObjects extension which allows you to set sample objects for different types and this same object is used in all cases where that particular type is returned from an action.
config.SetSampleObjects(new Dictionary<Type, object>
{
{typeof(string), "Hello World!"}
});
Could you share more specific(code) details as to how you are using SetSampleResponse extension?

Symfony2 - Do not render a view from controller like ZF setNoRender

Relatively new convert to Symfony2 from ZF1.
I have Googled and cannot seem to find the answer. Just wondering if there is a way to not render a view from a controller action in Symfony2.
In a ZF controller I could use:
$this->_helper->viewRenderer->setNoRender(true);
What is the equivalent in Symfony2?
In Symfony nothing is rendered for you automatically. If you need to render something, you have to do it explicitly. If you don't want to render, just don't do it :) Simply return a response:
return new Response();
Only job of a Symfony controller is to return a response. Rendering a template actually creates a response as well.
Wanted to give my Opinion:
Just because there is a possibility to render(ControllerMethod,{ params}) in a template doesn't mean you have to use it.
Doing so leads almost always to a shitty architecture, the turning point where projects start to be hard to debug, since you are mixing a VIEW (Presentation layer) with a CONTROLLER, that in turn renders another VIEW. You get the point.
Then when you have an error in the ControllerMethod, and instead you get a template error, not so nice isn't it ?
I vouch for strong architecture in software projects. This cheap solutions, like using this commodities, lead to the start of the bad. And I suggest to avoid it as much as you can unless there is no other possible way. And certainly there is!
That is the reason to use MVC. To separate Code from Presentation layer, start mixing both, and your architecture will leak.

Symfony some logic before controller

I'm a newbie to Symfony and I'm trying to switch my current project over to it.
For most of my controllers I need to do some multiple checks BEFORE executing the controller. Then if certain conditions are met for the check, forward them and show a different view, otherwise continue on to what they requested.
For example I have a group of controllers which should only be executed if the user is in a crew otherwise it loads a view saying "you're not in a crew".
This is very straight forward in procedural code, yet in OOP seems to get more complex, and now within a framework I seem to find myself even more limited.
How does one add logic before the controller is executed?
You want to set up before-filter logic. It's not something simple enough to write into a post here, but here's a good tutorial on doing so. If you have a specific issue with it, post here and I'll try to update with help: http://symfony.com/doc/2.0/cookbook/event_dispatcher/before_after_filters.html

Force case-sensitive routing in ASP.NET MVC

This question has been asked in a similar but not identical fashion (and not resolved to my satisfaction) previously on Stack Overflow and elsewhere.
Coming from a linux-world, I want to use ASP.NET MVC but avoid identical but differently-cased routes from resolving to the same page. I do not want to force all routes to be 100% lowercase.
e.g. I want /Home/Something to be a valid route and /Home/somethingElse to also be a valid route, but not /Home/something or /home/somethingelse, given two functions called Something and somethingElse in the HomeController.
I can't find any way of doing this from within the RegisterRoutes function, but maybe I'm missing something obvious? I can answer this easily enough by adding code to each Controller function, but I'm obviously trying to avoid doing that.
Optimally, the solution would involve catching all permutations of a particular route, then 301 redirecting any that do not exactly match the case of the controller's function.
I was unable to find any way of doing this after extensive searching. Basically, case-sensitivity and IIS/ASP.NET apparently do not go together.
We're now using a bit of a kludge to solve this. The code has been opensourced (MIT license) on github: NeoSmart Web Toolkit, in particular, this file containing the SEO redirect code.
Using it is easy enough: each GET method in the controller classes needs to add just this one line at the start:
Seo.SeoRedirect(this);
The SEO rewrite class automatically uses C# 5.0's Caller Info attributes to do the heavy lifting, making the code above strictly copy-and-paste.
Ideally, I would love to find a way to turn that line of code into an attribute. For instance, prefixing the controller methods with [CaseSensitive] would automatically have the same effect as writing in that line, but alas, I do not (yet) know how to do this.
I also can't find any way of figuring this out with the Routing class/structures. That's some opaque code!

How does asp.net mvc figure it out?

How is it that I can create a method in the controller and just put some arguments and it figures it out after I click on a form submit? Under the hood, how does it find the right method and how does it figure out that I just want those arguments?
In a nutshell:
The routing engine handles the HttpRequest, and checks the requested URL. When it finds the first route match, it creates a new instance of MvcRouteHandler and passes it the broken-up tokens of the URL in a RouteValueDictionary.
The route's MvcRouteHandler takes the request, and tries to instantiate a controller class instance. By convention, it looks for a class called "XXXXXXController", where the X's are replaced by the {controller} parameter in the route.
Once it finds the controller, it invokes the appropriate method on it, given by the {action} parameter of the route. Any named arguments, such as {id}, that exist in the route, are passed as parameters to the method.
Basically, everything that ASP.Net MVC "knows" comes from the route information. It can't divine the parameters from thin air - they have to come from the route parsing. If the information isn't present in the requested URL, it can't be passed into the method.
It should also be noted that you can override the behaviour of the framework by making your routes use alternate handlers instead of MvcRouteHandler. The framework is quite extensible, so you can plug in custom functionality at many points.
There's quite a bit of code in play for controller, action and view resolution, as well as the ModelBinders. So much that it'd probably be best for you to look into specific portions of the framework and ask a more detailed question to get much of an answer.
Luckily, the ASP.NET MVC framework has been open-sourced, so if you're curious as to how it all works, you can get the code and look through it yourself. Its excellent code to read through and you're sure to learn something.
More to the point of your question, however, you should look at the System.Web.Mvc.MvcHandler and System.Web.Mvc.ControllerActionInvoker classes, which should lead you down the right path for answering your questions.

Resources