I am using ASP.NET MVC 3, with the Razor engine. I have a partial view that contains one line:
#Html.ActionLink(ViewData["UserNameIfLoggedIn"], "Index", "Home")
This partial view is rendered in my _Layout.cshtml view. The snippet that calls the controller/action is this:
#{Html.RenderAction("UserLoggedIn", "User");}
I get a compilation error, stating:
'System.Web.Mvc.HtmlHelper' does not contain a definition for 'ActionLink' and the best extension method overload 'System.Web.Mvc.Html.LinkExtensions.ActionLink(System.Web.Mvc.HtmlHelper, string, string, object)' has some invalid arguments
I have made a similar call (same amount of arguments and same parameter datatypes) in another MVC application (a tutorial) and it executed just fine. What could be causing this?? Why is this not working now?
I know this is probably an extremely rookie MVC question, but I cannot figure this one out.
EDIT: The solution is this:
#Html.ActionLink(ViewData["UserNameIfLoggedIn"].ToString(), "Index", "Home")
I just needed to call the ToString() method to get the parameter as a string.
You need a string as your first parameter in ActionLink, I am not sure but I think ViewData is a dictionary.
Try this just as a test
#Html.ActionLink("test", "Index", "Home")
If that works, then you need to loop through ViewData and get all the single values, and pass them as string. I am not sure what is your ViewData, though.
If you want just a single value, use ViewBag instead.
http://brendan.enrick.com/post/Difference-Between-ViewBag-and-ViewData-in-MVC-3.aspx
It's because ViewData / ViewBag is a dynamic that has no idea what type of data it holds, you need to unbox into a local variable before trying to use it
#{ var foo = ViewData["Title"]; }
#Html.ActionLink(foo.ToString(), "Index", "Home")
Related
I don't get why we sometimes use ViewBag without reference (I mean #) to Controller in View, e.g.:
#{
string urlFilter = Url.Action("Index", "Home", new
{
CustID = ViewBag.custid,
Errors = ViewBag.errors
});}
It looks like a part of c# code in view. I know that razor synthax allow us to inject c# code into View but don't understand what's the point of using ViewBag without # in View
In this case it is because it is within the scope of a C# code block (#{ ... }) and not in the HTML markup.
If however, you were trying to reference the ViewBag inline in an HTML block you would need to prefix it with # to make sure it was processed by the Razor engine.
for example:
<p>#ViewBag.Name</p>
ViewBag is a dynamic property on the WebPageView from which the view is derived.
You can learn about the Razor syntax here: https://learn.microsoft.com/en-us/aspnet/web-pages/overview/getting-started/introducing-razor-syntax-c
According to Microsoft's documention, I should be able to pass an anonymously typed object as additionalViewData when calling #Html.DisplayFor; however, when I do this, I receive a yellow screen stating:
The model item passed into the dictionary is of type
'System.Collections.Generic.List'1[Surveys2.Models.ReportingSidebarItemViewModel]', but this dictionary requires a model item of type 'Surveys2.Models.ReportingSidebarItemViewModel'.
Here is part of my view:
#model Surveys2.Models.ReportingPageViewModel
#Html.DisplayFor(m => m.Pages, "ReportingSidebarItemViewModel", new { PageType = Model.PageType } )
Here is my controller action:
public ActionResult Summary(string projectCode)
{
ReportingPageViewModel reportingPageViewModel = GetReportingPageViewModel(new ReportingPageParams { ProjectCode = projectCode });
return View("Page", reportingPageViewModel);
}
The problem here is that you're targeting the display page by using the second param of DisplayFor. When you call displayfor(m=> m.prop) without a target view the ViewEngineCollection looks for the best suited diplay page. When the best suited display page is only for a single item and you passed a list it will iterate for you. The targeted display for assumes you are passing the exact type of the page you are targeting and thus it breaks.
EDIT-- Interestingly enough the MSDN Docs don't talk about looping except on the DisplayFor(m=> m.prop) method
I am new to mvc. Exploring the ways to pass value from action method of one controller to other controller. Is this possible to pass xml as value from one controller to other in httppost?
You can use Session, which is available at pretty much any time in a controller, and is very simple to use.
Session["ArbitraryKeyString"] = "Assign any object";
string arbitraryString = (string)(Session["ArbitraryKeyString"] ?? "Session returns null if key not found");
Just be sure to cast it back to the type you need, because it's stored as a Object. You can do this during server calls, since they're all simply external ways to call controller functions, and the values will persist between pages and calls.
Passing it as a parameter is probably your best option. Try using something like return RedirectToAction(ActionName, ControllerName, RouteValues);.
I've been having some problems getting redirects after login to work how I want. So I came up with the idea to store the current page in the viewbag and use that to redirect, so if the page is mydomain.com/debate/1 I end up with "/debate/1" stored in the viewbad but when I try to redirect its giving me this complaint
The parameters dictionary contains a null entry for parameter 'id' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult DebateDetails(Int32)' in 'PoliticalDebate.Controllers.DebateController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.
Parameter name: parameters
However If I manually type in mydomain.com/Debate/1 it works as expected.
Is there some way to get Redirect to work how I want ?
Since I don't see any code, I can't comment on the way you are trying to do it (which isn't working). On future posts, please post your code. This is one way how you can redirect if you are simply redirecting to the default action on the controller:
return this.RedirectToAction("Index", new { id = debateDetailsID } );
Although it's very hard to tell what you are truly trying to do because you mention debate/1 yet the method being called is DebateDetails which doesn't match (unless you've changed the default routes, again I don't know, there's no code).
Update
According to your comment, you have an error in your MapRoute. Your MapRoute should look like:
routes.MapRoute("Debate Details",
"debate/{id}",
new { controller = "Debate",
action = "DebateDetails",
// this id value is missing
// so it's not being passed to the controller
id = UrlParameter.Optional } );
the answer is there in the complaint, in this particular case you're sending a parameter so, checkout if this is specified
your code must look like redirectToAction("nameOfAction", new {id = yourIdOnViewBag}
I'm currently trying to user actionlink helpers in a way that I don't think was described in NerdDinner.
Lets say I am on this page
/Dinners/
and on that page there is a list of dinners, ok fine and working
now lets say I want to goto a new section of the site, which I have created a new controller MenuItemsController
so lets say I want to goto a new part of the website that manages menu items.
So going to
/menuitems/3
would bring up all the menu items assoicated with dinner id 3.
This is also working.
I am having trouble, linking to each of the menu item pages, because when I use the actionlink code, without much modification i get this
dinner1 = link /dinners/menuitems/3
rather than
dinner = link /menuitems/3
The actionlink code i am trying is
<%= Html.ActionLink("Menu Items", "/menuitems", new { id=item.id })%>
you can see the / there. This feels wrong.
I wasn't sure if this post was talking about the same problem or not.
how do i have links to root controllers in site.master in asp.net mvc
Are action links the completely wrong thing for me to be using here, becuase they are binded directly to the controller I am currently inside of?
If so, what would be the best method for me to achieve what I am trying to do, and also add further complexity like linking to create/edit/delete methods?
Just get rid of the slash and specify the controller and action explicitly:
<%= Html.ActionLink("Menu Items", "Item", "menuitems",
new RouteValueDictionary { { "id", item.id } })%>
You don't give an action name in your examples, so I guessed "Item." Insert the correct action name, obviously.
The current controller name is used if you use one of the ActionLink overloads which don't take a controller name.
I've written an in-depth explanation of routing, ActionLink, and more.
I oddly after much searching all day just found this page,
http://devlicio.us/blogs/derik_whittaker/archive/2008/03/06/link-building-101-with-asp-net-mvc.aspx
it seems like method 3 may be what I need, I'll try it when I get home.