I have a view model ViewModel1 that has all of the proerties for my view.
In my view I need 2 text boxes that will be used in a AJAX call to another action that has different parameters then the view I'm currently on.
Here's what I'd like the code to look like:
#using(Ajax.BeginForm("AjaxAction", "Home", new { TestId = Model.TestId }, new BOHAjaxOptions(), new { id = "newform", name = "newform" }))
{
#Html.TextBoxFor<DIFFERENT VIEW MODEL>(model => model.FIELD1)
#Html.TextBoxFor<DIFFERENT VIEW MODEL>(model => model.FIELD2)
Submit
}
I figured this would make sense since I want to be able to use the "AjaxAction" action on different views from different controllers since this action is going to be called from multiple parts on the site.
Or am I just not seeing the right picture here? Should I just include FIELD1 and FIELD2 in all of the ViewModels that need to call this AJAX action?
You should include all the data needed for the view in the view model, including data that might be posted back to another action as a separate model. Note that generally there isn't a one-to-one correspondence between a entity model and a view model. In nearly all cases my view models include either more or less data that the primary entity that the view is focused on.
Related
Imagine A MVC view that contains a grid:
#{
Html.Grid(
autoGenerateColumn: false,
Url : "/Grid/GetData",
columnBuilderAction: p =>
{
p.Add(c => c.Name, "100");
p.Add(c => c.Code, "100").AlignCenter();
}
);
}
The URL specify the action that returns a json array contains data for filling the grid.
Obviously "/Grid/GetData" should returns only Name and Code property of person, but person have more properties.
It is violation of DRY if we specified this properties in GetData action
It will take more traffic if we pass this properties from client (with Ajax request of grid) to action
It is not beautiful (in my opinion!) if this properties define in controller, pass with ViewData to grid and shared with GetData action
Is ther any best practices or suitable practices!
In the controller is where you define what view to show (or in your case the information to be passed to the view).
In this case... you have a controller Persons, and a Index action. In the Index view... you setup your grid.
So... for me is perfectly fine to provide a sub set of Person properties, just for the view. Remember that you are supposed to send VIEWMODELS to views, not domain models. So, in this case... if you just need Name and Code... you can create a QuickPerson class with those properties... and in you database query do:
.Select(x => new QuickPerson(){ Code = x.Code, Name = x.Name})
Not sure if the columnBuilderAction can detect the properies automatically to avoid this.
What happend if you don't set the columnBuilder? If it uses all the public properties of the model... then you just solved the issue, since your new QuickPerson model has just the needed ones.
I'm used to web forms, but am switching to MVC 5 and have a question about creating a multi step application form.
This form is like a wizard then will display information entered in each step at the end, then submit.
Is it easier to write this using html form in the .cshtml or do it all in the controller?
THank you
MVC, as its name suggests, has a Model, a View, and Controller. To create a form, you set up a class that will act as your Model, containing the properties that need to be worked with in a particular view. This is a different thing than your entity, the class that corresponds to a table in your database. You can sometimes use the entity as the Model, but especially in the case of a multi-step form, you don't want to persist the data until the end, which means, they'll need to be separate.
This brings us to the topic of view models, which is actually from another different pattern called MVVM. Regardless, your Model for these views will be a series of view models that contain just the information that the particular step needs to collect. At the end, you will piece all of the collected data together by creating an instance of your entity and mapping the property values from each view model over to it. Then, you will save the entity.
Now, as far as persisting the collected data between requests goes, that's where your session comes in. You'll merely add each posted view model into your Session object, and then at the end, fetch all of them from the Session object to create your entity.
So each POST action will have something like the following:
[HttpPost]
public ActionResult Step1(Step1ViewModel model)
{
if (ModelState.IsValid)
{
Session["Step1"] = model;
return RedirectToAction("Step2");
}
// errors
return View(model);
}
Then, your final POST action:
[HttpPost]
public ActionResult StepFinal(StepFinalViewModel)
{
if (ModelState.IsValid)
{
var myEntity = new MyEntity();
var step1 = Session['Step1'] as Step1ViewModel;
myEntity.SomeField = step1.SomeField;
// ... repeat for field in view model, then for each step
db.MyEntities.Add(myEntity);
db.SaveChanges();
Session.Remove('Step1');
// repeat for each step in session
return RedirectToAction("Success");
}
// errors
return View(model);
}
All of your form information will be in the .cshtml file like this:
#using (Html.BeginForm("Controller Action Method", "Controller Name", FormMethod.Post, new { id = "Form Name" }))
{
// Form Elements here
}
Then you can simply add a submit button that submits the form to your Controller for processing.
I'm using ASP.NET MVC 3. I have a question if it's possible to update the model, even if it's not being sent to the controller? Perhaps the question is completle of, or I'm doing things in a wrong way?
I have an ajax-call to a controller method. I'm passing in an id. I would like the controller to find some stuff in the db, and then update the model, passing it back to the view.
I've got a pretty big model... I've found some solutions, where to convert the model to a javascript object, and send it to the controller. Is that the only/right way?
How to send a model in jQuery $.ajax() post request to MVC controller method
I thought that maybe the controller has the model, where I could update some fields in it?
The call to the controller:
function getBis(id) {
$.ajax({
type: "GET",
url: '#Url.Action("GetBis")',
data: { "id": id },
dataType: 'json',
cache: false,
success: function (data) {
// Do something here
},
error: function (jqXHR, textStatus, errorThrown) {
alert("Problem!");
}
});
}
The controller code:
public ActionResult GetBis(string id)
{
BeslutIStortDTO viewModel = new BeslutIStortDTO();
int theId;
if (!Int32.TryParse(id, out theId))
throw new Exception("Wrong id");
viewModel = _blLayer.GetBIS(theId);
// somehow update the model here!
return View("index", viewModel);
}
usually you "pass the model" between JQuery and your controller when you need to "reflect" what ever is changed on your UI without doing any mapping(MVC is smart enough to construct a new object from the parameters you give it). In your case you said you just need to pass an ID to do some stuff on your model. So all you need to do is pass the ID as parameter, get it within the controller action and then do your stuff.
have a look at the below link
Pass a parameter to a controller using jquery ajax
First by updating the model, do you mean you want to update the record in the DB? That is not a good practice to do in a get request. If not read on..
Once you got your object with GetBis method, you can change all properties of it.
If you want to send this object to Javascript, use JSON Result.
return JSON(viewModel);
and one more thing, don't initialize view model in the first line of code, unnecessary object allocation.
The short answer is Yes and No, depending upon exactly what you mean, however you may want to reconsider your design. I would guess you are actually trying to render a Domain Entity to your view, rather than a View Model. This is a common newbie mistake.
One thing I would like to clarify is the difference between domain entities, and view models.
Domain entities are generally pulled from your persistence layer, and that is where your state changes should take place.
View models are temporary constructs, created on the server, just before a view is output as HTML, to be used as the data storehouse for the View template. It does not exist on the client's web browser after the request, and it no longer lives on the server after a request.
If you are using Ajax to perform some type of data change, instead of reloading the page, then what you would generally do, is make changes to the Domain object (via Id), rather than the View Model you originally passed in (which doesn't exist anymore).
For example.
I have a domain entity which is tied to a database record.
Person {long id=1;string name=bob;bool enabled=true}
I have a view model (that i map to bob in the initial get controller function)
PersonData {long id=1;string name ="bob", enabled=true}
To do this, in my initial page GET controller function, i pull up the Domain entity bob from the database, copy his data over to an instance of the view model, then pass the view model to the View("EditPerson",pd) action result, which goes through the razor view page and view model, and substitutes values into the HTML it is writing to the response stream, where appropriate.
Now, you have HTML on a client's web browser, that is IT. No view model exists. Now you have some Ajax which is browser side scripting, that says when I click a "Toggle Status" link for instance, what would happen is the browser (without changing pages) will submit a request to the ajax url you provided, passing in an Id of bob. Your controller function should then load the Entity version of Bob, and toggle the Entity version of Bob's enabled to an appropriate value, then persist that change to the database.
Nowhere at all does the original VIEW Model come into play, as it has not existed since the initial page was rendered to the browser.
Is there something specific you want to accomplish that you cannot see a way to do with this pattern?
I have a layout with an extension method that takes a list of menu items and creates HTML from that. In the controller actions I have:
public ActionResult Article(string rk)
{
Viewbag.menuItems = _menu.MenuItems("00");
..
return View(vm);
}
I have this repeated in many actions. Then in the _layout I have:
Html.NavLinks(ViewBag.menuItems)
I realize we're supposed to give the view what's needed but in this case would it be better if the view pulled partial details from an action? I'm asking this because I have only ONE layout that needs the data and I thought it may be better to code there rather than have the data retrieved in 20+ actions and sent to the views.
If it did a pull from the layout then would MVC cache the results of the action?
If pulling results from an action was better then how exactly could I do it?
If it did a pull from the layout then would MVC cache the results of the action?
It wouldn't cache the results of the action no, it would go and get them on every request.
If pulling results from an action was better then how exactly could I do it?
Instead of "pulling them from an action", just put them in the model that you are sending back from the controller, then you can use them in your view.
I have the following route in my MVC application:
/foobars/edit/{id}
The {id} in this case corresponds to the Id for my "Foobar" model.
In my Edit view I am doing the following:
#Html.Partial("~/Views/Notes/CreateNotePartial.cshtml", new CreateNoteViewModel())
The CreateNotePartial view uses a jQuery dialog and will POST to my NotesController using the following route:
/notes/create/{id}
The {id} in this case is NOT the same id as my Foobar id. My Foobar model has another property called UniqueId. I need to be able to pass this into my Partial view so that when I create the form to POST to the notes controller it passes in the right id. What is the best way to do this?
Right now I am doing the following:
// Foobar Edit View
#Html.Partial("~/Views/Notes/CreateNotePartial.cshtml", new CreateNoteViewModel(Model.UniqueId))
// Create Note Partial
#model CreateNoteModel
#using( Html.BeginForm("Create", "Notes", FormMethod.Post, new { id = Model.UniqueId }) ) {
}
Is there a better way to pass this to my partial view or is this the best way to do it?
Seems the best way to do it to me - I think your only other option is to pass it in ViewData, which everyone would tell you is not recommended for reasons of strong typing, magic strings, et al.
Certainly, it's the way that I do it (not that I'm the world's greatest authority of course).
From what it looks like, you're setting the form id to the model.UniqeId. That's just going to set the form's html element to whatever that model id is. I would not recommend doing that.
There's nothing wrong with using TempData (not the same as ViewData). TempData is made for passing a value from one view to another and then once it's accessed, it goes away. See this post for more.