MVC3 #Html.ActionLink displays Text together with the address - asp.net-mvc-3

I do not know what I have done wrong but all my #Html.ActionLinks are displaying the expected text together with hyperlink instead of the text alone.
#Html.ActionLink("About", "About", "Home")
displays as
About(Home/About)
instead of
About
In the views,
#Html.ActionLink("Edit", "Edit", new { id = item.Id })
displays
Edit(Home/Edit/4)
instead of the text
Edit
Any clues would be appreciated.

You might have an extension or DisplayTemplate that would change the default behaviour.
It looks like your second example is missing a parameter (the last null for html attributes, I also included the Controller here)
#Html.ActionLink("Edit", "Edit", "Home", new { id = item.Id }, null)

Related

ActionLink can't access root folder - MVC 3

I have an .Net MVC 3 web application that has the following structure
root
Views
Account
LoginPage.aspx
Controllers
AccountController
Areas
Course
Index.aspx
Imagine I am currently at the Index.aspx page in the Course area, and I would have a button that would forward me to the LoginPage.aspx
In a ASP.Net MVC I would call http://localhost/Account/Login that it would lead me to the correct page. If I just write it down on the browser it works!
But I would like to use the HTML Helper ActionLink, so I tried:
<%: Html.ActionLink("Log on", "Login", "Account", routeValues: null, htmlAttributes: new { id = "logonLink", data_dialog_title = "Logon" })%>
It get the relative path: http://localhost/Course/Account/Login
I tried also:
<%: Html.ActionLink("Log on", "Login", "../Account", routeValues: null, htmlAttributes: new { id = "loginLink", data_dialog_title = "Login" })%>
I got the error message: Cannot use a leading .. to exit above the top directory.
I also tried the relative path:
<%: Html.ActionLink("Log on", "Login", "~/Account", routeValues: null, htmlAttributes: new { id = "loginLink", data_dialog_title = "Login" })%>
And it lead me to:
http://localhost/Course/~/Account/Login
I would really appreciate how to find a solution for this problem.
Try this:
<%: Html.ActionLink("Log on", "Login", "Account", new { area = "" } , new { id = "logonLink", data_dialog_title = "Logon" })%>
The key is the area = "" bit. When using Url.Action or Html.ActionLink with areas, if you don't specify the area route value, MVC will only look for a match in the current area.
It get's even more important when using partial views/templates, since they can be rendered in Views in different areas.
So if using areas, get into the habit of always specifying the area route value, unless using Url.RouteUrl or Html.RouteLink.

ViewBag oddity in creating a MultiSelectList

I have spent a lot of time scouring the various forums for help on MultiSelectLists in asp.net MVC3. Finally figured out how to solve my issue now I'm trying to cut down on my code and I've come across something weird with ViewBags. First the code, than I'll explain the behavior.
My function that creates the MultiSelectList to used by the Controller
public MultiSelectList GetPermissionList(string[] selectedValues)
{
List<SelectListItem> permissions = new List<SelectListItem>()
{
new SelectListItem{ Value = "", Text = "None"},
new SelectListItem{ Value = "View", Text = "View"},
new SelectListItem{ Value = "Add", Text = "Add"},
new SelectListItem{ Value = "Edit", Text = "Edit"},
new SelectListItem{ Value = "Delete", Text = "Delete"}
};
return new MultiSelectList(permissions, "Value", "Text", selectedValues);
}
partial code from the edit action from the controller
public ActionResult Edit(int id)
{
ViewBag.Title = "Edit a Security Role";
SecurityRoles securityroles = Repository.Details(id);
ViewBag.Orders = securityroles.Orders.Split(',');
ViewBag.OrdersListBox = GetPermissionList(ViewBag.Orders);
return View(securityroles);
}
partial code from the View
<td class="rightAlign topAlign editor-label">
#Html.MyLabel(m => m.Orders, "lblOrders")
</td>
<td class="editor-field">
#Html.ListBoxFor(m => m.Orders, ViewBag.OrdersListBox as MultiSelectList, new { size = "5" })
</td>
Keep in mind I've cut out a large chunk of code from the edit Action, I have roughly 9 list boxes I'm creating for this security role manager.
My goal, in the edit action is to simply have 1 line of code, calling the GetPermissionList and having it return to the viewbag so I can just display that in the view, as opposed to the 2 lines per listbox that I currently have.
Just looking at the code, it seems obvious if I were to make the call this way:
ViewBag.OrdersListBox = GetPermissionList(securityroles.Orders.Split(','));
It should work, but the selected values do not come through. To compound the oddity, here is something else I tried and it worked fine, but it makes no sense why.
ViewBag.Orders = securityroles.Orders.Split(',');
ViewBag.OrdersListBox = GetPermissionList(securityroles.Orders.Split(','));
ViewBag.Orders plays no role in the ViewBag.OrdersListBox nor is it used in the view, but when I simply assign it a value than the 2nd line of code works.
Does this make sense to anyone? Any suggestions on how to create a way for the GetPermissionList to simply work correctly by sending it a string array instead of passing it the ViewBag object?
I think, You have to set Orders because that is what the selected values are being bound to when the selection happens. You could just pass a string[] if you didn't want to have anything preselected. Check out Darin's answer in this post. He is using a model but i think the same concept applies to view bag.
Multiselect with ViewModel

Multiple Html.ActionLink() within single MvcContrib.Grid column in MVC3

