I have been given the task of creating a template for Views in MVC. Basically, instead of many Views (CRUD) for each entity, we would only have one that accepts generic model and displays it in Edit/Display mode.
I have so far played around with IView, WebViewPage and ViewPage, but I can't seem to get anything to work. I also searched for something like this, but can't find anything useful really.
Specifically, I don't know which C# class I could overwrite/implement to get my desired effect. Can anybody help me out here?
When using MVC you normally have Razor Views (.cshtml).
These come in 4 flavours:
Full Views
Partial Views
EditorTemplates
DisplayTemplates
From your question, I think, you want EditorTemplates.
Create a new View in Views/Shared/EditorTemplates and name it YourGenericModel.cshtml
Inside this file write the first line:
#model YourGenericModel
You can now specify what should be rendered using the normal Razor syntax.
To Have your model displayed using your new View simply call
#Html.EditorFor(model => model.yourGenericModelInstance)
Related
I was wondering if it is possible to modify a view HTML before sending it to the browser.
I wanted to create a custom tag compiler where i can insert a simple tag as <my-parsing-tag></my-parsing-tag> on the view and replace it for some specific HTML.
I'm already using OnActionExecuting and OnActionExecuted filters to execute some actions on the context (Change ViewBags, View names, Sessions, etc.), i also tried to do it there but i couldn't find the correct place to get the HTML, well i don't even know if it's possible to do so.
Is it possible or i would need to store my views HTML on the database to accomplish what i need ?
EDIT
As #Juan asked, why i need it:
I'm working with a call to action system where the user can place some specific modal campaigns on the page he wants just using those simple tags or selecting the page that will display it.
After that i will append the selected HTML to the view before sending it to the user. This system is intended for users that can't work editing the views since they don't work with HTML.
EDIT 2
After some research i have tried to implement a custom RazorView, the code is here with the Index View HTML, but now i have two problems:
The first one is that my Index View has some HTML that is coming from the database and is placed there using vars on my ViewModel and instead of the call to action HTML being placed at the end of my Index View, it's being placed before the ViewModel vars. The second problem is that the HTML is being duplicated instead of replaced. Here is an image of how the result looks like:
http://imgur.com/a/elul1
You could use an HtmlHelper extension for this:
http://tech.trailmax.info/2012/08/creating-custom-html-helper-in-mvc3/
I would suggest the following:
Define a container in your template (layout most likely) that will receive any content the user decides to "drop" into it via the admin panel.
You let the view know there is something to display via the ViewBag.
The view uses information you passed in order to render the desired content.
How it renders is where the HTMLHelper extensions come in. You could create an extension method which renders partial views based on the information you pass to it or maybe a set of extension methods that you call selectively based on the desired widget.
I have 3 screens that share a section(with model data in it(#Html.TextBoxFor)). What is the best way to implement this screens?
What I tried:
1) Partial view for the common section(_ClientData). 3 views for the different screens. 3 view models that have common property(ClientData), that is the view model of the partial.
Problem: If I pass the model to the partial as #{Html.RenderPartial("_ClientData", Model.ClientData);} the data from the partial is not submited to the model.
If I pass the model to the partial as #{Html.RenderPartial("_ClientData", Model);} and reference the properties with a fill name the data is submited, but I can't pass models with different types to the partial view.
2) Use one big View model with all the data required by the 3 screens, one view and show/hide some elements depending on some flag.
Problem: I can't use ValidationAttributes(for example if one field is required in screen 1, but it's not shown in screen 2 and its value is null, the validation will fire). I can use some manual validation in the controller but the whole thing with the all in one view and viewmodel sounds very bad.
Partials are usually not the best choice in case you want to place them inside one form and submit together. In such scenario it is better to take advantage of EditorTemplates which will solve your problem.
Firstly you would have to drag your partials to the folder ~/Shared/EditorTemplates/ and rename them to match the model name.
Then you can call them in your view like this:
Html.EditorFor(model => model.ClientData)
Thanks to this your HTML code (the name attributes to be precise) will be generated in such a way that your default model binder will be able to bind this part of your view as well.
I have created a model with Name, Email, Phone no properties and also created views for create, edit, delete and index. All these are working fine.
Now I have added a property in model like Address. Now I want that, is there any method so that, after adding the property in model, the newly added property automatic add in all the respective views.
Can we do this?
There is a way but only applicable if the view is generated by using HTML helper classes. The view should be strongly typed.
#Html.EditorForModel()
This HTML helper will automatically update and genatrate required input fields but with this you might have limited flexibility.
Other way can be creating your own class that renders html page.
Use as below in your view. View should be strongly typed of the model you want to use:
#using(html.BeginForm()){
#Html.EditorForModel()
}
I have a component that deals with uploading images, it works fine when in its own form it is a view bound to a view model, mapped to the main model in the controller, and similarly I have a standard view that is bound to a simple view model, and then mapped to the main model and saved.
So, both of these work fine as separate pages, however, I am keen to present them to the user in the same page - and I am completely stuck.
I have two different View Models required for this one page and just not sure how to go forward, and how to combine them.
I have tried making a new Viewmodel which basically contains the two other View Models, but when either of the forms are submitted, ModelState.IsValid always returns false as some of the required data in other fields is not present.
By getting rid of ModelState.IsValid, the application works fine, but as a MVC newbie, I feel a bit uneasy with this and just wondering if anyone can help me?
(And if this does require a new ViewModel with a ViewModel for each form, Bonus points if you can tell me a good naming convention as the few I have tried just look really messy!)
You could try using Partial Views.
<div>
#Html.Partial("FormA")
</div>
<div>
#Html.Partial("FormB")
</div>
Then in FormA.cshtml, you'll have:
#model Namespace.FormAViewModel
<form> </form>
And then similar for FormB
If I have a fairly crud-based area of my app, do I really have to create separate "Create" and "Edit" views? The HTML will be practically the same. I want an "Edit" and "Create" action to both render a "Show.aspx" view, but certainly Resharper 5 is complaining about there being no "Show" action.
What's the best practice?
There are alternatives. Basically off the top of my head you have three options.
You could either make a user control and have very lightweight edit and create pages.
If you are using ASP.MVC 2 you can capture the layouts as attributes on your view model and use the new template helpers DisplayFor and in your edit / create case EditorFor / EditorForModel.
You can specify a view name on the call to View from your controller action.
You don't "have" to do anything. MVC is based on conventions, which are valuable, but these are not technically required. In your case, I think it's more important to avoid redundant code.
You might consider having only an "Update" action and an Update.aspx view (form) to go with it.
Use the same form for both creating and updating. The only difference is, when creating, the form won't have an object ID.
After submitting, if the Update action sees an ID, it loads the object. If not, it instantiates a new one. Then just update the properties from the form, and commit (save).
So, one action and one view. Less code and it keeps convention.
You can specify which view you want the controller method to use, so there is no strict requirement for having two different views.
If your Add and Edit views look exactly the same, but you want to make it clear to the user whether they are adding or editing, you can simply push a different title into the ViewData, and display it in the shared view.
You can also put views in the "shared" folder, or create .ASCX partials that can be shared.
Go for it. It makes perfect sense. View should always be set up for front-end developers convenience, as controllers can pass data to any view, without any extra effort. You shouldn't feel restricted to do something, just because ReSharper says so.