ASP .NET MVC How to pass data between views - asp.net-mvc

I have this scenarion.
There are Boards. And Threads. Therads can be created only on boards, and for that they need to be provided with board ID, Name or something like that, to let SQL know where it should add thread.
By now I've been using hidden fields to pass data between views, but more I used them tehre was more trash in code like ViewBags, unnesseary attributes in methods etc.
Are there cleaner ways to do it ?

Pass the model back to the view.
so if you have a model called Data with a field called Name then;
Data fvm = new Data{ Name = "my name"};
return View(fvm)
then inherit the view from the model and use;
<%= Model.Name %> to get data.
Then as you move from view to view you pass the form back to the view with either ajax, jQuery submit plugin or a submit button which should also be the model.
then in your controller;
public actionresult myciew(Data model)
{
//do something with the model
}

Related

MVC model casting in partial view, f__AnonymousType6

Is it possible to cast a model going into a partial view?
#Html.Partial(Model.Partial, new { model =
((WarningPopupModel)CommonData.NotificationPopup.PopupModel) })
Here PopupModel is of type object but holds an instance of WarningPopupModel, when I try this is the error I get
Additional information: The model item passed into the dictionary is of type
'<>f__AnonymousType6`1[EmployeeKiosk.Models.WarningPopupModel]',
but this dictionary requires a model item of type
'EmployeeKiosk.Models.WarningPopupModel'.
So really I need to understand the 'f__AnonymousType6' part and know what kind of flexibility I have here
Background.
I want to create a popup in the view depending on some business logic, so ultimately the controller will pass back the name of the view (or it could be a token) together with some model.
In the view I just need some way of being able to switch between the partial views that appear, the partial views will be Kendo popups
thanks
Pretty sure that you should just be able to change it to;
#Html.Partial(Model.Partial, (WarningPopupModel)CommonData.NotificationPopup.PopupModel);
Without the new { model = ... } part.

ASP.NET MVC flow (how are the models created, populated and passed around)?

I've seen flow charts of the life-cycle but they never seem to answer this question OR I'm just not getting it.
So if user hits a registration page is it:
Routing engine chooses controller.
Controller checks to see which view should be displayed, checks to see if it is strongly typed and if so instantiates the correct model.
Calls the View, passing the empty model in.
I'm also interested in what happens when the form is filled out and submitted.
I'm not looking for anything super technical, just something conceptual...
Regardless of the user actions (followed the link, entered the URL, submitted the form) the basic flow of the MVC application is the following:
According to the routing table Controller's name and method (aka Action) that will handle the request are defined.
If there were any request parameters (values in form for example) they are associated with the Action's parameters.
Request context is generated (contains details about request, client, server, etc.)
Object of Controller's type is created, Action (method) of this object is called with given parameters.
After processing, Action returns an appropriate result, most likely View (could also be Json, plain text, anything).
View is rendered and send back to the client as a response.
Of course, a lot of details are left aside here, but this is the general conception.
Update: some words about models.
Models are used to pass data from the Controller to the View. There are two main approaches:
Using ViewData collection - basically a regular key-value dictionary. In Controller it is filled with data:
ViewData["SomeKey"] = "someValue"; //not only string, any object can be here
return View();
And in View values are retrieved by keys:
<%= ViewData["SomeKey"] %>
Strongly typed Views. A Model class that will contain necessary data is created. View is specified to be strongly typed with this class, and when Action returns a View object, it passes an instance of this class as a parameter. Here is some code example:
Model:
public class SomeModel
{
public string SomeKey { get; set; }
}
Controller:
SomeModel model = new SomeModel();
model.SomeKey = "someValue";
return View(model);
View:
<%# Page ... Inherits="System.Web.Mvc.ViewPage<SomeModel>" %>
...
<%= Model.SomeKey %>

Asp.net MVC, after using jeditable (Edit in place)

