Can I generate ASP.NET MVC routes from a Sitemap? - asp.net

I'm thinking of learning the ASP.NET MVC framework for an upcoming project. Can I use the advanced routing to create long URLs based on the sitemap hierarchy?
Example navigation path:
Home > Shop > Products > Household > Kitchen > Cookware > Cooksets > Nonstick
Typical (I think) MVC URL:
http://example.com/products/category/NonstickCooksets
Desired URL:
http://example.com/shop/products/household/kitchen/cookware/cooksets/nonstick
Can I do this?

Zack, if I understand right you want unlimited depth of the subcategories. No biggie, since MVC Preview 3 (I think 3 or 4) this has been solved.
Just define a route like
"{controller}/{action}/{*categoryPath}"
for an url such as :
http://example.com/shop/products/household/kitchen/cookware/cooksets/nonstick
you should have a ShopController with a Products action :
public class ShopController : Controller
{
...
public ActionResult Products(string categoryPath)
{
// the categoryPath value would be
// "household/kitchen/cookware/cooksets/nonstick". Process it (for ex. split it)
// and then decide what you do..
return View();
}

The MVC routing lets you define pretty much any structure you want, you just need to define what each of the pieces mean semantically. You can have bits that are "hard-coded", like "shop/products", and then define the rest as variable, "{category}/{subcategory}/{speciality}", etc.
You can also define several routes that all map to the same end point if you like. Basically, when a URL comes into your MVC app, it goes through the routing table until it finds a pattern that matches, fills in the variables and passes the request off to the appropriate controller for processing.
While the default route is a simple Controller, Action, Id kind of setup, that's certainly not the extent of what you can do.

Related

NextJS specific dynamic routes

I'm building a small application and want to build a simple routing system but I got into a small issue.
I have my category page which is dynamic, and a single post which will be category/post-name now I want that my category page to be only accessible when the user goes to website.com/category1/ or website.com/category2/ or website.com/category3/ but not on other dynamic routes.
Is there a way to do it?
Predefined routes take precedence over dynamic routes, and dynamic routes over catch all routes. For example:
pages/category/category1.js - Will match /category/category1
pages/category/caregory2.js - Will match /category/category2
pages/category/category3.js - Will match /category/category3
pages/category/[category_id].js - Will match /category/category4, /category/category5, etc. But not /category/category1, /category/category2, /category/category3.

How many controller files should I create in my Symfony2 application?

In the src/AppBundle/Controller folder, there is a file called DefaultController.php.
I'll create url's like below, should I use just DefaultController.php for all URL requests or is it recommended to use a different controller.php file (UserController.php, FeedController.php, etc) for each part of the site? (profile, feed, settings, etc)
I also have another question. As far as I understand, we put our html files in our /App/Resources/views folder to keep them separated. Do I need to create a specific file for each part of the website just like flat PHP? (settings/index.php, settings/password.php, settings/things.php, settings/security.php, etc).
I am not sure whether this question is suitable for SO or not.
settings
/settings
/settings/password
/settings/things
/settings/security
/settings/privacy
/settings/ban
/settings/notifications
/settings/mail
/settings/mobile
/settings/applications
/settings/advertising
/settings/invite
user
/username
/username/photos
/username/friends
/username/posts
feed
/feed
/feed/posts/postid
For both questions is no hard answer. I should create a controller for each part of your website AT LEAST. Theoretical you could throw everything into one controller but it will be a very long list if you are finished. Another problem is that your action names like indexAction will repeat which is of course not possible because every method must have a different name. And names like index1Action, index2Action and so on is also not a proper solution :-). Another helper is to create an own controller for every ENTITY.
Twig files should only be written for one page only or only for a part of a page. Imagine that you have a homepage with last 10 newsitems but also a news page with more news items (maybe with pagination). The newsitems themselves looks the same on both pages. In this case you could make a home.html.twig, a news.html.twig and also a newsitem.html.twig. Both home and news will include newsitem to show the newsitems...
Hope i gave you a light.

