Can you help me? I used contoller HomeConrtoller.cs for view, edit and delete articles. All work, but When I go to the next page I get error don't found http://local.../Articles/1
public ActionResult Articles(int? page)
{
var viewData = mybaseRepository.FindAllArticles();
const int pageSize = 10;
var paginatedArticle = new PaginatedList<Article>(viewData, page ?? 0 , pageSize);
ViewData["Page"] = paginatedArticle.PageIndex;
return View(paginatedArticle);
}
In Global.asax.cs
routes.MapRoute(
"Articles",
"Articles/{page}",
new { controller = "Home", action = "Aticles", page = (int?)null }
);
paging in Articles.aspx
<% if (Model.HasPreviousPage) { %>
<%= Html.RouteLink("предыдущая <<<",
"Articles",
new {page = (Model.PageIndex - 1) })%>
<% } %>
<% if (Model.HasNextPage) { %>
<%= Html.RouteLink(">>> следующая",
"Articles",
new {page = (Model.PageIndex + 1) })%>
<% } %>
<div>
You wrote "Articls" in the URL but "Articles" when defining the route. Would that be it?
Related
I am trying to present a form to my user where they can enter a start postcode, hit a button and end up on a page offering driving directions to a known postcode.
The route I want to match is defined as:
routes.MapRoute("Directions", "Directions/{Name}/{StartPostCode}-to-{DestinationPostCode}", new { controller = "Directions", action = "Index" });
I am using the following code to present the form:
#using (#Html.BeginForm("Index", "Directions", new { DestinationPostCode = Model.postcode, Name = Model.nameURLized }, FormMethod.Get))
{
<input type="text" name="StartPostCode" id="StartPostCode" class="inputGreyed" value="Enter Postcode" onclick="ToggleDefaultText(this)"/>
<input type="submit" value="Get Directions" />
}
The problem is that I end up at /Directions/Index?StartPostCode=abc123. It is missing the destination postcode and the name key value pairs. This of course means I end up with my request being processed by the wrong route. I have proved this using Phil Haacks route debugger.
I have tested going directly to /Directions/TheName/ABC123-to-DT83PX which works as expected. In fact, I tried this using the following code to build a link:
#Html.ActionLink("Directions Generated", "Index", "Directions", new { StartPostCode = "ABC123", DestinationPostCode = Model.postcode, Name = Model.nameURLized }, new { #class = "button", #title = "More details on " + Model.name })
Any help will be much appreciated.
Please do the following:
a) add the default route:
routes.MapRoute(null, "{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = UrlParameter.Optional }
b) Pass the values for DestinationPostCode and ListingName in hidden input fields.
c) Use:
#using (#Html.BeginForm("Index", "Directions")) { your code }
Asp.net Mvc1
On my Views/home/Index.aspx which routes from http://localhost/DefectSeverityAssessmentMvcBeta/
This renders
Response.Write("<a href=\"");
Response.Write(Url.Action("Create", "Registration"));
Response.Write("\">Begin Registration</a>");
But returns a 404 for the address of the link http://localhost/DefectSeverityAssessmentMvcBeta/Registration/Create
while this Does not render or show in view source but doesn't cause any exception:
Html.ActionLink("Begin Registration", "Create", "Registration");
I have a RegistrationController and a /Views/Registration/Create.aspx
The registration controller has breakpoints on Index() and Create() but they are not being hit.
I'm not sure how I would use <%= %> in this scenario because it's inside the following code block:
<% if (ViewData.ContainsKey("user"))
{
if (ViewData.ContainsKey("registered") && (bool)ViewData["registered"] == true)
{
//Html.RouteLink("Resume Assessment", "Assessment", new { controller = "Assessment", action = "Index" });
Response.Write("<a href=\"");
// Html.ActionLink("Resume Assessment", "Index", "Assessment");
Response.Write("\">Resume Assessment</a>");
}
else
{
//Html.RouteLink("Begin", "Registration", new { controller = "Registration", action = "Edit" });
// Html.ActionLink("Begin Registration", "Create", "Registration");
Html.RouteLink("Begin", "Default", new { controller = "Registration", action = "Edit" });
//Response.Write("<a href=\"");
//Response.Write(Url.Action("Create", "Registration"));
//Response.Write("\">Begin Registration</a>");
}
}
else
{ Response.Write("Authentication failed"); }
%>
Are you using <% %> in the HTML for both Response.Write and Html.ActionLink? Try using <%= %> for Html.ActionLink(...);
The added equal sign calls Response.Write behind the scenes thus writing you code to the screen.
Because Html.ActionLink return the string and do not write to the response stream. You need to write to your page using <%= %> or Response.Write();
Response.Write(Html.ActionLink("Begin Registration", "Create", "Registration"));
I was not making use of the ability to use
<% if(x) {%> <%=Html.ActionLink(...)%><% } %>
Thanks to Charles Conway I got it working. Here's the code I wound up with:
<div class="entry">
<% if (ViewData.ContainsKey("user"))
{
if (ViewData.ContainsKey("registered") && (bool)ViewData["registered"] == true)
{ %>
<%=Html.ActionLink("Resume Assessment", "Index", "Assessment") %>
<% }
else
{ %> <%=Html.ActionLink("Begin Registration", "Create", "Registration") %>
<%
}
}
else
{ Response.Write("Authentication failed"); }
%></div>
Are you using an equals sign in your context switch, like this?
<%= Html.ActionLink("Begin Registration", "Create", "Registration"); %>
^--needs equals sign here
If you're not using an equals sign, you have to write directly to the Response object.
As far as the routing errors go, you can check out your routes using Phil Haack's diagnostic tool at http://haacked.com/archive/2008/03/13/url-routing-debugger.aspx.
Anything less than IIS7 requires special configuration for the routing.
My original question was a bit confusing, so let me edit this post to be more clear:
How can I generate an ActionLink that not only uses the Routing engine, but also takes you to an html element with particular ID on a page? I want to generate something like this:
<a href="/ControllerName/ActionName/#section2>Link</a>
or sometimes the same but with an action parameter of 15 for example:
<a href="/ControllerName/ActionName/15#section2>Link</a>
Where the View served by the actionName has an element with the id of "section2":
<div id="section1">
<h1>Section 1</h1>
...
</div>
<div id="section2">
<h1>Section 2</h1>
...
</div>
I believe that I could write a Html helper method that uses Url.RouteUrl() and then append the "#sectionId" but is this the easiest/best way to do this? Should I create a routing rule for this? The default route:
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Experiment", action = "Index", id = "" }
);
allows me to manually add "#section2" to the end of the url in my browser and it takes me to the section2 div. It seems like rather than adding or changing a route I simply need to append "#section2" to the ActionLink url.
You would want to change/add a route to be:
routes.MapRoute("MyRoute", "{controller}/{action}#{id}", /* some default here */);
Then the MVC Helper would be:
<%= Html.ActionLink("Link Text", "Index", new { id = "sectionId" }) %>
For the following route:
routes.MapRoute(
"Default",
"{controller}/{action}/{id}/{section}",
new { controller = "Home", action = "Index", id = "", section = "" }
);
you would do:
<%= Html.ActionLink("Link Text", "Index", new { section = "#sectionId" }) %>
I think the OP wants the ID to be the anchor ref at the end of the URL, as it appears to be a list of items and he wants the browser to scroll down to the item. (I'm just guesing here because of the "#" stipulation. Small edit to Mark's code:
routes.MapRoute(
"Default",
"{controller}/{action}/#{sectionId}",
new { controller = "Home", action = "Index", sectionId = Model.SectionId } );
Input:
Id, PartId, Name
1, 1, Head
1, 2, body
1, 3, Tail
2, 1, Head
2, 2, Leg
Output Display:
- Head, Body, Tail [Delete(1)]
- Head, Leg [Delete(2)]
My Code:
<ol>
<%
int prev = -1;
foreach (var item in t)
{
if(prev != item.ResponseId){
if (prev != -1)
{%>
<%= Html.ActionLink("[replacethis]", "RemoveResponse", new { id = item.ResponseId })
.Replace("[replacethis]", "<img src=\"../../Content/images/delete_icon.gif\" class=\"borderlessImage\" title=\"Remove\"/>")%>
</li>
<%} %>
<li>
<% }
else {
%>, <%
} %>
<%= Html.Encode(item.ResponsePartValue) %>
<% prev = item.ResponseId;
} %>
<%= Html.ActionLink("[replacethis]", "RemoveResponse", new { id = prev })
.Replace("[replacethis]", "<img src=\"../../Content/images/delete_icon.gif\" class=\"borderlessImage\" title=\"Remove\"/>")%>
</li>
</ol>
Questions:
What are the ways to refactor this?
Any MVC tricks I am missing?
Well, first of all you could create an HtmlHelper that renders image links for you, instead of generating the anchor tags first and then replacing their content with an image.
Take a look at here.
Also you don't have to use <%= every time you need to ouput some text. If you already have opening code blocks (ie <%), then you can just use Response.Write method to output what you want. In cases like yours, that'll most likely look better than %> <%=.
Though, I admit I don't exactly know what you are listing here and how you want it to display. But following your algorithm, I guess this is what I would have done :
<ol>
<%
int prev = -1;
foreach (var item in t) {
if(prev != item.ResponseId) {
if (prev != -1) {
Response.Write(Html.ImageLink("../../Content/images/delete_icon.gif", "RemoveResponse", new { id = item.ResponseId, #class ="borderlessImage", title = "Remove" }) + "</li>");
}
Response.Write("<li>");
}
else {
Response.Write(", ");
}
prev = item.ResponseId;
Response.Write(Html.Encode(item.ResponsePartValue));
} %>
<%= Html.ImageLink("../../Content/images/delete_icon.gif", "RemoveResponse", new { id = prev, #class ="borderlessImage", title = "Remove" }) %>
</li>
</ol>
I would put everything into a dictionary, it would make your logic more logical :-)
Something like:
IDictionary<int, List<Part>> partsDictionary = new Dictionary<int, List<Part>>();
Where the int key is your id and then the value of type List would be your individual parts.
Then put the logic into a HtmlHelper extension.
E.g. (Although I don't know what you're doing, view code doesn't match you db model at the top. This should give you an idea)
public static string PartsList(this HtmlHelper html, IDictionary<int, List<Part>> partsDictionary)
{
if (partsDictionary.Count == 0)
return "";
StringBuilder toReturn = new StringBuilder("<ol>");
foreach (KeyValuePair<int, List<Part>> kvp in Model.PartsDictionary)
{
toReturn.Append("<li>");
//Individual part links
IList<string> partsLinks = new List<string>();
foreach (Part part in kvp.Value)
partsLinks.Add(html.ActionLink(part.PartName, "ActionName", new { #id = part.Id }));
toReturn.Append(string.Join(", ", partsLinks.ToArray()));
//Part category(?) link
toReturn.Append(html.ActionLink("Delete", "ActionName", new { #id = kvp.Key }));
toReturn.Append("</li>");
}
toReturn.Append("</ol>");
return toReturn.ToString();
}
Or something like that ;-)
HTHs
Charles
I am trying to implementation the same pagination that is used in the NerdDinner ASP.NET. I am receiving the following error in my view, whenever the pagination starts to kick in.
"A route named 'Index' could not be
found in the route collection."
The error is happening on Line 64.
Line 62: <% if (this.Model.HasNextPage)
Line 63: { %>
Line 64: <%= this.Html.RouteLink("Next Page >>>", "Index", new { page = (this.Model.PageIndex + 1) })%>
Line 65: <% } %>
Line 66: </div>
My controller code is:
[Authorize]
public ActionResult Index(int? page)
{
const int pageSize = 25;
var topics = this.TopicRepository.FindAllTopics();
var paginatedTopics = new PaginatedList<Topic>(topics, page ?? 0, pageSize);
return this.View(paginatedTopics);
}
My view code is ...
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<CreativeLogic.Sauron.WebMvc.Helpers.PaginatedList<CreativeLogic.Sauron.WebMvc.Models.Topic>>" %>
<!-- Code to display the list here -->
<div class="pagination">
<% if (this.Model.HasPreviousPage)
{ %>
<%= this.Html.RouteLink("<<< Previous Page",
"Index", new { page = (this.Model.PageIndex - 1) }) %>
<% } %>
<% if (this.Model.HasNextPage)
{ %>
<%= this.Html.RouteLink("Next Page >>>",
"Index", new { page = (this.Model.PageIndex + 1) })%>
<% } %>
</div>
This is my first attempt at doing the pagination in ASP.NET MVC ... if there is a better way, please let me know, otherwise, where am I going wrong here?
Thanks much!
You should not use RouteLink (which takes a route name) but instead use an ActionLink which takes an action name like Index.
Well the RouteLink Extension Method looks for a defined route with the name of "Index" in the Global.asax, and by default there is just 1 route defined in the Global the "Default", it looks like this:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
Maybe as HakonB said you must use the ActionLink Extension Method or define a route in the Global asax for the pagination.