How to fill IEnumerable<T> after HttpPost request mvc 3? - c#

i want to make a form using below code i developed Model for View :

Please read the following blog post to better understand how the model binding works for collections and how your input fields should be named: http://www.hanselman.com/blog/ASPNETWireFormatForModelBindingToArraysListsCollectionsDictionaries.aspx
OK, now let's get rid of this foreach loop and use editor templates, shall we?
<table style="width:65%; vertical-align:top" id="sample">
<%= Html.EditorFor(x => x.Properties) %>
</table>
and now define an editor template that will automatically be rendered for each element of the properties collection (~/Views/Shared/EditorTemplates/PropertyModel.ascx):
<%# Control
Language="C#"
AutoEventWireup="true"
Inherits="System.Web.Mvc.ViewUserControl<PropertyModel>"
%>
<tr>
<td>
<%= Html.LabelFor(x => x.ParameterName) %>
</td>
<td>:</td>
<td>
<%= Html.TextBoxFor(x => x.ParameterName) %>
</td>
</tr>
As far as those radio buttons are concerned, there's something wrong in your design about them. They are not part of the collection model but part of the main view model and yet you are putting them inside the foreach loop that is rendered for each element of the collection property. You might need to rethink what you are trying to do here.

Related

MVC 5: ASPX and Razor View Engine in Visual Studio 2013 Update 4

I am still learning and today I came to a point when I don't understand why something that should work, actually doesn't.
My sample project, I wanted to test both aspx and razor engine so i created razor view which works like a charm and now it turned out that there is no way for me to add ASPX View to my project and make it work:
(I want to make it work in MVC 5 not MVC 4)
There is no option for me to create strongly typed view using ASPX engine at all:
When I create it manually:
Add .aspx file to Views folder like this:
And put the code that would be generated if I was using MVC 4:
<%# Page Language="C#" Inherits="System.Web.Mvc.ViewPage<IEnumerable<MVCDemo.Models.Employee>>" %>
<html>
<head runat="server">
<meta name="viewport" content="width=device-width" />
<title>List</title>
</head>
<body style="font-family:Arial">
<p>
<% Html.ActionLink("Create New", "Create") %>
</p>
<table class="table" border="1">
<tr>
<th>
<% Html.DisplayNameFor(model => model.Name) %>
</th>
<th>
<% Html.DisplayNameFor(model => model.Gender) %>
</th>
<th>
<% Html.DisplayNameFor(model => model.City) %>
</th>
<th>
<% Html.DisplayNameFor(model => model.Department.Name) %>
</th>
<th></th>
</tr>
<% foreach (var item in Model) { %>
<tr>
<td>
<% Html.DisplayFor(modelItem => item.Name) %>
</td>
<td>
<% Html.DisplayFor(modelItem => item.Gender) %>
</td>
<td>
<% Html.DisplayFor(modelItem => item.City) %>
</td>
<td>
<% Html.DisplayFor(modelItem => item.Department.Name) %>
</td>
<td>
<% Html.ActionLink("Edit", "Edit", new { id = item.Id }) %> |
<% Html.ActionLink("Details", "Details", new { id = item.Id }) %> |
<% Html.ActionLink("Delete", "Delete", new { id = item.Id }) %>
</td>
</tr>
<% } %>
</table>
</body>
</html>
and the View is accessed like this:
public ActionResult Index()
{
var employees = db.Employees.Include(e => e.Department);
return View("List", employees.ToList());
}
I am getting error, which means basically:
TRANSLATION:
*Server error in Application: '/MVCDemo'.
Description: An error occurred during the parsing of a resource required to service this request. Please review the following specific parse error details and modify your source file appropriately.
Could not load type: 'System.Web.Mvc.ViewPage>'.
Source error:*
I tried as well to use this package from nuget, but to be honest I can't find any documentation about it.
=== ADDITIONAL INFO: ===
System.Web.MVC is present
Exactly the same application with Razor View works perfectly fine
I would be really grateful for your help guys.
=== SOLUTION IN CASE SOMEONE HAS SIMILAR PROBLEM ===
So, I managed figure it out, however there is still problem that Visual Studio for new projects support only razor. I wanted to try sth else, Spark for example. But it seems I cannot even import it anymore for MVC 5, I can do it only for MVC 4 project. And creating custom project template would require massive ammount of work I suppose to make it all work together.
Anyway, solution for curious ones:
I had to add this to my main web.config file, to system.web section
Alternatively add this, to my .aspx View (on the very beginning):
<%# Import Namespace="System.Web.Mvc.Html"%>
I had to add this, to my web.config file in 'Views' directory (to system.web section):
Finally in the ASPX View, I had to add ":", like this:
And thank you all so much for quick replies, I really appreciate your help guys.

ASP.NET MVC Riddle