Play Framework - how do I redirect to a page generated by a plugin controller? [SecureSocial]

I have this in my routes.conf file:
# SecureSocial routes
# Login page
GET /login securesocial.controllers.LoginPage.login
And then I have this in a Scala Controller file
val index = SecuredAction { implicit request =>
Redirect(routes.UserOps.watchlist)
// how do I go straight to /login? >|
}
Doing this takes me to a login page that has a red error bar saying "you must be signed in to view this page". If I access `localhost:9000/login' I get the login page without the error bar.
Normally I do a Redirect(routes.SomeControllerObject.ActionMethodName) but in this case the controller I need to access is in a plugin...
I feel like I'm missing something rather large here...
Update:
To reverse-route to an action in a plugin controller you need to provide the correct, full path to the plugin's routes class.
Redirect(securesocial.controllers.routes.LoginPage.login)
Original Answer
For reverse-routing I don't think it matters where the Controller is since Play is building that when the project compiles. From the documentation:
For each controller used in the routes file, the router will generate a ‘reverse controller’ in the routes package, having the same action methods, with the same signature, but returning a play.api.mvc.Call instead of a play.api.mvc.Action.
So this should work just as if LoginPage was a controller directly in your app.
Redirect(routes.LoginPage.login);
In order to show the message, you must have an item in the Flash. When you hit /login directly, there is no flash, so you won't see that message.
If you want to see that message:
Redirect(securesocial.controllers.LoginPage.login).flashing( ... )

SEO layout of the website

I am making one website about books and the user reaches the book which he/she intends by traversing though the subjects, then categories and then the subcategories.
As usual, I have made pages that use query strings like this
www.mywebsite.com/subjects.aspx?subjectid=10
The subjectid refers to one of the subjects.
The the user selected the categories and then subcategories and reaches the book.Now, everything is referred by it's id and not by it's name.
Now my question is that the Search Engines dont know how many subjeccts are there and the subject names are not understandable from the id(s).
When I tried to use Google Custom Search, and passed on the url of my website it does not go deep to the book level, instead stays on the main url www.mywebsite.com.
There are some website that I have seen have URL like this:
http://dotnetslackers.com/articles/aspnet/Implementing-Search-in-ASP-NET-with-Google-Custom-Search.aspx
Do they really create a seperate aspx page for each and every article ?
I maynot be able to make you people understand what I want coz I just started asp.net so please think that it has got to do with SEO.
If any clarification is need, please comment and will edit the question.
EDIT 1: Just when I posted this question I noted that it has also created a similar type of page:
http://stackoverflow.com/questions/5581873/seo-layout-of-the-website
Now, Is that a new folder "seo-layout-of-the-website" !
EDIT:2 SO it appears that URL Rewriting is what I need. The example given in one tutorial states that for urls like :
http://www.store.com/products.aspx?category=books
http://www.store.com/products.aspx?category=DVDs
http://www.store.com/products.aspx?category=CDs
I can redirect them to
http://www.store.com/products.aspx/Books
http://www.store.com/products.aspx/DVDs
http://www.store.com/products.aspx/CDs
But in my case, I am using Ids, so does that mean that I should use the names (subject.aspx?subjectname=abcd instead of subject.aspx?subjectid=123) ?
URL Rewriting is what you're looking for. So you could convert your URL:
www.mywebsite.com/subjects.aspx?subjectid=10
to:
www.mywebsite.com/subject/10
by adding a route to it. If you're using ASP.NET 4, you can do this easily. In your Global.asax.cs file, define the following in the Application_Start function:
using System.Web.Routing;
protected void Application_Start(object sender, EventArgs e)
{
RouteTable.Routes.MapPageRoute(
"SubjectRoute",
"subject/{subjectId}",
"~/subjects.aspx"
);
}
And in subjects.aspx.cs, get the value with:
if (Page.RouteData.Values["subjectId"] != null)
{
var mySubjectId = Page.RouteData.Values["subjectId"].ToString());
}
No, they don't create new pages for SEO purpose. what most of us do is rewrite the URL rule in htaccess or apache files. I dont know how it works in asp though

.NET frameworks for formatting e-mail messages?

Are there any open source/free frameworks available that take some of the pain out of building HTML e-mails in C#?
I maintain a number of standalone ASP.NET web forms whose main function is to send an e-mail. Most of these are in plain text format right now, because doing a nice HTML presentation is just too tedious.
I'd also be interested in other approaches to tackling this same problem.
EDIT: To be clear, I'm interested in taking plain text form input (name, address, phone number) and dropping it into an HTML e-mail template. That way the receipient would see a nicely formatted message instead of the primitive text output we're currently giving them.
EDIT 2: As I'm thinking more about this and about the answers the question has generated so far, I'm getting a clearer picture of what I'm looking for. Ideally I'd like a new class that would allow me to go:
HtmlMessage body = new HtmlMessage();
body.Header(imageLink);
body.Title("Some Text That Will Display as a Header");
body.Rows.Add("First Name", FirstName.Text);
The HtmlMessage class builds out a table, drops the images in place and adds new rows for each field that I add. It doesn't seem like it would be that hard to write, so if there's nothing out there, maybe I'll go that route
Andrew Davey created Postal which lets you do templated emails using any of the ASP.NET MVC view engines. Here's a video where he talks about how to use it.
His examples:
public class HomeController : Controller {
public ActionResult Index() {
dynamic email = new Email("Example");
email.To = "webninja#example.com";
email.FunnyLink = DB.GetRandomLolcatLink();
email.Send();
return View();
}
}
And the template using Razor:
To: #ViewBag.To From: lolcats#website.com Subject: Important Message
Hello, You wanted important web links right? Check out this:
#ViewBag.FunnyLink
<3
The C# port of StringTemplate worked well for me. I highly recommend it. The template file can have a number of named tokens like this:
...
<b>
Your information to login is as follows:<br />
Username: $username$<br />
Password: $password$<br />
</b>
...
...and you can load this template and populate it like this:
notificationTemplate.SetAttribute("username", Username);
notificationTemplate.SetAttribute("password", Password);
At the end, you get the ToString() of the template and assign it to the MailMessage.Body property.
I recently implemented what you're describing using MarkDownSharp. It was pretty much painless.
It's the same framework (minus a few tweaks) that StackOverflow uses to take plain-text-formatted posts and make them look like nice HTML.
Another option would be to use something like TinyMCE to give your users a WYWIWYG HTML editor. This would give them more power over the look and feel of their emails, but it might just overcomplicate things.
Bear in mind that there are also some security issues with user-generated HTML. Regardless of which strategy you use, you need to make sure you sanitize the user's input so they can't include scary things like script tags in their input.
Edit
Sorry, I didn't realize you were looking for an email templating solution. The simplest solution I've come up with is to enable text "macros" in user-generated content emails. So, for example, the user could input:
Dear {RecipientFirstName},
Thank you for your interest in {ClientCompanyName}. The position you applied for has the following minimum requirements:
- B.S. or greater in Computer Science or related field
- ...
And then we'd do some simple parsing to break this down to:
Dear {0},
Thank you for your interest in {1}. The position you applied for has the following minimum requirements:
- B.S. or greater in Computer Science or related field
- ...
... and ...
0 = "RecipientFirstName"
1 = "ClientCompanyName"
...
We store these two components in our database, and whenever we're ready to create a new instance from this template, we evaluate the values of the given property names, and use a standard format string call to generate the actual content.
string.Format(s, macroCodes.Select(c => EvaluateMacroCode(c, obj)).ToArray());
Then I use MarkdownSharp, along with some HTML sanitizing methods, to produce a nicely-formatted HTML email message:
Dear John,
Thank you for your interest in Microsoft. The position you applied for has the following minimum requirements:
B.S. or greater in Computer Science or related field
...
I'd be curious to know if there's something better out there, but I haven't found anything yet.

Resources