multiple table in a view in ASP.NET mvc (with visual basic) - asp.net

I made Index view by ADO.NET(model), MVC 5 controller use Entity Framework with views(controller).
It is so easy way. but I got a problem when I try make two table (in a view).
How can I show two tables in one view.
I wanna reference multiple models. But I can refer just one model as below
(in view)
#ModelType IEnumerable(Of Ora_Connect.UsersData)
please advise
This is made by Visual Basic
added comment
Hello again.
could you advice for me.
I transf from C# to VB. So, I made masterview for multi table.
I tried about 3days. but not solved yet
thank you so much.
model
Public Class TestMulti_ViewModel
Public Property Test1 As IEnumerable(Of SCT_AUTH_OUT)
Public Property Test2 As IEnumerable(Of SCT_AUTH_OUT_ADD)
control
Namespace Controllers
Public Class TestMultiController
Inherits Controller
'Private db1 As New TestMulti_Entities1
' GET: TestMulti
Function Index_Test(ByVal searchString As String) As ActionResult
Dim mview = New TestMulti_ViewModel
Return View(mview.Test1.ToList())
End Function
End Class
#Modeltype IEnumerable(Of TestMulti_ViewModel)
View
#Modeltype IEnumerable(Of TestMulti_ViewModel)
<table class="table">
#Code Dim item As SCT_AUTH_OUT End Code
<tr>
<th>
#Html.DisplayNameFor(Function(model As SCT_AUTH_OUT) model.ID)
</th>
<th>
#Html.DisplayNameFor(Function(model As SCT_AUTH_OUT) model.PASS)
</th>
<th>
#Html.DisplayNameFor(Function(model As SCT_AUTH_OUT) model.NAMEK)
</th>
<th></th>
</tr>
#code Dim mview = New TestMulti_ViewModel().Test1 end code
#For Each item In mview
#<tr>
<td>
#Html.DisplayFor(Function(model As SCT_AUTH_OUT) item.ID)
</td>
<td>
#Html.DisplayFor(Function(model As SCT_AUTH_OUT) item.PASS)
</td>
<td>
#Html.DisplayFor(Function(modelItem As SCT_AUTH_OUT) item.NAMEK)
</td>
<td>
</td>
</tr>
Next
</table>

Related

Why is my statically typed partial view trying to render an unintended model type?

I have a partial view, in my ASP.NET MVC4 web app. It's just a partial view designed to display a table, given a collection of entities. It looks like this:
#model ICollection<Portal.Models.Matter>
<table class="table table-striped table-bordered table-hover">
<thead>
<tr>
<th>Name</th>
<th>Last Accessed</th>
<th>Client</th>
</tr>
</thead>
<tbody>
#if (Model.Count > 0)
{
#Html.DisplayForModel()
}
else
{
<tr>
<td colspan="3" class="text-muted text-centered">There are no Matters to display.</td>
</tr>
}
</tbody>
</table>
I have a DisplayTemplate for Matter that is statically typed to the single Matter entity, and it handles rendering of each table row.
For some reason, when this partial is rendered, instead of using the Matter DisplayTemplate it just shows the following:
System.Collections.Generic.List`1[Portal.Models.Account]System.Collections.Generic.List`1[Portal.Models.Account]
Now, this partial is not even bound to a collection of Account entities. It's bound to a collection of Matter entities. So, why is #Html.DisplayForModel() trying to display for a collection of Accounts? At run time, using a debugger, I can see the Model is in fact a collection of Matter entities, not Account.
I render this partial using the following code:
#Html.Partial("~/Views/Matter/_Table.cshtml", Model.Client.Matters, new ViewDataDictionary())
I found a work around, or maybe a solution, not sure. Anyway, instead of using DisplayForModel on an ICollection, I iterate over the collection and use DisplayFor on each element.
For example ...
#model ICollection<Foo>
for (var item in Model)
{
#Html.DisplayFor(m => item)
}
I guess nothing is forcing you to use a property off of m in DisplayFor.

Code still loads content on new page

