ASP.net MVC Routing resources - asp.net

I just cant get this to work...
I have the following routes:
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.IgnoreRoute("*.html|js|css|gif|jpg|jpeg|png|swf");
routes.IgnoreRoute("{*favicon}", new { favicon = #"(.*/)?favicon.ico(/.*)?" });
routes.MapRoute(
"Default", // Route name
"{lama}/{controller}/{action}", // URL with parameters
new { controller = "Home", action = "Index", lama = "en-gb" } // Parameter defaults
);
And once I load the page.. I have a img element that tries to retrive the following url:
css/img/backgrounds/slide1_2048x1280.jpg
But the image wont show up and if I check my console I get the following error:
GET {my localhost}/cn/Home/css/img/backgrounds/slide1_2048x1280.jpg 404 (Not Found)
I have such a hard time understanding the route-system.. is there anywhere I can read ALOT more about this?.. And could somebody please help me with this single problem then that whould be very appreciated!

I think have fallen foul of relative urls in your html.
Since you haven't said whether this is Razor or Aspx; I'm just going to go with Aspx.
When you write the img tag it seems that you might be doing:
<img src="[relative_path_to_file]" />, using the path of the img relative to the page.
If that doesn't start with / then it's almost certainly the case that you will end up with issues, especially since MVC URLs don't map to the path of the actual page.
What you want to do is to use Url.Content("~/[full_path_to_file]") which will ensure that an absolute path will always be used.
On another note - you really do not need to write all these ignore routes for files that exist on disk. By default, the routing engine will not route existing files - you have to set routes.RouteExistingFiles = true in the RegisterRoutes method in your global in order to route files that already exist; so I think you should get rid of them.

i usually hit up 1) stackoverflow (obviously!), and 2) the msdn docs are pretty good:
http://msdn.microsoft.com/en-us/library/dd410120.aspx. But i usually end up googling for specifically what i need =)
However, looks like you're trying to setup a route to ignore certain filetypes?
i found this article that gives some good ideas on how to handle this.
I've only blocked one or two filetypes before, and i made one line per filetype. Not sure if you can make one line that has extensions delimited by pipe (|) like you're doing (i could be wrong!)
routes.IgnoreRoute("{*allaspx}", new {allaspx=#".*\.aspx(/.*)?"});
routes.IgnoreRoute("{*allswf}", new {allswf=#".*\.swf(/.*)?"});

Related

CQ5 SlingServlet and resourceTypes not working for specific resource paths

If I define a Sling Servlet as follows:
#SlingServlet(
label="TestResourceTypeServlet",
name = "com.company.project.servlets.TestResourceType",
extensions = {"bob"},
resourceTypes= {"cq:Page"},
methods= {"GET"},
metatype=true)
#Properties({
#Property(name = "service.description", value = "A test servlet"),
#Property(name = "service.vendor", value = "Company")
})
The servlet picks up any get request to every page with an extension of '.bob', which is fine but what I really want is to handle a request to a specific page type,
SO
I modify resourceTypes to read
resourceTypes= {"site-administration/components/page/page-distribution"},
the supplied value is the specific sling:resourceType (copied and pasted out of CRXDE Lite) of a page I am trying to access with the .bob extension, but I get a 404!!!
All the documentation I've read says the above should work, but it does not.
Out of desperation I've even tried "site-administration/components/page" which is the super type of the page I want.
I'm running a clean 5.6.1 instance with this servlet as part of an OSGi bundle.
Am I missing something obvious here, or if not is anyone aware of any hot fixes that could resolve this issue ?
Any help would be appreciated as I'm starting to go slightly mad in the head.
EDIT
Ok, so I've gotten a little further: If I access the page with:
[path-to-page]/page.bob.html
The servlet fires. But in this URL is bob not a selector? and if so why when the resource type is cq:Page does the configuration work with bob as an extension?
Very confused :-S
I'm obviously missing something very simple here.
The problem with pages is that the resourceType is stored on the jcr:content node below the cq:Page node. If you would call [path-to-page]/_jcr_content.bob it should work. Note: _jcr_content is an url save version of jcr:content.
Why your last example is actually working, I cannot tell.

Meteor how to save templates in mongo

I want to give my users the possibility to create document templates (contracts, emails, etc.)
The best option I figured out would be to store these document templates in mongo (maybe I'm wrong...)
I've been searching for a couple of hours now but I can't figure out how to render these document template with their data context.
Example:
Template stored in Mongo: "Dear {{firstname}}"
data context: {firstname: "Tom"}
On Tom's website, He should read: "Dear Tom"
How can I do this?
EDIT
After some researches, I discovered a package called spacebars-compiler that brings the option to compile to the client:
meteor add spacebars-compiler
I then tried something like this:
Template.doctypesList.rendered = ->
content = "<div>" + this.data.content + "</div>"
template = Spacebars.compile content
rendered = UI.dynamic(template,{name:"nicolas"})
UI.insert(rendered, $(this).closest(".widget-body"))
but it doesn't work.
the template gets compiled but then, I don't know how to interpret it with its data context and to send it back to the web page.
EDIT 2
I'm getting closer thanks to Tom.
This is what I did:
Template.doctypesList.rendered = ->
content = this.data.content
console.log content
templateName = "template_#{this.data._id}"
Template.__define__(templateName, () -> content)
rendered = UI.renderWithData(eval("Template.#{templateName}"),{name:"nicolas"})
UI.insert(rendered, $("#content_" + this.data._id).get(0))
This works excepted the fact that the name is not injected into the template. UI.renderWithData renders the template but without the data context...
The thing your are missing is the call to (undocumented!) Template.__define__ which requires the template name (pick something unique and clever) as the first argument and the render function which you get from your space bars compiler. When it is done you can use {{> UI.dynamic}} as #Slava suggested.
There is also another way to do it, by using UI.Component API, but I guess it's pretty unstable at the moment, so maybe I will skip this, at least for now.
Use UI.dynamic: https://www.discovermeteor.com/blog/blaze-dynamic-template-includes/
It is fairly new and didn't make its way to docs for some reason.
There are few ways to achieve what you want, but I would do it like this:
You're probably already using underscore.js, if not Meteor has core package for it.
You could use underscore templates (http://underscorejs.org/#template) like this:
var templateString = 'Dear <%= firstname %>'
and later compile it using
_.template(templateString, {firstname: "Tom"})
to get Dear Tom.
Of course you can store templateString in MongoDB in the meantime.
You can set delimiters to whatever you want, <%= %> is just the default.
Compiled template is essentially htmljs notation Meteor uses (or so I suppose) and it uses Template.template_name.lookup to render correct data. Check in console if Template.template_name.lookup("data_helper")() returns the correct data.
I recently had to solve this exact (or similar) problem of compiling templates client side. You need to make sure the order of things is like this:
Compiled template is present on client
Template data is present (verify with Template.template_name.lookup("data_name")() )
Render the template on page now
To compile the template, as #apendua have suggested, use (this is how I use it and it works for me)
Template.__define__(name, eval(Spacebars.compile(
newHtml, {
isTemplate: true,
sourceName: 'Template "' + name + '"'
}
)));
After this you need to make sure the data you want to render in template is available before you actually render the template on page. This is what I use for rendering template on page:
UI.DomRange.insert(UI.render(Template.template_name).dom, document.body);
Although my use case for rendering templates client side is somewhat different (my task was to live update the changed template overriding meteor's hot code push), but this worked best among different methods of rendering the template.
You can check my very early stage package which does this here: https://github.com/channikhabra/meteor-live-update/blob/master/js/live-update.js
I am fairly new to real-world programming so my code might be ugly, but may be it'll give you some pointers to solve your problem. (If you find me doing something stupid in there, or see something which is better done some other way, please feel free to drop a comment. That's the only way I get feedback for improvement as I am new and essentially code alone sitting in my dark corner).

Page.RouteData.Values are empty for one page but not another

I have Routing working in ASP.NET c# WebForms using Microsoft.AspNet.FriendlyUrls but not for all pages.
Here is an example:
routes.MapPageRoute("List/{Location}/{ZipCode}/", "List/{Location}/{ZipCode}/", "~/List.aspx");
On the above mentioned page (List.aspx) in the page_load there are no values.count in the Page.RouteData.
Page.RouteData.Values.Count == 0
I have another page in the same site with this info matched to it:
routes.MapPageRoute("{Location}/{ZipCode}/{Name}/{LocID}/{ID}/{Code}/", "{Location}/{ZipCode}/{Name}/{LocID}/{ID}/{Code}/", "~/place.aspx");
This page (place.aspx) always shows the correct count of Routes.
While on the List page in debug mode I checked the querystring and location and the ZipCode were there.
So, what might cause Page.RouteData to not show in one page but be available in another?
I am pretty new to url routing, but I think I ran into a similar problem and also found the solution. Have you tried:
routes.MapPageRoute("ListDetails/{Location}/{ZipCode}/", "ListDetails/{Location}/{ZipCode}/", "~/List.aspx");
instead of
routes.MapPageRoute("List/{Location}/{ZipCode}/", "List/{Location}/{ZipCode}/", "~/List.aspx");
?
In my case I had:
routes.MapPageRoute(
"ImageDelete",
"Admin/Images/Delete/{nameToKill}",
"~/Admin/Images.aspx"
);
which showed Page.RouteData.Values always empty.
When I changed it to
routes.MapPageRoute(
"ImageDelete",
"Admin/Image/Delete/{nameToKill}", // mind the missing 's'
"~/Admin/Images.aspx"
);
it worked!
I think the route may not start with the URL of a site that actually exists.

Route images in View folder in Asp.Net MVC 3

I tried asking this question a bit differently before, but it wasn't understood, so I'll try another way:
I have an MVC 3 application where I have views in the Views directory as usual. However, for various reasons I need the images for each view to be in the same folder as the view itself, i.e. in my case e.g. Views/Manuals/en-US/name
Here's the route I use:
routes.MapRoute(
"Parameter",
"{controller}/{action}/{lang}/{prod}",
new { controller = "Manuals", action = "Product", lang = "en-US", prod = "name" }
);
Now, as mentioned, I need the images for this view to be in the same folder, so that the image path can simply be "ATEXSymbol.svg".
When I just have this route, and use a simple relative path like this for the image, what I get is an error like this:
The view 'da-DK/ATEXSymbol.svg' or its master was not found or
no view engine supports the searched locations. The following
locations were searched: ~/Views/Manuals/da-DK/ATEXSymbol.svg.aspx
~/Views/Manuals/da-DK/ATEXSymbol.svg.ascx
~/Views/Shared/da-DK/ATEXSymbol.svg.aspx
~/Views/Shared/da-DK/ATEXSymbol.svg.ascx
~/Views/Manuals/da-DK/ATEXSymbol.svg.cshtml
~/Views/Manuals/da-DK/ATEXSymbol.svg.vbhtml
~/Views/Shared/da-DK/ATEXSymbol.svg.cshtml
~/Views/Shared/da-DK/ATEXSymbol.svg.vbhtml
So basically, it's looking for the image in the correct language folder, but without the product name folder part, and with one of a number of view extensions appended. I know MVC doesn't really expect this relative path in the same folder, but I pretty much don't have any choice. I'm required to put images in the same folder for purposes out of my hands.
So how can I achieve this?
EDIT:
Actually, I was mistaken a bit above, saying that the product name part of the path was missing, of course it isn't. That part of the path is the name of the view itself. So basically the path I get by a simple relative path (just the name of the image file) in the src attribute creates the correct path for the image. The only problem is that the view file extension is added...
Anyone know how to solve this?
EDIT 2:
BTW, I could have used Url.Content, but for some reason that doesn't work either. If I use this:
<embed type="image/svg+xml" src="#Url.Content("~/Content/images/da-DK/3153/CheckRotation.svg")"></embed>
...it works...but if I use this (same thing but with the image in the Views folder)...
<embed type="image/svg+xml" src="#Url.Content("~/Views/Manuals/da-DK/CheckRotation.svg")"></embed>
...it doesn't work. If I inspect the path in the latter example in the web inspector, it looks like the correct path (localhost:49864/Views/Manuals/da-DK/CheckRotation.svg) but with the message that it cannot be found.
EDIT 3:
The answer by Thinking Sites gave me a solution, I just had to modify it a bit, since I needed the route suggested for the views themselves. So I added this route:
routes.MapRoute(
"Image",
"{controller}/{action}/{lang}/{prod}",
new { controller = "Manuals", action = "Image", lang = "en-US", prod = "name" }
);
I made a slight adjustment in the path (as suggested), since the prod now actually carries the entire filename, including extension:
public ActionResult Image(string lang, string prod)
{
var root = Server.MapPath("~/Views/Manuals/");
var filepath = Path.Combine(root, lang, prod); // whatever creates your path here.
return File(filepath, "image/svg+xml");
}
And then in the view I can have paths like this:
<embed type="image/svg+xml" src="#Url.Content("/Manuals/Image/da-DK/CheckRotation.svg")"></embed>
Using this route:
routes.MapRoute(
"Parameter",
"{controller}/{action}/{lang}/{prod}",
new { controller = "Manuals", action = "Product", lang = "en-US", prod = "name" }
);
Create this action in your controller ManualsController
public ActionResult Product(string lang,string prod){
var root = Server.MapPath("~/views/manuals/");
var filepath = Path.Combine(root,lang,prod,".svg"); // whatever creates your path here.
return File(filepath ,"your mime type");
}
No need for a custom view engine. The FileResult is designed for just this occasion.
Maybe the answer to your question is in your error:
The view 'da-DK/ATEXSymbol.svg' or its master was not found or no view engine supports the searched locations.
Have you thought about plugging in a custom view engine?
I have never created one myself & can't offer guidance, so this is an incomplete answer (I can delete later depending on comments). It's an interesting problem though, and so far as I can tell a unique one. I wonder who would dictate that items be "dumped in en masse" for a framework that doesn't work that way by convention. Pretty straightforward if you were working with web forms though.

Webservlet urlpatterns for index.jsp

I'm stuck with this problem and I can't find a solution for it anywhere, so any ideas are welcome.
I want to execute some code on a #WebServlet (javax.servlet.annotation.WebServlet) before it loads my index.jsp. For that I added "/" to the urlPatterns. This does what it's expected in the index.jsp, but it doesn't load my css or image paths any more. The problem is the "/" makes it include all other files in these urlPatterns, but if I try to use "index" instead, it doesn't work.
Can someone please help?
Cheers,
M.
Just use an url-pattern which exactly matches /index.jsp.
#WebServlet(urlPatterns = { "/index.jsp" })
Unrelated to the concrete question, I wonder if you can't better use a ServletContextListener (which is annotable using #WebListener). This is certainly true when your sole functional requirement is to preload/preinitialize some application-wide data on server's startup, regardless of the first-opened webpage.

Resources