I'm following this MVC tutorial and when I add a View for the Edit action, Model is null in the following snippet on the .aspx page:
<%= Html.TextBox("Id", Model.Id) %>
I'm learning MVC, so please understand if I'm doing a dumb thing. But as far as I can see, I've following the steps in the tutorial pretty well. And actually added the Create action and it works correctly.
Ideas appreciated.
Is your view strongly typed?
<%# Page Language="C#" MasterPageFile="~/Views/Shared/TwoColumnUI.Master" Inherits="System.Web.Mvc.ViewPage<MyObject>" %>
then you would need to pass in an object of type MyObject from your controller action method
return View(new MyObject() { Id = 42 } );
Did you set the model in the controller? What does your controller method look like? Are you just returning View()? You need to pass the model as a parameter to that call like they do in the example:
return View(movieToEdit);
Related
I'm using ASP.NET MVC 4.
I implemented the solution here, and it works great for Html.ActionLink. However, when I use Html.Action or Html.RenderAction it doesn't work. I get error:
The controller for path '/Demarrer' was not found or does not implement IController.
Steps to reproduce:
Download the sample code from the website above. LocalizedRouteExample.zip (23.23 kb)
Add a new controller SetupController and respective View.
Add on the homepage:
<%= Html.ActionLink("Setup", "Index", "Setup") %>
<% Html.RenderAction("Index", "Setup"); %>
.
4. Add on Global.asax line 30:
new RouteValueTranslation(cultureFR, "Setup", "Installation")
.
public class SetupController : Controller
{
public ActionResult Index()
{
return PartialView();
}
}
Views/Setup/Index.ascx:
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
<strong>This is SETUP</strong>
5) Now change to French language and jump back to homepage.
I know its' because it can't find the controller. What should I pass to this RenderAction method to make it work?
For RenderAction, a solution using "ViewContext.RequestContext.RouteData.DataTokens" is presented here:
ASP.NET (MVC) routes internationalization
I have a usercontrol named "LoginUserControl.ascx" which I have placed in a master page.
Header of "LoginUserControl.ascx"
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<MultiTechnologyWeb.Models.loginmodel>" %>
Then I used the below code to show the usercontrol in the masterpage.
<% Html.RenderPartial("LoginUserControl"); %>
On first run the page "index" is loaded.
Notice the header of the "index" page, no model is specified. Thus page load successfully
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/MT.Master" Inherits="System.Web.Mvc.ViewPage<dynamic>" %>
Now I click on the link to open register.aspx. I got the below error
The model item passed into the dictionary is of type 'MultiTechnologyWeb.Models.registermodel', but this dictionary requires a model item of type 'MultiTechnologyWeb.Models.loginmodel'.
Header of "register.aspx" page
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/MT.Master" Inherits="System.Web.Mvc.ViewPage<MultiTechnologyWeb.Models.registermodel>" %>
So to my understanding model is being interchanged, so anybody can please help me on how to resolve this issue
More Explanation.............LATEST
I have debug, i know that the crash is occuring after the actionresult for register is finished execution.
Code below is for actionresult "register"
public ActionResult register()
{
registermodel model;
//some code here
return View("register",model);
}
So i'm just returning one type of model that is "registermodel", Would it be possible to return another model such as "loginmodel" by using a list or array to return multiple models in the same view.
You should use <% Html.RenderAction("Logon","Account"); %> in your MasterPage instead of using RenderPartial and in this action you just return the login partial you want to use in the header
public ActionResult Logon(){
// do your stuff
return PartialView("LoginUserControl");
}
By this way you could pass the loginmodel to the LogInPartial and pass registermodel to the register page
Please not that RenderAction and RenderPartial are not the same.
RenderPartial will render only the view. While RenderAction will make a new MVC roundtrip, by making a new instance of the controller etc and returning the result.
To solve your issue you could pass in the MultiTechnologyWeb.Models.loginmodel where you call <% Html.RenderPartial("LoginUserControl"); %>. It would look like this:
<% Html.RenderPartial("LoginUserControl", new MultiTechnologyWeb.Models.loginmodel()); %>
Or:
<% Html.RenderPartial("LoginUserControl", Model.LoginModel); %>
If you're not wanting to send a model to your partial view, which I've wanted to do in the past, you do have to at least pass something to the RenderPartial method.
This was the only method I could find that allowed me to now have to pass a model. I tried passing null and it continued to pass the parent model
<% Html.RenderPartial("LoginUserControl", new ViewDataDictionary()); %>
I'm trying to accomplish something like this. I feel like it's possible, and if not probably an oversight in the MVC framework?
View:
<%# Page Language="C#" Inherits="System.Web.Mvc.ViewPage<List<MyViewModel>>" %>
...
<% foreach (MyViewModel vm in Model) {
Html.RenderPartial("MyViewModelPartial", vm);
} %>
The partial view being an editable form, strongly typed to a single MyViewModel, and use the DataAnnotations on the MyViewModel class to validate
Controller:
public ActionResult FooController(List<MyViewModel> vml)
{
...
}
Is this possible? This seems like the most logical way to build grid/table structures in MVC(with each partial view being a table row) but I can't seem to get it to work and I end up using FormCollection in my controller to loop through the whole dang form, and it's just messy.
See:
http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx
Which is linked to from:
Complex model binding to a list
How ASP.NET MVC: How can I bind a property of type List<T>?
First, I use Asp.Net MVC 2 RC 2.
What I want to do is to list a comment view and below this view being able to add comment (with validations). For example, something like when you add comment in stackoverflow. Except that my page should work with or without javascript enabled.
So to solve that problem I use the new RenderAction and it partially solved my problem. I got my list view that calls my addcomment usercontrol with RenderAction.
The validations work. My problem occurs when I try to add a comment that it's valid. The page didn't refresh correctly. If I got in the database, my comment is added, but it's doesn't have been refresh in my list view and the add comment form isn't clear.
I think it's because of how the workflow is rendered.
Maybe if someone got a example or blog about this, it's can help me to get it right...
At the bottom of my Comment/List.aspx
<% Html.RenderAction("Create", "Comment"); %>
In Comment/Create.ascx
<% using (Html.BeginForm(
ViewContext.ParentActionViewContext.RouteData
.Values["action"].ToString(),
ViewContext.ParentActionViewContext.RouteData
.Values["controller"].ToString(),
FormMethod.Post, new { id = "createForm" })){ %>
You can force the parent View to refresh itself with a small hack involving ViewContext.ParentActionViewContext.
In your CommentController class:
public ActionResult Create(Comment comment)
{
...
if (isValid) // Comment entered in form is valid
{
ControllerContext.ParentActionViewContext.ViewData["SuccessfullCreate"] = true;
}
...
}
And in your Comment/List.aspx page (view) :
<% Html.RenderAction("Create", "Comment"); %>
<%
if (ViewContext.ViewData["SuccessfulCreate"] != null)
{
string action = ViewContext.RouteData.Values["action"].ToString();
string controller = ViewContext.RouteData.Values["controller"].ToString();
string url = "/" + controller + "/" + action;
Response.Redirect(url);
}
%>
So basically, what's happening is that the child action is "telling" the parent action to refresh itself by using the parent's ViewData.
It's kind of a hack, but it works fine for what's you're doing.
I'm with a problem, I have a ajax link that pass a parameter, but, the page that it opens does not need that parameter. The page only load 2 partial views, one of those need that parameter passed to the page to load the data correctly, and the other just need to load a form, so, don't need that parameter. How can i acheive this?
In order to do what you want, you will need to add the id to the ViewData construct.
var sysfunctions= UnisegurancaService.FunctionsRepository.All();
ViewData["NeededID"] = id
return View(sysfunctions);
then in your view where you render the partial
<%= Html.RenderPartial("GridFunction", (int)ViewData["NeededID"]) %>
Cast as required of course.
Whatever gets pushed in as the second param becomes the .Model in the partial. I would suggest also strongly typing your partials.
Try this:
<% Html.RenderPartial("GridFunction", new ViewDataDictionary {{"Id", ViewData["Id"]}}); %>
UPDATED:
And add this in your controller action:
ViewData["Id"] = Id;
UPDATED:
And in your GridFunction partial View you can access Id as:
<%= ViewData["Id"] %>
//Controller
public ActionResult EditFunctions(int id)
{
var sysfunctions= UnisegurancaService.FunctionsRepository.All();
return View(sysfunctions);
}
// This is the controller (it does no need the parameter "ID")
//This is the view "EditFunctions"
<div id="formFunction">
<% Html.RenderPartial("FormFunction"); %>
</div>
<div id="gridFunction">
<% Html.RenderPartial("GridFunction"); %> // The grid needs the ID to work correctly but its in the parent page not in the partial call....and the call is an ajax call
</div>
If some dependency of the page needs the parameter, then the page needs to know enough to pass the data in, so the page should be able to provide the data. Or, more simply, just add the parameter to the Page's viewdata and be done with it.