Ok, i can use jeditable to edit-in-place some content on a page and the content will be saved to a database. But whats the best way to re get that text-content from db to show into a place holder?
p id="paraNo34" class="editable"
-->What i will write here so that it will get content from a
db's table: [Content], where id=="paraNo34".
/p
The problem is if i will use some hard coded text like
p id="paraNo34" class="editable"
-->Some text here
/p
I will able to edit-in-place using jeditable but when i will refresh page it will show the same "Some text here" as its not getting data from db.
Your pseudocode implies that you want the view to be responsible for fetching the required data, which is an anti-pattern in MVC. You need to retrieve the text in your controllers action and pass it to the view, either using ViewData or a custom view model, e.g.:
public ActionResult Index(string id)
{
// call some method to fetch data from db
ViewData["ID"] = id;
ViewData["Content"] = content;
return View();
}
And the view looks something like:
<p id='<%= ViewData["ID"] %>' class="editable">
<%= Html.Encode(ViewData["Content"]) %>
</p>
A better approach would be to create a strong-typed view model (Stephen Walther has a blog post about view models here), but the above example should illustrate how data can be passed from the controller to the view.

Function in ASP.NET MVC

A function returns only one view.
what if I want to return multiple views in a function?
For example, I have this code:
Function Index() As ActionResult
Dim _news As DataTable = News.newsSelect()
Dim _announcement As DataTable = Announcement.SelectAnnouncement()
Return View()
End Function
I want to return _news and _announcement to be used in the aspx page. How would I do this?
Are you trying to show both sets at the same time? News and Announcements?
If so then why not implement either a PartialView or two PartialViews?
Then in your main view you can render them and pass the collection to the PartialViews?
There are heaps of samples on this and the one I recommend is in NerdDinner if you haven't already seen it.
I hope this helps. If you want sample code then let me know.
One simple way is just to have those two datasets sent in a ViewData element, which you can access in a field.
example:
ViewData["Elements"] = new SelectList(aElements, "Guid", "Name");
is consumed as:
<%= Html.DropDownList("Elements","Pick an element")%>
Also, I think that if you read between the lines of this blog post here you will find an elegant way of achieving what you want ;) but its a bit more involved..(only because you mentioned Views instead of just variables..
Quote:
We need to create our own implementation of IViewFactory. This
is responsible for locating and
creating an instance of an IView
(which both ViewPage and
ViewUserControl implement).
To “inject” (all you DI fans excuse me borrowing the term without
using a DI framework) our new View
Factory into every Controller we are
going to create our own
IControllerFactory implementation.
We need to configure the framework to use our new Controller
Factory.
Finally we can create two Views – an AJAX version and a pure
HTML version.
Building on that should be all you need
Good luck!
Ric
Assuming what you are trying to do is use both of those DataTables to populate some View, then my recommendation would be to create a wrapper object and then a strongly typed view based on this object.
The wrapper object would contain properties for all of the data elements that you need in order to render your view properly. In your case, it is 2 DataTable objects. I do not really know VB, so all my examples will be in C#. Here is an example of the data wrapper class...
public class IndexViewData
{
public DataTable News { get; set; }
public DataTable Announcement { get; set; }
}
You then might update the Index action in your controller as follows:
public ActionResult Index()
{
var viewData = new IndexViewData();
viewData.News = News.newsSelect();
viewData.Announcement = Announcement.SelectAnouncement();
return View(viewData);
}
Finally, you would need to create/update your view to be strongly typed. This is done by having your page inherit from the generic System.Web.Mvc.ViewPage<T> class. Just substitute the view data wrapper created earlier for T. To do this, you would set the inherits attribute of the <%# Page %> element. In your case, if we assume your root namespace is called "Foo", you might have the following page declaration in your Index.aspx view (added extra line breaks for readability):
<%# Page Title=""
Language="C#"
MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage<Foo.Models.MyModelType.IndexViewData>"
%>
Once you have a strongly typed view for your view data wrapper, you can access the wrapper object in your view using the Model property. Here is an example of something you could do in your Index.aspx view
<%-- Output some random data (bad example, for demonstration only) --%>
<%= Model.News[0]["title"] %><br/>
<%= Model.Anouncement[0]["body"] %>
In reality you're probably going to do something like iterate over each row of the data table. Regardless, once you create the strongly typed view, your model object, which was passed to the view in the Index method of the controller, is available in the Model property within the view.
You can find detailed tutorials at the ASP.NET MVC site

ASP.net MVC - How to persist model over various views

Situation: In some project management software written in asp.net I have a create project page (working fine). I need to add to this the ability to add tasks from a list of templates to this project pre-creation BUT the list of available tasks is dependent on some values sitting in the create form.
My abstract solution is this:
I have a "Create" view and an "Add Tasks" View - both strongly typed to a composite viewModel defined in the controller
My Create method checks which button was used to call it - if the
button was "Add Tasks" it then renders the AddTasks view, passing the model in from the create view, again all in the same controller.
The AddTasks View posts to the Create view with one of two buttons, one loads the view and the other causes an actually DB save.
My Problem is this:
The different views use different properties of the same model, but in passing this model between them, the data is reset (in any case reload or save).
I am guessing this is happening from auto binding of data - though I thought fields not present on the form would not overwrite existing model data passed down.
There is hardly any code in the controller manipulating the model at present - It is only passed from view to view in these cases.
This is the controller code:
// POST: /Project/Create/<viewModel>
[Authorize, AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create([Bind(Exclude = "Id,id")] ProjectViewModel model)
{
if (model.SubmitValue == "Create")
{
try
{
model.Project.Id = Guid.NewGuid();
model.Save(this.User.Identity.Name);
return this.RedirectToAction("Details", new {id = model.Project.Id});
}
catch (Exception e)
{
this.ModelState.AddModelError(e.ToString(), e.ToString());
}
return View(model);
}
if(model.SubmitValue == "AddTasks")
{
return this.View("AddTasks",model);
}
return this.View(model);
}
//POST: /Project/AddTasks/ + model
[Authorize, AcceptVerbs(HttpVerbs.Post)]
public ActionResult AddTasks([Bind(Include = SelectedCarrierTasks")]ProjectViewModel model)
{
return View(model);
}
The Question is: How do I maintain the state of the model across these views until it finally save it?
I would prefer to avoid any hackish (TempData) or JS dependant solutions, but I am not closed to these if they are really the best solution.
Thanks,
Adam Tolley
One simple solution is to persist the ViewModel object in a Session variable and bind the View from this source.I ts certainly not the most elegant solution. Another option, and probably less elegant one is persist this model data in the database, with some temporary/unsaved flag.
The problem is that when you display the add tasks view you're not providing fields for your "Project" object therefore the ModelState loses the data related to the project, you will need to provide this fields to ensure you're not loosing that data.
You don't need to display this fields they can be of type hidden and they will preserve the value. Just make sure that if you will be binding to a view model you will need to name this fields correctly like this Model.Project.Property.
Perhaps I am trying to solve the wrong problem (ala Bruce Eckel). I am going to try to move to a structure that needs this sort of fuzzy boundary less. I don't want to adopt a REST paradigm only to shoe-horn it into a stateful application.
Possibly these controls belong on the same page, and I can use some JQuery goodness to put in a tab pane for easiness on the eyes.
Thanks to those who answered, I found each useful and will try to remember to up-vote them as soon as I have some more rep.
I can't comment on other peoples questions at the moment, but the only real option is the session if you want to persist an objects state during web requests, or serializing it and placing it in a hidden field.
Or a final option would be to change the way your pages work so you can save the object after each request...
If your using nHibernate then you might want look into the Conversations pattern, but this just essentially saves the nHibernate session into the asp.net session anyway...

Resources