I want to know what is the best way to handle stuff like "help files" in mvc. I was thinking about this last night and I have a solution but is it a best practice (or good enough practice). Ignore html files.
routes.ignoreroute("{filename}.html");
Alternatively I was thinking that I could do a view with pages for help files.
Ie /Views/Shared/Help/helpfilename
I wanted to avoid the database solution but if that is best practise I am ok with that too.
Select html-content where helpcontentname=varible and helplanguage=variable
Static files are served automatically, there is no need to add any ignore routes. By default RouteCollection.RouteExistingFiles = false
Except:
true if ASP.NET routing handles all requests, even those that match an existing file; otherwise, false. The default value is false.
The wording is not the best, but basically what it means is; if the file exists and the value is false, IIS will serve the file directly, without starting up an HttpRequest in the ASP.Net pipeline. (The same reason you don't have to ignore Scripts, StyleSheets, or Images)
Related
I am developing a Clojure/ClojureScript SPA based on http-kit, compojure and tiny bits of hiccup on backend and mainly reagent on frontend. Project is done with leiningen, based on hand-wrecked chestnut template.
When I tried to make more complex URLs than just "/" the following setup created a mess for me:
When producing the initial hiccup to serve HTML and adding includes for CSS and JS files I followed the examples and added them as relative urls like
(include-css "css/style.css")
;and
(include-js "js/compiled/out/goog/base.js")
(include-js "js/compiled/myproject.js")
(note absence of slash in the beginning)
In the chestnut template I got default :asset-path option for cljsbuild set to "js/compiled/out"
Of course, when I tried to add a route to the same page with the http://my-domain/something URL in addition to root http://my-domain/ and load it, the thing failed to get any of my assets (trying to fetch them under e.g. /something/js/compiled/myproject.js).
I was able to fix this issue for explicitly included assets by making those urls relative to root (prepending a slash to each of them). It left me with the same problem with the script tag with src="js/compiled/out/cljs_deps.js" injected by cljsbuild, but this one I fixed by making :asset-path relative to root as well.
It all seems to work properly now, but the fact that I had to make some head-scratching and a surprisingly large amount of googling to finally resolve this makes me feel this is not the default approach. Hence the questions:
Did I do the right thing by converting all asset urls to relative-to-root ones? (Keeping in mind that I'm working on an SPA)
If yes, why isn't this a default approach and why I keep seeing relative-to-current location URLs everywhere (including all the examples on the web as well as lein templates)?
Update:
The relevant part of my app's compojure routes looks like this:
(defroutes home-routes
(resources "/")
(GET "/" _
(friend/authenticated
(html-response
(app-page))))
(GET "/something*" _
(friend/authenticated
(html-response
(app-page)))))
Is there a lint utility for ASP.NET MVC? Given that I frequently specify views and links via strings, when I move things around or change entity names I often break things, which I then only find out about when something fails at runtime.
ReSharper's v6 (whose nightlies are now available, if you don't mind living on the edge) will catch this kind of error for you.
You can use Refactor -> Rename and enable Search in Strings to replace every string in the solution
Other option -- use the strongly typed helpers (which might still be in the futures assemblies). EG, Html.Action<ProductsController>(x => x.ShowProduct(id)) ; really the only way to fly.
I don't know that there's something like that, but I'll tell you what I do: All my view names are in a struct that contains string constants. It's a pain to keep it sync'ed as the project changes, but it's worth it because you're far more likely to catch errors if you're using
ViewNames.Customer
rather than
"customer"
I have an actual folder with the same name as a controller. So the resulting link from this:
<li><%= Html.ActionLinkForAreas<BlaController>(c => c.Index(1), "BlaDiBla")%></li>
e.g.
www.bla.com/foldername (where foldername = controller name)
Stopped working.
I am wondering how I can avoid this behaviour as easy as possible (I need the folder with the same name though).
Thanks.
Best wishes,
Christian
IIS does not get priority, but the ASP.net routing engine in System.Web.Routing looks for physical files (or directories) before looking at the Routes you have defined.
You can switch this at a global level with the RouteCollection.RouteExistingFiles property, which will then give your route definitions priority over the file system. Make sure you test all your routes when you change this!
See also this question Considerations when turning on RouteExistingFiles.
I am trying to develop a grails application that has "root" content (www.mydomain.com/about for example) but will also support "projects" based upon the subdomain of the request; for example myproject.mydomain.com > www.mydomain.com/myproject. As a first pass, i have the URL configuration below:
"/$controller/$action?/$id?" {
...
}
"/$project/$controller/$action?/$id?" {
constraints {
}
}
The main drawback so far is that the $project variable must be injected manually into every link (tedious and not DRY):
<g:link controller="foo" action="bar" params="${[project: params.project]}">link</g:link>
Is there a way to automatically inject the $project parameter into all links if it is present, or is there a better way to approach this problem?
Basically you can create a grails plugin that will inject into the controller a new project param with a value based on a custom TagLib <g:project bean="myproject"/> (for instance)
It will force you to define this tagLib on each gsp page of your project but it is still DRYer than each link.
Hope it helps,
Fabien.
I can think of a couple of things.
a) You can place a proxy (Apache or something else) in front of your app-server and do some url-rewriting. Bonus: This would also allow you to do some caching of static resources.
b) This solution is a little more technically interesting. You can look up the project based on the http host header (the subdomain part). This will save you from rewriting all urls, all Grails conventions will still apply so you shouldn't run into any problems with third party plugins and so on.
What is the best way to support multiple languages for the interface in an ASP.NET MVC application? I've seen people use resource files for other applications. Is this still the best way?
If you're using the default view engines, then local resources work in the views. However, if you need to grab resource strings within a controller action, you can't get local resources, and have to use global resources.
This makes sense when you think about it because local resources are local to an aspx page and in the controller, you haven't even selected your view.
I found this resource to be very helpful
Its a wrapper round the HttpContext.Current.GetGlobalResourceString and HttpContext.Current.GetLocalResourceString that allows you to call the resources like this...
// default global resource
Html.Resource("GlobalResource, ResourceName")
// global resource with optional arguments for formatting
Html.Resource("GlobalResource, ResourceName", "foo", "bar")
// default local resource
Html.Resource("ResourceName")
// local resource with optional arguments for formatting
Html.Resource("ResourceName", "foo", "bar")
The only problem I found is that controllers don't have access to local resouce strings.
Yes resources are still the best way to support multiple languages in the .NET environment. Because they are easy to reference and even easier to add new languages.
Site.resx
Site.en.resx
Site.en-US.resx
Site.fr.resx
etc...
So you are right still use the resource files.
The Orchard project uses a shortcut method called "T" to do all in-page string translations. So you'll see tags with a #T("A String to Translate").
I intend to look at how this is implemented behind the scenes and potentially use it in future projects. The short name keeps the code cleaner since it will be used a lot.
What I like about this approach is the original string (english, in this case) is still easily visible in the code, and doesnt require a lookup in a resource tool or some other location to decode what the actual string should be here.
See http://orchardproject.net for more info.
Some of the other solutions mentioned as answer do not work for the released version of MVC (they worked with previous versions of alpha/beta).
Here is a good article describing a way to implement localization that will be strongly-typed and will not break the unit testing of controllers and views: localization guide for MVC v1
This is another option, and you'll have access to the CurrentUICulture in the controller:
Check MVC3-multi-language