0

I'm trying to create a status update page where I want a user to insert status message in Index page and also, I want to show all inserted all status messages in the same Index page.

This is my Model code:

public class Statuses
{
    [Key]
    public int StatusID { get; set; }
    [DataType(DataType.MultilineText)]
    [Required]
    public string message { get; set; }
}
public class StatusContext : DbContext
{
    public DbSet<Statuses> Status { get; set; }
}

And, I used

@Html.EditorFor(model => model.message)
in the Index.cshtml page.

To show the editor, I used the following model in View.

@model LearnStart.Models.Statuses

However, to show all the status messages below the Multiline TextArea, I think I'm supposed to use the below one.

@model IEnumerable<LearnStart.Models.Statuses>

How to use both model in same view so that I can display both the text area (to insert the status message) and to list all available status messages below it?

infused
  • 24,000
  • 13
  • 68
  • 78
Arjun
  • 16
  • 1
  • In your case you first you need to get the list of message so best way is you bind that message list in ViewBag and that ViewBag bind to textarea in view side. Let me know if you need some code for that. – Pragnesh Khalas Aug 30 '14 at 05:17

2 Answers2

2

First, you should not be passing your entities directly to your view. The recommended best practice is to use View Models, which are models tailored specifically to your view.

Second, when using a view model you can now do this, since it's not tied to your data model entities:

public class MyActionViewModel {
    public List<StatusesViewModel> StatusList {get;set;}
    public StatusesViewModel CreatedStatus {get;set}
}

Then in your view:

@model MyActionViewModel

@Html.EditorFor(x => x.CreatedStatus)

.............................................

@Html.DisplayFor(x => x.StatusList)

Then you can create two templates, an EditorTemplate and a DisplayTempate:

In ~/Views/Shared/EditorTemplates/StatusesViewModel.cshtml

@model StatusesViewModel

@using(Html.BeginForm()) {
    @Html.EditorFor(x => x.Message)
    <input type="submit" value="Create Status" />
}

In ~/Views/Shared/DisplayTemplates/StatusesViewModel.cshtml

@model StatusesViewModel

<div>
    <span>@Model.Message</span>
</div>

The thing that's nice about using the templates is that they will automatically iterate over your collection.. no foreach or for statement is used. A single EditorFor works on the entire collection, then renders the template based on the type, which in this case translates to StatusViewModel.cshtml

Erik Funkenbusch
  • 92,674
  • 28
  • 195
  • 291
  • I need to write the MyActionViewModel class separately in Model? If so, please see that I already have "Statuses" model. – Arjun Aug 30 '14 at 09:55
  • @Arjun, Create a separate folder in your project (say) `ViewModels` for `class MyActionViewModel` (and your other view models) with the relevant `using` statements. As Erik has said, using a view model is the recommended approach. The [answers here](http://stackoverflow.com/questions/11064316/what-is-viewmodel-in-mvc) may help to understand the benefits. –  Aug 30 '14 at 12:47
  • @Arjun - Yes, I know you alrady have a Statuses model. But, this is your data entity, and it is not considered best practice to use this model directly in your view. You should create a View Model version for use in your view. Yes, it's more work, but it's also more maintainable and doesn't cause as many problems with your data model. – Erik Funkenbusch Aug 30 '14 at 21:23
-1

Easy way is to put a list inside Viewbag and show list in View as shown :-

Controller :

Public Actionresult Myaction()
{
   .........
   Viewbag.data = //bind list of messages here
   return View();
}

View :

@model LearnStart.Models.Statuses
.........
.........
.........
@if(Viewbag.data != null){
 <table>
 @foreach(var item in Viewbag.data)
  {
    <tr><td>@item.message</td></tr>
  }
 </table>
}
Kartikeya Khosla
  • 18,743
  • 8
  • 43
  • 69
  • You are advising him to modify his entity to include a self-referencing navigational property. Apart from the fact that this makes no sense in his data model, it has repercussions in the rest of his code, all for functionality that is related to the display of data in the view. There is no relationship between statuses. This is terrible advice. – Erik Funkenbusch Aug 30 '14 at 07:07
  • @ErikFunkenbusch..then in that case i gave him another alternative as well..and moreover a answer deserves downvote if its wrong ..and above answer is not wrong.. – Kartikeya Khosla Aug 30 '14 at 07:10
  • Answers deserve downvoting if they are bad. You're advising him to nuke his data model and mess it up. That deserves downvoting. – Erik Funkenbusch Aug 30 '14 at 07:11
  • @ErikFunkenbusch...well that is your opinion...in my opinion both answers are correct and will work..thanks.. – Kartikeya Khosla Aug 30 '14 at 07:13
  • @Exception After doing what you said, I'm getting NullReferenceException at foreach part in View. Look at my Controller code for correction. public ActionResult Index() { Statuses obj = new Statuses(); obj.statlst = db.Status.ToList(); return View(obj); } – Arjun Aug 30 '14 at 09:37
  • @Arjun...see updated answer..apply condition not null as shown above – Kartikeya Khosla Aug 30 '14 at 09:41
  • @Exception Same exception error but here: Line 19: @if(Model.statlst != null){ – Arjun Aug 30 '14 at 09:53
  • @Arjun...no you are doing it wrong..for your requirement my second answer will be best..just try that... – Kartikeya Khosla Aug 30 '14 at 09:56
  • @Exception In the second method, I don't receive any error but doesn't display all the Status messages that I insert. Form just gets submitted and does nothing. – Arjun Aug 30 '14 at 10:06
  • @Arjun...then there must be problem when you are getting data in viewbag just put a breakpoint and see if there are rows inside viewbag – Kartikeya Khosla Aug 30 '14 at 10:07
  • @Exception Is this the correct way? public ActionResult Index() { ViewBag.data = db.Status.ToList(); return View(db.Status.ToList()); } – Arjun Aug 30 '14 at 10:28
  • There's absolutely no reason you should be providing your view with data using ViewBag instead of a model. That's just plain sloppy. – The Muffin Man Aug 31 '14 at 03:37