Hi I have problem with my MVC application.
I would like click on ActionLink > load data from server > and insert data to div in same page.
But my code still loads content on new page and I don`t have idea why. Anybody to help me ?
This is my Index.cshtml in HomeController,
#model IEnumerable<Kango_kmen.KangoKmenWS.WSEntityInfo>
#Content.Script("jquery-1.9.1.min.js", Url)
#Content.Script("jquery.unobtrusive-ajax.min.js",Url)
#Content.Script("jquery.unobtrusive-ajax.js",Url)
#Content.Script("myScript.js",Url)
#section Entities{
<table>
<tr>
<th>
<input type="submit" value="zobrazit" />
</th>
<th>
iD
</th>
<th>
name
</th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Ajax.ActionLink("..", "CheckEntity", new { id = item.iD },
new AjaxOptions{ UpdateTargetId="properties",
HttpMethod="GET",
InsertionMode=InsertionMode.InsertAfter,
})
</td>
<td>
#Html.DisplayFor(modelItem => item.iD)
</td>
<td>
#Html.DisplayFor(modelItem => item.name)
</td>
</tr>
<tr>
<td>
<div id="properties">
</div>
</td>
</tr>
}
</table>
}
#section PropertyInfo{
<p>Property info</p>
}
#section Properties{
<p>properties</p>
}
And here is my Controller in HomeController
public PartialViewResult CheckEntity(int id)
{
var model = WSConnect.getEntityInfo(id);
if(model !=null){
return PartialView("CheckEntity", model.property);
}
var modell = new WSEntityInfo[0];
return PartialView("CheckEntity", modell);
}
and ChecktEntity is the Partial view but everytime I click on ActionLink controller load url: /Home/ChceckEntity/1000 for exmaple on view data on this new page "(
There are 2 things wrong with your code:
You have included the jquery.unobtrusive-ajax.js script twice, once the minified version and once the standard version. You should include it only once
The jquery.unobtrusive-ajax.js is not compatible with jquery 1.9.1 because one of the breaking changes in jQuery 1.9 is that the .live() method was removed and the jquery.unobtrusive-ajax.js script relies on it. If you look at your javascript console you would see the following error: The .live method is undefined.. So if you want to use the unobtrusive AJAX functionality in ASP.NET MVC you will have to downgrade the version of jQuery. For example the 1.8.3 version should be fine.
So:
#model IEnumerable<Kango_kmen.KangoKmenWS.WSEntityInfo>
#Content.Script("jquery-1.8.3.min.js", Url)
#Content.Script("jquery.unobtrusive-ajax.min.js", Url)
#Content.Script("myScript.js", Url)
Also please learn how to debug your javascript code. Use a tool such as FireBug or Chrome developer toolbar where all those errors will be shown.

Persisting session data to child views MVC 3

So I'm working on an MVC 3 project that pulls from multiple (10) tables from a legacy data source to a Master View with 6 partials. There is one table that has data on every child view, so we decided to store that in session data and then populate the rest of the child views with whatever other data is needed.
When we originally tried to do this, we were getting null reference exceptions to the session data. I've come up with a solution, but it seems very clunky and I don't think it's best practices/introducing unnecessary state.
Relevant code to follow:
This is what we have on the main controller:
public ActionResult PolicyView(string PolicyID)
{
IPolicyHolder phdata = new PolicyHolderData();
Polmast policy = phdata.GetPolicyFromUV(PolicyID);
ViewBag.FullName = policy.FULLNAME;
ViewBag.PolicyID = PolicyID;
Session["polmast"] = policy;
return View("PolicyView");
}
And then in our main view, one of the links to the partial child views:
<div id="Billing">
#{ Html.RenderAction("Billing", Session["polmast"] ); }
</div>
In the child controller:
public ActionResult Billing(object sessiondata)
{
return PartialView("_Billing", sessiondata);
}
And in the child view:
#{var polmast = (Polmast)Session["polmast"];}
**snip**
<table id="premiumsgrid" class="display" border="1"
cellpadding="0" cellspacing="0" width="50%">
<thead>
<tr>
<th>Annual</th>
<th>Semi-Annual</th>
<th>Quarterly</th>
<th>Monthly</th>
</tr>
</thead>
<tbody>
<tr>
<td>#polmast.PAN</td>
<td>#polmast.PSA</td>
<td>#polmast.PQT</td>
<td>#polmast.PMO</td>
</tr>
</tbody>
</table>
I would recommend starting to use models and returning those to your views instead of passing around the session object and casting it within your view. It would make this code much more clean.
This is how I would structure my code:
public ActionResult PolicyView(string PolicyID)
{
IPolicyHolder phdata = new PolicyHolderData();
Polmast policy = phdata.GetPolicyFromUV(PolicyID);
PolicyModel model = new PoliceModel() {
FullName = policy.FULLNAME,
PolicyID = PolicyID
//Populate other properties here.
};
Session["polmast"] = policy;
return View("PolicyView", model);
}
Then I would set up your main view (there's no need to wrap this call in curly braces and you shouldn't need to pass any route values):
<div id="Billing">
#Html.RenderAction("Billing")
</div>
The child controller:
public ActionResult Billing()
{
//Get the data out of session; it should already exist since your parent controller took care of it.
var policyData = (Polmast)Session["polmast"];
PolicyModel model = new PoliceModel() {
FullName = policy.FULLNAME,
PolicyID = PolicyID
//Populate other properties here.
};
return PartialView("_Billing", model);
}
And your child view:
#model Polmast
snip
<table id="premiumsgrid" class="display" border="1"
cellpadding="0" cellspacing="0" width="50%">
<thead>
<tr>
<th>Annual</th>
<th>Semi-Annual</th>
<th>Quarterly</th>
<th>Monthly</th>
</tr>
</thead>
<tbody>
<tr>
<td>#Model.PAN</td>
<td>#Model.PSA</td>
<td>#Model.PQT</td>
<td>#Model.PMO</td>
</tr>
</tbody>
</table>

ASP.Net MVC EditorFor not working

I am trying to render a table, using EditorFor, and a partialview, I think.
I have a model with a List<> property defined like this:
public List<TransactionSplitLine> TransactionSplitLines { get; set; }
The idea is that a user selects a few drop downs and enters a value into an edit box, and clicks a button. The model goes back to the controller, and the controller adds the entered values to the List<>
[HttpPost]
public ActionResult AccountTransaction(AccountTransactionView model)
{
var reply = CreateModel(model);
if (model.CategoryIds != null)
{
foreach (var c in model.CategoryIds)
{
reply.TransactionSplitLines.Add(new TransactionSplitLine { Amount = "100", Category = "Test Category", SubCategory = "Test More", CategoryId = int.Parse(c) });
}
}
reply.TransactionSplitLines.Add(new TransactionSplitLine { Amount = "100", Category = "Test Category", SubCategory = "Test More", CategoryId = 1 });
return View("AccountTransaction", reply);
}
Ignore the CreateModel. It simply sets up some data. Also, I am hardcoding data. This will eventually come from some form values.
The model is then returned to the same screen, allowing the user to ender more data. Any items in the List<> are read and a Table is rendered. I also have to store the current listen item values in hidden fields, so that they can be submitted back, along with the new data entered, so that the list can grow each time the user adds data.
The view is defined like this:
<table width="600">
<thead>
<tr class="headerRow">
<td>
Category
</td>
<td>
Sub Category
</td>
<td>
Amount
</td>
</tr>
</thead>
<tbody>
<%=Html.EditorFor(m=>m.TransactionSplitLines) %>
</tbody>
</table>
This is my first attempt with EditorFor...
My View is in a folder 'Views/BankAccount/AccountTransaction.aspx
I have created a ascx in Views/Shared/TransactionSplitLines.ascx
The code for the ascx is like this:
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<BudgieMoneySite.Models.TransactionSplitLine>" %>
<tr>
<td>
<%=Model.Category %>
<%=Html.HiddenFor(x => x.CategoryId)%>
</td>
<td>
<%=Model.SubCategory %>
<%=Html.HiddenFor(x => x.SubCategoryId)%>
</td>
<td>
<%=Model.Amount %>
<%=Html.HiddenFor(x => x.AmountValue)%>
</td>
</tr>
This is data
The 'This is data' is just test stuff, which is never rendered.
When I run this, all that happens is that my output is rendered as:
<table width="600">
<thead>
<tr class="headerRow">
<td>
Category
</td>
<td>
Sub Category
</td>
<td>
Amount
</td>
</tr>
</thead>
<tbody>
Test Category
</tbody>
</table>
It seems like the ascx isn't being used? I'd expect to see the 'This is data' text. But, nothing. Hopefully you can see an obvious fault?
Your editor template should be either:
~/Views/Shared/EditorTemplates/TransactionSplitLine.ascx
or:
~/Views/BankAccount/EditorTemplates/TransactionSplitLine.ascx
The name of the ascx is always the type name of the collection item (TransactionSplitLine and not TransactionSplitLines) and it should be situated at ~/Views/Shared/EditorTemplates or ~Views/ControllerName/EditorTemplates.
Or if you want to use a custom editor template name:
<%= Html.EditorFor(m=>m.TransactionSplitLines, "~/Views/foo.ascx") %>
Or use UIHintAttribute on your model.

Nested grouping with Linq?

I am trying to create a "simple" timesheet application that is almost doing what I need it to do, I'm not sure it's the most efficient way of doing this, so please give me feedback if you have better ideas... I got help here at SO before (See Group items with Linq and display in table in MVC view where you can also see the database schema). Now I just need to be able to group at one more nested level.
What I get now is a sort of table layout looking sort of like this:
Project Task 1 2 3 (dates with hours in the cells)
ProjA Analysis 8 8 8
ProjB Analysis 8 7 8
(Etc)
Here's the property in the viewmodel that I use to populate the table(s):
public IEnumerable<IGrouping<Project, TimeSegment>> TimeSegmentsByProject
{
get
{
var projectGroups = from timeSegment in ts.TimeSegments
group timeSegment by timeSegment.Project
into projectGroup
select projectGroup;
return projectGroups.ToList();
}
}
And here's the code in the View:
<table>
<tr>
<th>
Projekt
</th>
<th>
Aktivitet
</th>
<th>
Timmar
</th>
</tr>
<% foreach (var item in Model.TimeSegmentsByProject)
{ %>
<tr>
<td>
<%:item.Key.Name %>
</td>
<td>
<table>
<% foreach (var i in item)
{ %>
<tr>
<td>
<%: i.Task.Name %>
</td>
</tr>
<% } %>
</table>
</td>
<td>
<table>
<% foreach (var i in item)
{ %>
<tr>
<% for (int index = 0; index < 30; index++)
{%>
<td width="20px">
<%if (i.Date.Substring(8) == index.ToString())
{ %>
<%: i.Hours %>
<% } %>
</td>
<% } %>
</tr>
<% } %>
</table>
</td>
</tr>
<% } %>
</table>
Now, the problem is that this works fine, but even though Project is grouped and only appears once for each project, task is repeated with a new row for the same task name. I want each task only once, just like for Project. But the linq group expressions and all that has already got me so confused so I have no idea how to get this done. I'm in a bit over my head here, I thought a timesheet application would'nt be such a hard thing (at least a basic one). But I'm fairly close to something that would do, if I could just get this task grouping to work so I don't get it repeated.
Any advice for how to change my code to do this would be appreciated! (And if you think I'm doing it wrong, please tell me how)
Here's a stab at it.
var projectGroups =
from timeSegment in ts.TimeSegments
group timeSegment by new //start off by grouping two properties
{
ProjectName = timeSegment.Project.Name,
TaskName = timeSegment.Task.Name
} into g
select new
{
Key = g.Key,
Values = //and finish off by turning each group into another query.
(
from ts in g
group ts by ts.Date.Substring(8)) into g2
select new {
indexValue = g2.Key,
Hours = g2.Sum(ts2 => ts2.Hours)
}
).ToList()
};
Now, just because I used anonymous types here, doesn't mean you need to. You can declare actual classes and use them to project into. Just be careful with the class that serves as the grouping key (it has ProjectName and TaskName) as you don't want to use reference equality...

Resources