I'm trying to wrap my head around the proper syntax to achieve the following--or at least to find out if it's even do-able or if there is a better alternative solution.
Ok, out of the box, when you generate a strongly-typed View using the List scaffold under ASP.Net MVC3 you get a simple table with a column that has something like two or three Html.ActionLink() items representing common actions like so:
Edit | Details | Delete
I would like to use the MvcContrib grid and do the same, but I cannot figure out the correct syntax to get it to work. So far, in my Index.cshtml, I have the following snippet:
#(
Html.Grid(Model.PagedList).AutoGenerateColumns()
.Columns(column =>
{
column.For(f => Html.ActionLink("Edit", "Edit", new { id = f.itemID}))
.Named("");
})
.Sort(Model.GridSortOptions);
)
but that just gives me one column for "Edit", where as I want the column to contain three action links--Edit, Devices, Delete--with all three having the same itemID for the particular row. Is this achievable? And if so, how? If not, is there an alternative?
You could use a custom column:
columns.Custom(
#<text>
#Html.ActionLink("edit", "edit", new { id = item.Id }) |
#Html.ActionLink("details", "details", new { id = item.Id }) |
#Html.ActionLink("delete", "delete", new { id = item.Id }) |
</text>
);
Maybe it helps somebody:
#Html.Grid(Model).Columns(column =>
{
column.For( c=> Html.Raw(Html.ActionLink(...).ToString() +
" " + Html.ActionLink(...).ToString())).Named("Actions").Encode(false);
....
You should pass an inline helper:
column.For(#<text>
#Html.ActionLink("Edit", "Edit", new { id = item.itemID })
#Html.ActionLink(...)
#Html.ActionLink(...)
</text>)

MVC DropDownListFor() Selected Item is not Selected / Required Validation not run

I am having trouble getting my DropDownList to set the selected item to the value from the model.
The field in the model is just a string for the Title of the users name (Mr, Miss etc..) Below is my code so far.
<td>
#{ var list = new List<SelectListItem>(new[] {
new SelectListItem{ Selected = string.IsNullOrEmpty(Model.Title), Text="",Value=""},
new SelectListItem{ Selected = Model.Title.Equals("Mr"), Text="Mr",Value="Mr"},
new SelectListItem{ Selected = Model.Title.Equals("Mrs"), Text="Mrs",Value="Mrs"},
new SelectListItem{ Selected = Model.Title.Equals("Miss"), Text="Miss",Value="Miss"},
new SelectListItem{Selected = Model.Title.Equals("Ms"), Text="Ms",Value="Ms"}
});
}
#Html.DropDownListFor(m=>m.Title, list)
</td>
I had this problem with MVC 3 and it turned out that I had set ViewBag.Title on my View (using it for the page title). As soon as I changed it to ViewBag.PageTitle, the dropdownlist code started working : #Html.DropDownListFor(model => model.Title, Model.MySelectList)
The reason for this is that in MVC 2/3, any ViewBag / ViewData properties with the same name as those in the Model object get used in preference in DropDownListFor(), so you need to rename them to make sure they don't conflict. Because that seems really flaky, I just stopped using ViewBag entirely and now rely only on the View Model for passing stuff into the View.
The reason this problem is so prevalent is that ViewBag.Title is used in many introductory tutorials and demo code to set the HTML title element, and so inevitably gets adopted as a "best-practice" approach. However, Title is a natural Model property name for use in dropdowns on a "User Details" view.
So it turns out that the only reason it doesn't work is because my field name is Title, I changed it to Prefix and my exact code works. Way too much time spent finding that out...
Here is working code.
<td>
#{ var list = new List<SelectListItem>(new[] {
new SelectListItem {
Selected = string.IsNullOrEmpty(Model.Prefix),
Text="",
Value=""
},
new SelectListItem {
Selected = Model.Prefix.Equals("Mr"),
Text="Mr",
Value="Mr"
},
new SelectListItem {
Selected = Model.Prefix.Equals("Mrs"),
Text="Mrs",
Value="Mrs"
},
new SelectListItem {
Selected = Model.Prefix.Equals("Miss"),
Text="Miss",
Value="Miss"
},
new SelectListItem {
Selected = Model.Prefix.Equals("Ms"),
Text="Ms",
Value="Ms"
}
});
}
#Html.DropDownListFor(m => m.Prefix, list)
</td>

MVC 3 View with partial view and Ajax form

Here is my quandary. I have an MVC 3 web site, and I have a page that needs to contain a sub-form, if you will, to collect some data related to my model. I have successfully created a partial view that contains the markup and I am rendering this properly. However, the input button in the partial view doesn't seem to be doing much of anything. Here is the form in the partial view:
#using (Ajax.BeginForm("AddProductCustomField", new AjaxOptions { HttpMethod = "POST", UpdateTargetId = "addCustomFieldView" }))
{
#Html.DropDownListFor(m => m.SelectedCustomFieldId, new SelectList(Model.CustomFields, "FieldId", "FieldName"), "-- Select One --", new { #class = "int_std_select" })<text> </text>
#Html.TextBoxFor(m => m.CustomFieldValue, new { #class = "int_std_textbox" })
<input type="submit" value="Add Custom Field" /><br />
}
"AddProductCustomField" is the name of my controller method that I want to handle this form post. However, clicking the submit button does nothing. I even popped open Fiddler to see if a request was getting eaten and nothing. I've included all the appropriate JavaScript files for this page (MicrosoftAjax, MicrosoftMvcAjax and the unobtrusive JavaScript). I'm stumped.
Please let me know if I need to provide more info. Thanks much, this has been stumping me for days!
You mentioned sub-form. Do you literally mean you are nesting forms? This is not supported in HTML, so I would think that's probably the source of your problem.

Resources