When we have anything that requires user input (Eg adding a product to a database) the Edit screen looks the same as the add screen. When using MVC .Net how do you handle this? Do you return the same view? Just adjust the model to reflect the change?
Same (partial)view
You create only one but strong typed view (depending on the UI it can of course be a partial view as well). When adding new data return this view from controller action with default model object instance (usually just a new instance without any properties being set), but when you edit, return it with the object instance that you'd like to edit.
Controller part
Regarding controller actions you can have four of them:
Add GET
return View("SomeView", new Customer());
Add POST
Edit GET
return View("SomeView", new CustomerRepository().GetCustomer(id));
Edit POST
Bot GET actions return the same view but with different model as described earlier. POST actions both store submitted data, but return whatever they need to. Probably some RedirectToAction()...
You can use the same view for display and Edit, simply call it from your controller
return View("ViewName")
You could have the form fields in a partial view and have two separate views using the same partial view, one posting to the edit controller action method and the other posting to the add controller action method.
Partial views are used to remove duplicity. You could read an example of this in the Nerd Dinner tutorial.
Related
I have a user control that creates a new record in a database. After it creates the new record, I would like to redirect it back to the view its from. The purpose of this is to refresh the view so that it can show the newly created record. The problem is that user control can exists in more than one view, so how can i know which view is the user control from? so that I can achieve the above scenario? Thanks,
RWendi
I have a user control that creates a new record in a database.
No, it doesn't. It just renders HTML, and nothing else.
It's the controller action which creates a new record in the database, and thus this is where the redirect should happen.
The [HttpPost] action which accepts the model/form should perform the redirect after the save has been completed.
E.g:
public ActionResult Save(SomeModel model)
{
db.Save(model);
return RedirectToAction("Index");
}
I'm assuming that the "view" you want to refresh is the same page, regardless of which page the user controller was rendered on, therefore the above code is fine.
On a side note, you shouldn't be using user controls (e.g partials) for rendering forms.
You should be using editor templates. The presentation code which renders the form (and specifies which action to post to) should be in the view, not in the user control.
EDIT - example of how to render form on Views:
Instead of doing this on a View:
#Html.Partial("_SomeModel")
Do this:
#using (Html.BeginForm()) {
#Html.EditorFor(model => model.SomeModel)
}
And place the form markup in the editor template. The key thing here is IMO the Views should be responsible for setting up the form, not the user control.
There are several ways,
1) You can use this.Request.UrlReferrer.AbsoluteUri , which will always give you the Url of your page.
2) Or, you can have a hidden property in ... in PartialView, which will hold the value for current url. (#this.ViewContext.ParentActionViewContext.HttpContext.Request.UrlReferrer.AbsoluteUri)
But only if you are using #Html.RenderAction.
In the child action, you can redirect to either of above urls. (First approach is much more better and will work in all scenarios)
I think the refresh is responsibility of the action that renders the view your user control is from.
You can have scenarios (or views) where the inserting is done in one action and then pass the request to another action (maybe a list) that shows the newly created record.
Or you can have other scenarios where the inserting is just part of what you want to save to the db and refreshing the original view may cause the loss of data.
Maybe what I'm saying is not what happens with your project right now but it's something you should consider before giving the user control a responsibility it shouldn't have.
So I'm trying to add a partial view to my main view in MVC3, but the partial view needs new data. Instead of expanding the view model that has the necessary data in the main view and then passing it along to the partial view, is it possible to specify a controller action that directly feeds the partial view with the necessary model?
For example something like:
#Html.Partial("_PartialView", Controller, Action, Parameters)
Thanks in advance.
In a limited sense, yes.
The only thing you can do is send the current model over to another action through Html.Action
Besides that you either need to add it to TempData, or pass what's required in the querystring through your GET parameters OR use an ajax request where you write these values to an html form and serialize that to your new page, but thats a hack : )
I have a RegisterView, used for three different actions. Until now it was only used for two, and I have a FormVisible flag on my view model that the controller sets for the first action, which uses the visible form to collect user details. On the second action, confirming the registration, the details form is not visible.
I now have two sets of details to collect, so instead of a boolean decision of whether on partial view must be rendered or not, I need a way for the controller to specify which partial view to render. How can I do this?
have not tried this, but you can pass the name of the partial view in either the view model or the ViewBag, then use that in your view to render the partialview
in the controller:
ViewBag.PartialView = "PartialViewA";
in the view:
#Html.RenderPartial(ViewBag.PartialView)
I am using ASP.NET MVC and jquery. I would like to implement preview functionality to a form. i.e. I have a form with number of fields for example name, address etc.. Before the user submits the info, he/she can preview it as to how it will appear on the site. Could any one please point me to right direction as to how I could implement this in a cleaner way? I have tried regenearting the html on click.. but it's very messy.
Any help will be highly appreciated.
You could create a new Controller Action called Preview(YourModel model); which would display everything as needed for preview.
The Preview-View should be Strongly typed with your model containing a Submitbutton which THEN calls the [HttpPost]Save/Update(YourModel model); Action.
I'd go with the preview without posting the form, although generating the html could get a bit messy but you can use microsoft's template plugin (included in jquery 1.4.3) to alleviate that. In my book, you're on the right track already.
It should be pretty similar to your "View"<-> "Read" Action from the CRUD operations, the only difference is, you are not populating the model from the database because its not saved yet (in some cases) and you already have the model binded from the FormColecction.
public ActionResult View(int id)
{
//get the data from the DB
//populate the model
//return the view
}
public ActionResult PreView(YourModel model)
{
//populate the model or some pre-formatting
//return the view
}
Using Ajax on the Preview Action get the job done and you don't need to use too much js (that is always a little messy)
I am working on an ASP.NET MVC application that contains a header and menu on each page. The menu and header are dynamic. In other words, the menu items and header information are determined at runtime.
My initial thought is to build a base Controller from which all other controllers derive. In the base controller, I will obtain the menu and header data and insert the required information into the ViewData. Finally, I will use a ViewUserControl to display the header and menu through a master page template.
So, I'm trying to determine the best practice for building such functionality. Also, if this is the recommended approach, which method should I override (I'm guessing Execute) when obtaining the data for insertion into the ViewData.
I'm sure this is a common scenario, so any advice/best-practices would be appreciated! Thanks in advance!
EDIT:
I did find the following resources after posting this (of course), but any additional anecdotes would be awesome!
http://www.singingeels.com/Blogs/Nullable/2008/08/14/How_to_Handle_Side_Content_in_ASPNET_MVC.aspx
How do you use usercontrols in asp.net mvc that display an "island" of data?
Depends on where your information is coming from. We have standard view data that we use to generate some of the information we have on screen that we create in just this fashion. It works well and is easily maintained. We override the View method to implement strongly typed view names and use this information to retrieve some of the data that the master page requires as well.
You could write a helper extension to render the header/menu
That way you could have it show in different places in the view should you need to, but only one place for maintenance.
public static HtmlString MainMenu(this HtmlHelper helper)
Use a base controller class to implement generell filter methods. The controller class implements some filter interfaces IActionFilter, IAuthorizationFilter, IExceptionFilter and IResultFilter which are usefull to implement some common behavior for all controllers.
If the menu data is the same on all pages but different for each unique user.
Generate the menudata in an OnAuthorization or Initialize method of your controller base class. First will be called on authorization. Initialize will be called before every action method. You have access to ViewData Context. Generate the menudata there.
Put the view content for menu and header into the master page and access generated ViewData there.
I tackled a similar design challenge a couple months ago - implementing a breadcrumb feature that changes as user navigates from page to page.
I overrided the OnActionExecuting method to gather the breadcrumbs and store them in ViewData (I use the name of the action as the breadCrumb of the view). Then I updated the Master page to include a user control that takes the ViewData and renders the breadcrumbs.
One thing to be aware is that if you were using the default ASP.NET MVC error handling attribute [HandleError] and your error page is using the same Master page that attempts to read the ViewData, you will soon find out that you can't access ViewData from your error page and it will raise an exception. Depending on whether you need the ViewData for failure scenarios, the viable solution is to use a separate Master page or do this: How do I pass ViewData to a HandleError View?
I'll answer your question with another question. Will the base controller have to determine what type it really is in order to generate the proper menu data? If so, then you're defeating the purpose of polymorphism and the code to generate the data should go in each controller, perhaps in OnActionExecuting if the menu is the same for all actions. Pushing it back down into a parent class seems likely to end up with some switch statement in the parent class doing what each derived controller really ought to take care of.