I registered a route:
routes.MapRoute(
"Journals",
"Journals/{year}/{month}/{id}",
new {
controller = "Journals",
action = "Get",
year = UrlParameter.Optional,
month = UrlParameter.Optional,
id = UrlParameter.Optional
}
);
Action:
public ActionResult Get(int? year, int? month, int? id)
Later in view (just to check):
#Url.Action("Get", "Journals")
#Url.Action("Get", "Journals", new { year = 2013 })
#Url.Action("Get", "Journals", new { year = 2013, month = 4 })
#Url.Action("Get", "Journals", new { year = 2013, month = 4, id = 1 })
And result is:
/Journals
/Journals
/Journals/2013/4
/Journals/2013/4/1
So the 2nd URL missed the parameter. What's wrong?
You cannot have more than 1 continuous optional route parameters.. as it cannot understand which one is missing..
the 2013 in /Journals/2013 could be interpreted as either a year or a month or an id
See Infinite URL Parameters for ASP.NET MVC Route for a workaround using a catch-all route parameter.
Related
I have a Create view that allows a user to add Title and Date. When the user goes to edit it should show the Title and Date when it was created. I'm not sure how to do this.
[HttpGet]
public IActionResult Edit(int id)
{
var iDate = DateTime.Now.ToString("MM/dd/yyyy HH:mm");
var editViewModel = new CreateEditViewModel
{
Id = id,
AsOf = ToEdit.AsOf,
Title = ToEdit.Title,
)
};
editViewModel.AsOf = DateTime.ParseExact(iDate, "MM/dd/yyyy
HH:mm", null);
return View(editViewModel);
}
I am currently using DateTime.Now in the Edit Action in the controller but I know this isn't correct because it was show the current date/time insted of the date and time that it was originally created.
Are you getting the model to edit from a database?
I have these routes:
routes.MapRoute("ListPage", "{controller}/{action}/{pn}/{ps}", new { controller = "home", action = "index", pn = 1, ps = 10 });
routes.MapRoute("Default", "{controller}/{action}/{id}", new { controller = "home", action = "index", id = UrlParameter.Optional });
Which allows me to have URLs like:
/foo/bar/1/10
to control lists of foos on a page (page 1, with 10 items a page). Hooray!
However, the following gives a 404:
/foo/bar/1
Using Url.Action("bar", "foo", new { id = 1}) gives the URL
/foo/bar?id=1
Which then matches correctly to the action signature
public ActionResult Bar(int id) { //stuff }
My thinking is that the first route in the table would not match, as both {pn} and {ps} are required.
So it drops to the second route, which should then match the parameter as {id}.
Obviously my thinking is not correct!
Question is: why is the route not matching without the parameter name?
Just try with interchanging routes postition
routes.MapRoute("Default", "{controller}/{action}/{id}", new { controller = "home", action = "index", id = UrlParameter.Optional });
routes.MapRoute("ListPage", "{controller}/{action}/{pn}/{ps}", new { controller = "home", action = "index", pn = 1, ps = 10 });
I am teaching myself asp .net mvc3 by creating a blog application. However, I have
problems with comment upload. It is a very subtle error in that everything works when a user leaves a comment. However, the url of the post changes.
So, a blog post has a url
http://localhost:49175/Blog/Details/3/Third-post
This is generated by the url route map here:
routes.MapRoute(
"BlogDetail", // Route name
"Blog/Details/{id}/{urlHeader}", // URL with parameters
new { controller = "Blog", action = "Details", id = UrlParameter.Optional, urlHeader = UrlParameter.Optional } // Parameter defaults
);
Now, when a user leaves a comment - he is directed to a comment controller:
[HttpPost]
public ActionResult Create(BlogDetailsViewModels viewModel)
{
if (ModelState.IsValid)
{
try
{
blogrepository.Add(viewModel.Comment);
return RedirectToAction("Details", "Blog", new { id = viewModel.Comment.BlogID });
}
catch (DataException)
{
ModelState.AddModelError("", "Unable to save comment. Try again, and if the problem persits then contact administrator.");
}
}
// If we got this far, something failed, redisplay form
return RedirectToAction("Details", "Blog", new { id = viewModel.Comment.BlogID });
}
}
However, when somebody leaves a comment - he is redirected back to
http://localhost:49175/Blog/Details/3
I know, as of now there is nothing in the RedirectToAction that passes the urlHeader info. However, I have tried a few things like:
return RedirectToAction("Details", "Blog", new { id = viewModel.Comment.BlogID, urlHeader = viewModel.Blog.UrlHeader });
However, it doesn´t seem to work.
This is the blog details controller:
//
// GET: /Blog/Details/5
public ViewResult Details(int id, string urlHeader)
{
var blogs = blogrepository.GetBlog(id);
var recentblogs = blogrepository.FindRecentBlogs(5);
var archivelist = blogrepository.ArchiveList();
BlogDetailsViewModels viewModel = new BlogDetailsViewModels { Blog = blogs, RecentBlogs = recentblogs, ArchiveList = archivelist };
return View(viewModel);
}
I am stuck for days on this.
-- Full route method as requested --
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"BlogDetail", // Route name
"Blog/Details/{id}/{urlHeader}", // URL with parameters
new { controller = "Blog", action = "Details", id = UrlParameter.Optional, urlHeader = UrlParameter.Optional } // Parameter defaults
);
routes.MapRoute(
"BlogArchive", // Route name
"Blog/{year}/{month}", // URL with parameters
new { controller = "Blog", action = "Archive" }, // Parameter defaults
new { year = #"\d{4}", month = #"\d{1,2}", } // Parameter constraints
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
}
If your form does not contains data for viewModel.Blog.UrlHeader, it will be an empty string, even viewModel.Blog may be null.
You can add a parameter to your post action method, like this:
[HttpPost]
public ActionResult Create(BlogDetailsViewModels viewModel, String urlHeader)
And, in your view that renders the form, use this code to generate the form element:
#Html.BeginForm("Create","Blog",new{urlHeader=Model.Blog.UrlHeader})
Alternatively, you can add a hidden input in your form for the urlHeader. In this way, you don't have to do any of previous two updates.
#Html.HiddenFor(m=>m.Blog.UrlHeader)
Either way, make sure your Model.Blog.UrlHeader is not null or an empty string
I have an controller that takes 3 paramteres
public ActionResult Directives(string MachineName, int ProjectId, int CompanyId)
Right now the Url looks like this.
/Project/Directives?projectId=41&MachineName=Apple%20Macbook%20Luft
But how do i get it to look like this.
/Project/Directives/41/AppleMacbookAir/
Try a custom route:
routes.MapRoute(
"Project", // Route name
"{Controller}/{Action}/{projectId}/{machineName}/{companyId}",
new { controller = "Project", action = "Directives", projectId = 0, machineName = "", companyId = 0 } // Parameter defaults
);
http://www.asp.net/mvc/tutorials/controllers-and-routing/creating-custom-routes-cs
You can pass the id as part of the routeValues parameter of the RedirectToAction() method.
return RedirectToAction("Action", new { id = 99 });
This will cause a redirect to Site/Controller/Action/99.
Edit:
For customizing url, you have to create custom route as:
routes.MapRoute( "Project", // Route name
"{controller}/{Action}/{ProjectId}/{MachineName}/{CompanyId}",
new { controller = "Project",
action = "Directives",
ProjectId= 0,
MachineName= "",
CompanyId = 0
} // Parameter defaults );
Use UrlParameter.Optional if you want any parameter optional.
Follow By Stephen Walthe article on ASP.NET MVC Routing
Refer this: RedirectToAction with parameter
I am having an issue with MVC-3 generating outgoing routes for me.
This is the address of the page I am on for both scenarios: http://localhost:1283/Conflict/Create/1200/300
Here are the map routes:
routes.MapRoute(
null, // Route name
"{controller}/{action}/{custId}/{projId}", // URL with parameters
null, // Parameter defaults
new { custId = #"\d+", projId = #"\d+" }
);
routes.MapRoute(
null, // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
Scenario 1:
From the controller:
public ActionResult Create(int custId, int projId)
{
return View();
}
From the view:
#Html.ActionLink("Back to List", "Index", "Conflict", new { custId = ViewBag.custId, projId = ViewBag.projId }, null)
The resulting link that gets created.
http://localhost:1283/Conflict?custId=1200&projId=300
If I change the controller code to read as follows:
public ActionResult Create(int custId, int projId)
{
ViewBag.custId = custId;
ViewBag.projId = projId;
return View();
}
I didn't make any changes in the view, only added those two lines to the controller and the following link is created:
http://localhost:1283/Conflict/Index/1200/300
What am I missing here? This is consistent behavior, I was able to reproduce this in other areas of my application. The "solution" is obvious, but my question is why?
What's happening is the "?custId=1200&projId=300" part of your link is coming over from the link you used to GET the page you're on. So the Html.ActionLink call is doing this:
generate the /Conflict/Index path
look for the custId and projId in the ViewBag and finds the query string instead
just appends your query string
In the second scenario, you're actually providing values, so the link is generating normally. Hope that helps.