Explain how this could print out two different values:
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IList<Models.AModel>>" %>
<%
int i = -1;
foreach (var m in AModel){
i++;
%>
<td><%= Html.TextBox(string.Format("[{0}].TheName", i), m.TheName) %> <%= m.TheName %></td>
<% } %>
For example, if theList contains three elements {TheName: "A"} and {TheName: "B"} and {TheName: "C"}, it will print:
<td><input name="[0].TheName" type="text" value="A">B</td>
<td><input name="[1].TheName" type="text" value="B">C</td>
<td><input name="[2].TheName" type="text" value="C">A</td>
Totally baffled.
I'll give votes for guesses and answer to the best guess, even if it's not the answer. To start out:
-TheName does not have any special code in the getter.
EDIT: Clarified the question with better examples (as I've discovered them), polished up the code to match suggestions. Still have the problem. As you can see, it appears the two lists are somehow out of order.
Is this a partial dump of the code? There are a number of oddities:
You're using <%: with Html.TextBox, which doesn't make sense. <%: HTML-encodes output, so it doesn't make sense that you'd be using it to print a TextBox.
You've got a closing </td> tag in your loop, but no opening <td> tag.
Update:
After your edit, it just looks to me like your list/enumerable must be doing something bizarre (or your posted output isn't the actual output) You should show us how you're populating your model.
This code is not correct at all. Jacob has mentioned some of em.
Even if you are sure this code works then i think it has something to do with List item being bound to view and something happens that shows next value...

MVC, view displaying data

Hey, I am new to asp and I would like to ask you for some help. I built store with MvcMusicStore tutorial help. Now I want to add a View to manage orders which will display just OrderID (in Index View), then more info in Details View. Info will come from table which looks like this:
When I list OrderID, its multiplying because each product creates new record with the same OrderID in the table. Is there any way to display each Id just once?
Then I tried to display more info in Detaild View but I failed again. I used this code in Controller:
public ActionResult Details(int id)
{
var orderdetail = storeDB.OrderDetails.Single(a => a.Order.OrderId == id);
return View(orderdetail);
}
but obviously it wont work because only one element can be displayed. I also tried with foreach loop in Details.aspx but I was getting some IEnumerables-related error. Any advice is welcome, sorry for newbie question and bad English. Thank you.
Edit: Here is Controller's code for Index View (Product in my table equals Album in tutorial):
public ActionResult Index()
{
var manageorders = storeDB.OrderDetails
.Include("Product").Include("Order")
.ToList();
return View(manageorders);
}
And Details View code:
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/MasterPage.Master" Inherits="System.Web.Mvc.ViewPage<ss.Models.OrderDetail>" %>
Index
<div id="style3">manage orders</div>
<div id="style1">
<table>
<tr>
<th></th>
<th>
user
</th>
<th>
data
</th>
<th>
product
</th>
<th>
quantity
</th>
</tr>
<% foreach (var item in Model) { %>
<tr>
<td>
<%: Html.ActionLink("Edit", "Edit", new { id=item.Order.OrderId }) %> |
<%: Html.ActionLink("Details", "Delete", new { id=item.Order.OrderId })%>
</td>
<td>
<%: item.Order.Username %>
</td>
<td>
<%: item.Order.OrderDate %>
</td>
<td>
<%: item.Quantity %>
</td>
<td>
<%: item.Quantity %>
</td>
</tr>
<% } %>
<p>
<%: Html.ActionLink("Create New", "Create") %>
</p>
And error I am recieving:
Compiler Error Message: CS1579: foreach statement cannot operate on variables of type 'ss.Models.OrderDetail' because 'ss.Models.OrderDetail' does not contain a public definition for 'GetEnumerator'
Single() will throw an exception if there's more than 1 element in the sequence, so the error here is because each Order can have many OrderDetails (this is your IEnumerable-ish error). If you wanted to select the first match, when there could be many, use the First() method, which won't throw if there's more than one.
It depends really what your controller is working with - Orders or OrderDetails. This would be the difference between Orders/Details/1 and OrderDetails/Details/1, where the first would be focussing on the whole order and all of its details, and the second would be looking at one specific line.
If you wanted to work with the order - which it looks like you're going for - then you'd need a reference of some kind from the Order to its collection of OrderDetails. If you're using something like Entity Framework like in the MusicStore tutorial, then you'll get this collection as part of your entity model. You would pass the Order to the view, and could then access the OrderDetails collection in a for each or similar loop e.g.
public ActionResult details(int id)
{
Order viewModel = storeDb.Orders.Single(o => o.Id = id);
return View(viewModel);
}
This wouldn't throw if Id is the unique per order, because there is only a single match (not many). Your view could then have something like:
<ul>
<% foreach (OrderDetails od in Model.OrderDetails) { %>
<li><%: od.UnitPrice %> (Or whatever information you wanted to show) </li>
<% } %>
</ul>
I'm assuming you would be using a strongly typed view of type Order, otherwise you'd have to work with ViewData, but it looks from your question like you're happy enough with those concepts already.
Edit - adding more...
1.The typing of your page is causing you some problems, make sure you are clear in your own mind exactly what your Model is. If you are passing in a list - like you would in an Index action - you need a page that inherits ViewPage> (you can see this in the <%# Page %> declaration at the top of the page). If you're going to write code like "for each... in model", that would imply that your model must contain more than one thing. This is where your "GetEnumerator" error message is from.
Your view as posted inherits ViewPage, i.e. the model is a single object, not a collection of objects, and so "for each ... in model" has no sensible meaning. The type of your View should be the same as the type being passed down by your controller. Your Index method passes a List, and List is an example of an IEnumerable. Your details however passes a single YourModelClass.
2.The error message "Compiler Error Message: CS1061: 'ss.Models.OrderDetail' does not contain a definition for 'OrderDetails'" - check your model, if there are relationships (foreign keys etc) between your tables, they should be joined on the model diagram, and you'd normally have navigation properties as well. The fact that you're getting this message means that something in that isn't there.
3.I'd suggest it might be worth checking out some of the videos, as the explanations are quite handy. Try some of the videos at http://www.asp.net/mvc/fundamentals . I Joe Stagner's "For the rest of us" series are very good, and as a starting point Stephen Walther's "Creating a Movie DB Application" would help, as it shows this kind of thing.

How do I display a datatable in asp.net mvc 2?

I am running a dynamically built SQL statement and putting the results in a datatable. I then need to display these results as a table in a partial view. I would normally create a List<> object and strongly type it to the page, but in this case I do not know what the final sql will be, since it is built by the user at run time.
So, how can I display the data in a datatable when I do not know what is in it? Also is there a better way to do this than in a datatable?
Thanks
As you are displaying tablular data, you should use an html table to do the job. Dismissile's answer only displays one column of the table. The more generic answer can be found in the following SO question:
Displaying standard DataTables in MVC
The bit that concerns you is, with the model strongly typed as a DataTable:
<table border="1">
<thead>
<tr>
<%foreach (System.Data.DataColumn col in Model.Columns) { %>
<th><%: col.Caption %></th>
<%} %>
</tr>
</thead>
<tbody>
<% foreach(System.Data.DataRow row in Model.Rows) { %>
<tr>
<% foreach (var cell in row.ItemArray) {%>
<td><%: cell.ToString() %></td>
<%} %>
</tr>
<%} %>
</tbody>
</table>
EDIT
Edited to encode the content of the datable. As using mvc 2 (according to the tag), then Html.Encode not required, just the <%: notation that is available in mvc 2.

Display data tables grouped and separated by headings on an MVC view

I'm a complete C# AND MVC noob, so this one's been a bitter struggle for me.
I've done a horrible but ultimately successful job of building a website for work to display the results of the impending primary/local elections.
What I need in the final view of my site is to display all the results of races in the same category. For example, there are three city commission positions open, and I need results for all three races on one page. I can display all the results I want, filtered by category, and in the pretty css table, what I can't seem to figure out is how I split that table up with sub headings for each of the individual races.
The data is direct Linq to SQL and comes out of a single view on the server (repositories are a thing that will have to happen in my next project unless they are essential to this function).
I'm not quite sure if this is what you are after, do let me know and I'll try to help.
This won't work directly for you, but hopefully might point you in the right way. I'm currently using a custom view model to hold this data, which I'm actually thinking of moving away from as my system is getting very complicated, but it might help you.
I can explain what that means if you need me to, (I was a noob just a year ago!)
I have assumed that you want races grouped by category.
<% foreach (var group in Model.GroupBy(item => item.categoryId)) Gives you the inital sort
{ %>
<% foreach (var item in group.Take(1))
{ //Category %>
<%=Html.Encode(item.CategoryName) %>
<% } %>
<% foreach (var item in group)
{ //Indervidual races%>
<%=Html.Encode(item.raceResult) %>
<% } %>
<% foreach (var item in group.Take(1))
{ %>
<!-- Area which happens after each category grouping -->
<% } %>
<% } %>
THANK YOU!! That was precisely the information I was looking for. Model.groupby was the break through for me.
Here's the code I used in the final FWIW:
<%
foreach (var group in Model.GroupBy(item => item.contestNumber))
{
foreach (var item in group.Take(1))
{
%>
<table width="600">
<tr>
<th>
<%: item.txtContest %>
</th>
<th width="40"></th>
</tr>
<%
foreach (var result in group)
{
%>
<tr>
<td>
<%: result.Candidate %>
</td>
<td>
<%: result.voteTotal %>
</td>
</tr>
<%
}
%>
</table>
<br />
<br />
<br />
<%
}
}
%>

Categories

Resources