View Multiple Model that JOIN with FK through query from Controller - c#

Here is Controller Code
//Approved
public ActionResult Approved(String VoucherNIK, String Admin, int? month, int? Year, int? minPrice, int? maxPrice)
{
if (Session["Nama_Lengkap"] != null)
{
var NIKLst = new List<int>();
var NIKQry = from d in db.Voucher
where d.Voucher_Number >= 2000
orderby d.NIK
select d.NIK;
var query = from app in db.Approved
join det in db.Detail on app.ID_Approved equals det.ID_Approve
join vou in db.Voucher on det.ID_Voucher equals vou.ID_Voucher
join adm in db.Admin on app.ID_Admin equals adm.ID_Admin
select new
{
vou.NIK,
app.Tanggal_Approve,
app.Total,
app.ID_Admin,
adm.Nama_Lengkap,
app.ID_Approved
};
IEnumerable < int > enumerable = NIKQry.GroupBy(v => v).Select(group => group.FirstOrDefault());
NIKLst = enumerable.ToList();
ViewBag.VoucherNIK = new SelectList(NIKLst);
try
{
if (!string.IsNullOrEmpty(Admin))
{
query = query.Where(s => s.Nama_Lengkap.Contains(Admin));
}
}
catch (DataException /* dex */)
{
ModelState.AddModelError("", "Unable to Apply.");
}
return View(query));
}
else
{
return RedirectToAction("Login", "Account");
}
}
And the View
#model IEnumerable<Voucher.Models.Approved>
#{
ViewBag.Title = "Approved";
Layout = "~/Views/Shared/_LayoutAdmin.cshtml";
}
#using (Html.BeginForm("Approved", "Voucher", FormMethod.Get))
{
<div class="form-horizontal">
<hr />
<div class="form-group">
NIK Voucher :
<div class="col-md-10">
#Html.DropDownList("VoucherNIK", null, "All") <!-- new { onchange = "document.location.href = '?VoucherNIK=' + this.value;" })!-->
</div>
</div>
<div class="form-group">
ADMIN Approve :
<div class="col-md-10">
#Html.TextBox("Admin")
</div>
</div>
<div class="form-group">
Month :
<div class="col-md-10">
#Html.TextBox("month")
</div>
</div>
<div class="form-group">
Year :
<div class="col-md-10">
#Html.TextBox("Year")
</div>
</div>
<div class="form-group">
Price(min NUMBER) :
<div class="col-md-10">
#Html.TextBox("minPrice")
</div>
</div>
<div class="form-group">
Price(max NUMBER) :
<div class="col-md-10">
#Html.TextBox("maxPrice")
</div>
</div>
</div>
<input type="submit" value="Filter" class="btn-toolbar" /><br />
}
<br />
<table class="table">
<tr>
<th>
Nama Admin
</th>
<th>
ID Approved
</th>
<th>
Tanggal
</th>
<th>
ID Admin
</th>
<th>
TOTAL
</th>
<th></th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Nama_Lengkap)
</td>
<td>
#Html.DisplayFor(modelItem => item.ID_Approved)
</td>
<td>
#Html.DisplayFor(modelItem => item.Tanggal_Approve)
</td>
<td>
#Html.DisplayFor(modelItem => item.ID_Admin)
</td>
<td>
#Html.DisplayFor(modelItem => item.Total)
</td>
<td>
#Html.ActionLink("More Detail", "DetailAppr", new { id = item.ID_Approved })
</td>
</tr>
}
</table>
When Run i got this error
The model item passed into the dictionary is of type 'System.Data.Entity.Infrastructure.DbQuery1
,but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable1[MvcMarks.Models.MarksType]'

Change return statement to
return View(query
.Select(it => new MarksType{
//initilize properties of `MarksType` with `it`
}));
Your view expects a model of type IEnumerable<MarksType> but query variable is IEnumerable of Anonymous objects.

Related

How do I pass a selected ID to my SQL Database?

I am having trouble with this last part of my project. I have all of my SQL Table columns filled up except for this last part. I have two tables WorkSchedule and WorkShiftBid.
In WorkShiftBid, I have WorkShiftBidID,WSBidDateTime,WSBidStatus,WorkScheduleID,StaffID
I will be using Guid.NewGuid() for WorkShiftBidID, Datetime.now for WSBidDatetime, A hardcoded "pending" value for WSBidStatus, A viewbag for StaffID and I am trying to get the WorkScheduleID to work but to no avail.
For WorkSchedule, I am trying to get just the "WorkScheduleID" attribute just by using a button method asp-route-id="#item.WorkScheduleID" and it will redirect me to the Create page whereby I will select a Staff from the drop-down list and then save it to my WorkShiftBid table as it has a foreign key for "WorkScheduleID".
It would be helpful if someone could help me. Thank you.
Controller Code:
public IActionResult CreateWorkShift()
{
ViewData["StaffID"] = new SelectList(_context.Staff, "StaffID", "StaffName");
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> CreateWorkShift(Guid? id, [Bind("WorkShiftBidID,WSBidDateTime,WSBidStatus,WorkScheduleID,StaffID")] WorkShiftBidModel workShiftBidModel)
{
if (id != workShiftBidModel.WorkScheduleID)
{
return NotFound();
}
if (ModelState.IsValid)
{
workShiftBidModel.WSBidDateTime = DateTime.Now;
workShiftBidModel.WorkShiftBidID = Guid.NewGuid();
_context.Add(workShiftBidModel);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(DisplaySchedule));
}
ViewData["StaffID"] = new SelectList(_context.Staff, "StaffID", "StaffName", workShiftBidModel.StaffID);
return View(workShiftBidModel);
}
private bool WorkShiftBidModelExist(Guid id)
{
return _context.WorkSchedule.Any(e => e.WorkScheduleID == id);
}
Display WorkShift Page:
<h1 class="text-center"> Apply Workshifts</h1>
<hr />
<table class="table">
<thead>
<tr>
<th>
From (DateTime)
</th>
<th>
To (DateTime)
</th>
<th>
Day
</th>
<th>
Status
</th>
<th>
Work Descriptions
</th>
<th>
Branch
</th>
<th>
Manager
</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.WorkScheduleFromDateTime)
</td>
<td>
#Html.DisplayFor(modelItem => item.WorkScheduleToDateTime)
</td>
<td>
#Html.DisplayFor(modelItem => item.WorkScheduleFromDateTime.DayOfWeek)
</td>
<td>
#Html.DisplayFor(modelItem => item.WorkScheduleStatus)
</td>
<td>
#Html.DisplayFor(modelItem => item.WorkDescriptions.WorkDescriptionName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Branches.BranchName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Staff.StaffName)
</td>
<td>
<form method="post">
<input type="submit" class="btn btn-primary btn-block" value="Bid" asp-route-id="#item.WorkScheduleID" asp-action="DisplaySchedule" asp-controller="PartTimer" />
</form>
<div class="form-group col-md-6">
<a asp-action="CreateWorkShift" asp-route-id="#item.WorkScheduleID" class="btn btn-success">Create</a>
</div>
</td>
</tr>
}
</tbody>
</table>
Create view page code:
<h1>Create</h1>
<h4>Work Shifts</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="CreateWorkShift">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input type="hidden" asp-for="WorkScheduleID"/>
<div class="form-group">
<label asp-for="WSBidStatus" class="control-label"></label>
<input readonly asp-for="WSBidStatus" value="Pending" class="form-control"/>
<span asp-validation-for="WSBidStatus" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="StaffID" class="control-label"></label>
<select asp-for="StaffID" class="form-control" asp-items="ViewBag.StaffID"></select>
</div>
<div class="form-row">
<div class="form-group col-md-6">
<input type="submit" value="Save" class="btn btn-primary btn-block" />
</div>
<div class="form-group col-md-6">
<a asp-action="ProfilePage" class="btn btn-secondary btn-block"><i class=" fa fa-table"></i>Back to List</a>
</div>
</div>
</form>
</div>
</div>
#section Scripts {
#{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
Do you mean you cannot get the WorkScheduleID in public async Task<IActionResult> CreateWorkShift(Guid? id, [Bind("WorkShiftBidID,WSBidDateTime,WSBidStatus,WorkScheduleID,StaffID")] WorkShiftBidModel workShiftBidModel).If so,you need to get and pass Id in public IActionResult CreateWorkShift.Here is a demo worked:
public IActionResult CreateWorkShift(int id)
{
List<Staff> list = new List<Staff> { new Staff { StaffID = 1, StaffName = "staff1" }, new Staff { StaffID = 2, StaffName = "staff2" } };
ViewData["StaffID"] = new SelectList(list, "StaffID", "StaffName");
WorkShiftBidModel w = new WorkShiftBidModel { WorkScheduleID = id };
return View(w);
}
result:

How to add a counter with row numbering on all site in mvc

I want to add an automatic numbering of order items to all pages.
Below is an example that works but only numbers on one page. After going to the next page, it starts from the beginning.
public ActionResult ListaZlecen(int? IdStatusZlecenia, int strona = 1)
{
var ListaZlecenWszystkich = db.Zlecenia.ToList();
var userId = User.Identity.GetUserId();
//var ListaZlecen = db.Zlecenia.Where(p => p.UserId == userId).ToList();
//var ListaZlecen = db.Zlecenia.OrderBy(w => w.IdZlecenia).Where(p => p.UserId == userId).Skip((strona - 1) * WielkoscStrony).Take(WielkoscStrony).ToList();
var ListaZlecen = db.Zlecenia.OrderBy(w => w.IdZlecenia).Skip((strona - 1) * WielkoscStrony).Take(WielkoscStrony).ToList();
// var zleceniezalacznik = db.ZleceniaZalaczniki.ToList();
var viewodel = new ListaZlecenUzytkownikaViewModel()
{
StronaInfo = new StronaInfo
{
AktualnaStrona = strona,
PozycjeNaStrone = WielkoscStrony,
WszystkiePozycje = ListaZlecenWszystkich.Count()
},
ListaZlecenUzytkownika = ListaZlecen
};
return View(viewodel);
}
and View
#model AplikacjaHelpDesk.ViewModels.ListaZlecenUzytkownikaViewModel
#using AplikacjaHelpDesk.Infrastructure;
#{
ViewBag.Title = "Lista Zlecen Użytkownika";
Layout = "~/Views/Shared/_LayoutAdministracja.cshtml";
}
<div class="container-fluid">
<img src="~/Content/Images/Layout/Home.png" />
<a href="link">
#Html.MvcSiteMap().SiteMapPath()
</a>
<h2><span class="glyphicon glyphicon-user"></span>&nbsp<strong>Lista Zleceń </strong></h2>
<br /><br />
<div id="divLoading" class="panel panel-primary text-center text-primary" style="display:none;">
<h3><strong>Proszę czekać ładowane są posty!</strong></h3>
</div>
<div id="divLoadingForm" class="panel panel-primary text-center text-primary" style="display:none;">
<h3><strong>Proszę czekać ładuję formularz</strong></h3>
</div>
#*#if (ViewBag.Informacja != null)
{
<div class="alert alert-warning"><h4><strong>#TempData["Dodano-Post"]</strong></h4></div>
}*#
<table class="table table-responsive table-striped transactions" style="text-combine-upright:all;">
<tr style="text-transform: uppercase; text-combine-upright:all;">
<th>
<label>Pozycja Nr.</label>
</th>
<th>
<label>Nr Zlecenia</label>
</th>
<th>
<label>Data Przyjęcia Zlecenia</label>
</th>
<th>
<label>Data Planowanego Zakończenia Zlecenia</label>
</th>
<th>
<label>Data zakończenia zlecenia</label>
</th>
<th style="width: 160px;"></th>
<th style="width: 160px;"></th>
</tr>
#{ var i = 0;}
#foreach (var item in Model.ListaZlecenUzytkownika)
{
<tr class="panel panel-primary">
#*
<h5><strong>Zlecenie nr: #Html.DisplayFor(modeItem => item.IdZlecenia)</strong></h5>
<td>
#{i++;}
#i
</td>
<td>
<h5><strong>Zlecenie nr: #Html.DisplayFor(modeItem => item.IdZlecenia)</strong></h5>
</td>
<td>
#Html.DisplayFor(modelItem => item.DataPrzyjeciaZlecenia)
</td>
<td>
#Html.DisplayFor(modelItem => item.DataPlanowaniaZakonczenia)
</td>
<td>
#Html.DisplayFor(modelItem => item.DataZakonczenia)
</td>
<td>
#Ajax.ActionLink("Pokaż Posty Zlecenia", "_ListaPostow", new { idZlecenia = #item.IdZlecenia }, new AjaxOptions()
{
HttpMethod = "GET",
LoadingElementId = "divLoading",
UpdateTargetId = "divPozycje",
InsertionMode = InsertionMode.Replace
}, new { #class = "btn btn-primary" })
</td>
<td>
#Ajax.ActionLink("Dodaj Odpowiedz", "_DodajPost", new { idZlecenia = #item.IdZlecenia }, new AjaxOptions()
{
HttpMethod = "GET",
LoadingElementId = "divLoadingForm",
UpdateTargetId = "divDodajPozycje",
InsertionMode = InsertionMode.Replace
}, new { #class = "btn btn-primary" })
</td>
</tr>
<tr style="background: #23527c; color:white;">
<td>
<label>Opis załącznika</label>
</td>
<td style="width: 120px;">
<label>Załącznik</label>
</td>
</tr>
<tr class="panel panel-group">
<td>
#Html.Raw(item.ZleceniaZalaczniki.Opis)
</td>
<td>
<span class="btn btn-primary">
#Html.ActionLink("Pobierz", "Download", "Zlecenia", new { nazwaPliku = #item.ZleceniaZalaczniki.NazwaPliku }, null)
<span class="glyphicon glyphicon-download" aria-hidden="true"></span>
</span>
</td>
</tr>
<tr id="divDodajPozycje"></tr>
}
</table>
<br />
<div class="btn-group pull-right">
#Html.LinkStrony(Model.StronaInfo, x => Url.Action("ListaZlecen", new { strona = x }))
</div>
<br />
<hr />
<div id="divPozycje">
</div>
</div>
I tried this way but it creates numbering only on one page. Going to the next numbering is created from the beginning.
#{ var i = 0;}
<td>
#{i++;}
#i
</td>
I have 3 orders on each page and I would like all orders to be automatically numbered, for example:
First page 1,2,3
Second page 4,5,6
I am asking for help in creating the numbering for the entire collection of orders
Instead of starting at i=0 you can start at your current page,
I don't know which language it is but I hope i got it right.
// Instead of this: #{ var i = 0;} - on your view
//Use this:
#{ var i = (Model.AktualnaStrona -1 ) * Model.PozycjeNaStrone ;}
//It should be equal to the calculation you use on the API:
(strona - 1) * WielkoscStrony
//(from this line: )
var ListaZlecen = db.Zlecenia.OrderBy(w => w.IdZlecenia).
Skip((strona - 1) * WielkoscStrony). //--> THIS
Take(WielkoscStrony).ToList();

Child Actions are not allowed to perform redirect actions Partial Views

On my Main View I have 4 partial views.. two are tables.. the others are create forms.
Partial View Table 1
#model IEnumerable<ProjectName.Models.code_AutoMake>
<h3>Auto Make List</h3>
<table id="Auto-Make-Table" class="table table-bordered table-striped">
<thead>
<tr>
<th class="col-md-5">
#Html.DisplayNameFor(model => model.AutoMake)
</th>
<th class="col-md-5">
#Html.DisplayNameFor(model => model.Active)
</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.AutoMake)
</td>
<td>
#Html.DisplayFor(modelItem => item.Active)
</td>
#if (!item.Active)
{
<td>
#Html.ActionLink("Edit", "Edit", new { id = item.MakeID }) |
Activate
</td>
}
else
{
<td>
#Html.ActionLink("Edit", "Edit", new { id = item.MakeID }) |
Deactivate
</td>
}
</tr>
}
</tbody>
</table>
Partial View Table 2
#model IEnumerable<ProjectName.Models.code_Funding>
<h3>Funding List</h3>
<table class="table table table-bordered table-striped">
<tr>
<th>
#Html.DisplayNameFor(model => model.Funding)
</th>
<th>
#Html.DisplayNameFor(model => model.Active)
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Funding)
</td>
<td>
#Html.DisplayFor(modelItem => item.Active)
</td>
<td>
#Html.ActionLink("Edit", "Edit", "code_Funding",new { id=item.FundID }, null) |
</td>
</tr>
}
</table>
Partial View 1 Create
#model ProjectName.Models.code_AutoMake
#using (Html.BeginForm("Create", "code_AutoMake", FormMethod.Post))
{
#Html.AntiForgeryToken()
<h3>Add Auto Make</h3>
<div class="form-horizontal">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="row">
<div class="col-sm-12 col-md-3">
#Html.Label("Auto Make")
#Html.EditorFor(model => model.AutoMake, new {htmlAttributes = new {#class = "form-control"}})
</div>
<div class="col-sm-12 col-md-3">
#Html.Label("Active")
<div class="checkbox">
#Html.EditorFor(model => model.Active)
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-12 col-md-3">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
Partial View 2 Create
#model ProjectName.Models.code_Funding
#using (Html.BeginForm("Create", "code_Funding", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<h3>Add Funding</h3>
<div class="form-horizontal">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="row">
<div class="col-sm-12 col-md-3">
#Html.Label("Funding")
#Html.EditorFor(model => model.Funding, new {htmlAttributes = new {#class = "form-control"}})
</div>
<div class="col-sm-12 col-md-3">
#Html.Label("Active")
<div class="checkbox">
#Html.EditorFor(model => model.Active)
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-12 col-md-3">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
Main View
<div id="AutoMake" class="tab-pane fade active in">
<div id="AutoMake-Index">#{Html.RenderAction("Index", "code_AutoMake");}</div>
<hr/>
#{Html.RenderAction("Create", "code_AutoMake");}
</div>
#*Funding*#
<div id="Funding" class="tab-pane fade">
#{Html.RenderAction("Index", "code_Funding");}
<hr/>
#{Html.RenderAction("Create", "code_Funding");}
</div>
Now here is the scenario.. When I want to create a new autoMake.. I fill out the form and hit submit.. this goes through fine.. until I get back to the Main View.. specifically this line:
#{Html.RenderAction("Create", "code_Funding");}
and I get a runtime error saying:
Child Actions are not allowed to perform redirect actions
I have debugged.. and for some reason.. the HttpPost Create action for code_Funding is being hit.. even when I'm not filling out the create form for code_funding.. How is that possible?
Here are my Create Methods for code_autoMake and code_funding:
code_Funding
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "FundID,Funding,Active")] code_Funding code_Funding)
{
try
{
if (ModelState.IsValid)
{
db.code_Funding.Add(code_Funding);
db.SaveChanges();
return RedirectToAction("EditDDL", "tblNewAutos");
}
}
catch (DbEntityValidationException ex)
{
foreach (var entityValidationErrors in ex.EntityValidationErrors)
{
foreach (var validationError in entityValidationErrors.ValidationErrors)
{
Response.Write("Property: " + validationError.PropertyName + " Error: " + validationError.ErrorMessage);
}
}
}
return RedirectToAction("EditDDL", "tblNewAutos");
}
code_autoMake
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "MakeID,AutoMake,Active")] code_AutoMake code_AutoMake)
{
if (ModelState.IsValid)
{
db.code_AutoMake.Add(code_AutoMake);
db.SaveChanges();
return PartialView("~/Views/PartialViews/_AutoMakeCreate.cshtml");
}
return RedirectToAction("EditDDL", "tblNewAutos");
}
Why when I try and create a new automake.. both HttpPost Create methods are hit?
Any help is appreciated.
Well, the problem is following. In your main view you have got this code:
...
#{Html.RenderAction("Create", "code_AutoMake");}
...
Which triggers the Create action which finishes with the following line of code if ModelState.IsValid == false:
return RedirectToAction("EditDDL", "tblNewAutos");
That is obviously a bad idea. Why? You are already in a process of rendering a parent view. Child actions might be a bit confusing at first because they are not real actions - no client/server communication. You are still on the server side. Therefore no redirect is allowed in the child action.
Solutions
First of all, I am not quite sure what you want to achieve so my solution recommendation might be a bit off, but let's see.
Option 1
You may want to use two different actions. One that is called on submit of the form and another one that is called from your main view. The latter one should not make a redirect - instead it should wisely choose which view to render based on the ModelState.IsValid if this is really what you need.
Option 2
There is a hack way which allows you to make redirect from a child action. Instead of making a redirect, only store information about required redirect for instance in HttpContext.Items collection. Then, implement an ActionFilter and in its OnResultExecuted event, check if the redirect request was set to the HttpContext.Items. If so, make a redirect. The ActionFilter should be applied on the parent action, not on the child action.
#{Html.RenderAction("Create", "code_Funding");}
in this RenderAction Method is call the GET request but, your controller you written only post method. and you write the
[ChildActionOnly]
public ActionResult Create(string parm)
{
reurn view()
}
and use [ChildActionOnly] this attribute is allowing restricted access via code in View.
Check and reply me..

Error executing child request: 'System.Web.Mvc.HttpHandlerUtil+ServerExecuteHttpHandlerAsyncWrapper'. after adding a validationmessage

I'm having this error and scavenged S.O. for answers. I used the [childonly], added the controller to my renderaction. I was able to submit but once I added validationmessagefor. This exception came up.
Here's the partial View
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion" href="#Draft">
My Drafts
</a>
</h4>
</div>
<div id="Draft" class="panel-collapse collapse">
<div class="panel-body">
#{
Html.RenderAction("GetDrafts","MyPostController");
}
</div>
</div>
</div>
<div class="row">
<div class="col-md-5">
<label>Reply To:<small>(optional)</small></label>
</div>
<div class="col-md-7">
#Html.TextBoxFor(m => m.ReplyTo,null,new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.ReplyTo)
</div>
</div>
on top of that there's a
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="col-md-3">
#*//side menu here*#
#Html.Partial("_SideMenu", Model)
</div>
here's the action
/// <summary>
/// get all saved drafts
/// </summary>
/// <returns></returns>
[ChildActionOnly]
public ActionResult GetDrafts()
{
var drafts = _dbrepo.GetUserDrafts();
return PartialView("_DraftView", drafts);
}
here is the _draftview
#model IEnumerable<Models.MyModel>
#{
Layout = null;
}
<div class="table-responsive">
<small>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.PostSubject)
</th>
<th>
#Html.DisplayNameFor(model => model.PostDate)
</th>
<th>
#Html.DisplayNameFor(model => model.RecCreateUser)
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.PostSubject)
</td>
<td>
#Html.DisplayFor(modelItem => item.PostDate)
</td>
<td>
#Html.DisplayFor(modelItem => item.RecCreateUser)
</td>
<td>
#Html.ActionLink("View", "ViewDraft", new { id = item.ID}, new { #class = "btn btn-default btn-xs" })
</td>
</tr>
}
</table>
</small>
</div>
I tried this Html.RenderAction Failed when Validation Failed
but its throwing me an "ambiguous between the following action methods" error
So as I have mentioned. I was able to post data if modelstate isvalid. but once it is invalid. that exception comes up.
I tried commenting the renderaction for testing. and I was able to throw the validationmessage.

Why are the parameters of my action null?

I'm trying to make a page using ASP MVC 5 with C# in which I have some controls to type search parameters and a table where the results are shown.
The thing is that the user should be allowed to edit the text of two fields in the table and save the changes.
To accomplish this, my view receives a model with two objects as properties, one for the search parameters and one for the result list, like this:
public class SEARCH_PAGE
{
public List<VIEW_DATA_APR> table{ get; set; }
public SEARCH parameters{ get; set; }
}
Then my Controller is this:
public class CargaAPRController : Controller
{
private datasource db = new datasource();
// GET: CargaAPR
public ActionResult Index()
{
try
{
List<SelectListItem> items = new SelectList(db.COMPANY, "IDCOMPANY", "COMPANYNAME").ToList();
items.Insert(0, (new SelectListItem { Text = "ALL", Value = "0" }));
ViewData["IDCOMPANY"] = items;
var letters = (from c in db.LETTERS
select new VIEW_DATA_APR
{
company = c.COMPANY.COMPANYNAME,
idLetter = c.IDLETTER,
nic = "not found",
client = "not found",
energy = 0,
money = 0,
period = "",
letterCode = c.LETTERCODE
});
SEARCH_PAGE sp = new SEARCH_PAGE();
sp.table= letters.ToList();
sp.parameters= new SEARCH();
return View(sp);
}
catch (Exception ex)
{
return RedirectToAction("Error", new RouteValueDictionary(new { controller = "Users", action = "Error", mensaje = "Error: " + ex.Message }));
}
}
[HttpPost]
public ActionResult Index(SEARCH_PAGE model)
{
try
{
List<SelectListItem> items = new SelectList(db.COMPANY, "IDCOMPANY", "COMPANYNAME").ToList();
items.Insert(0, (new SelectListItem { Text = "ALL", Value = "0" }));
ViewData["IDCOMPANY"] = items;
decimal company = Decimal.Parse(model.parameters.company);
var letters= (from c in db.LETTERS
where (company== 0 ? c.IDCOMPANY: company) == c.IDCOMPANY
select new VIEW_DATA_APR
{
company= c.COMPANY.COMPANYNAME,
idLetter= c.IDLETTER,
nic = "not found",
client = "not found",
energy = 0,
money = 0,
period = "",
letterCode = c.LETTERCODE
});
SEARCH_PAGE sp = new SEARCH_PAGE();
sp.table= letters.ToList();
sp.parameters = model.parameters;
return View(sp);
}
catch (Exception ex)
{
return RedirectToAction("Error", new RouteValueDictionary(new { controller = "Users", action = "Error", mensaje = "Error: " + ex.Message }));
}
}
[HttpPost]
public ActionResult Save(SEARCH_PAGE model_search_page )
{
return View();
}
}
And my View is:
#using datasource.Models
#model SEARCH_PAGE
#{
ViewBag.Title = "Load APR";
Layout = "~/Views/Shared/_Layout.cshtml";
}
#Styles.Render("~/Content/energetica.css")
<meta name="viewport" content="width=device-width" />
<title>Letters</title>
<link href="#Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
<div class="container-fluid">
<div class="col-md-1">
</div>
<div class="col-md-10">
<div class="panel panel-default">
<!-- Default panel contents -->
<div class="panel-heading">
<div class="row">
<div class="col-md-1">
<a href="#Url.Action("Index", "LoadFiles")" class="elements">
<img class="img img-responsive" style="width:25px; height:26px;padding:1px" src="~/img/BackIcon.png">
</a>
</div>
<div class="col-md-11 text-left" style="padding:1px;">
LOAD APR
</div>
</div>
</div>
</div>
#using (Html.BeginForm("Index","LoadAPR", FormMethod.Post, null))
{
<table style="width:100%">
<tr>
<td style="width:10%">
<b>COMPANY: </b>
</td>
<td style="width:20%">
#Html.DropDownListFor(m => m.parameters.company, (IEnumerable<SelectListItem>)ViewData["IDCOMPANY"], new { htmlAttributes = new { #class = "form-control" } })
</td>
<td style="width:10%">
<b>PERIOD: </b>
</td>
<td style="width:20%">
#Html.EditorFor(m => m.parameters.period)
</td>
<td style="width:20%; text-align:right">
<input type="submit" name="SEARCH" value="SEARCH" />
</td>
</tr>
<tr>
<td style="width:10%">
<b>CLIENT: </b>
</td>
<td style="width:20%">
#Html.EditorFor(m => m.parameters.client)
</td>
<td style="width:10%">
<b>NIC: </b>
</td>
<td style="width:20%">
#Html.EditorFor(m => m.parameters.nic)
</td>
</tr>
</table>
}
<br />
#using (Html.BeginForm("Save", "LoadAPR", FormMethod.Post, null))
{
<div style="overflow-y: scroll; max-height: 300px">
<table style="width:100%">
<tr>
<th>
#Html.Label("LBDIS", "Company")
</th>
<th>
#Html.Label("LBNLETTER", "Letter Code")
</th>
<th>
#Html.Label("LBNIC", "NIC")
</th>
<th>
#Html.Label("LBCLIENT", "Client")
</th>
<th>
#Html.Label("LBENERGY", "Energy")
</th>
<th>
#Html.Label("LBMONEY", "Money")
</th>
</tr>
#foreach (var item in Model.table)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.company)
</td>
<td>
#Html.DisplayFor(modelItem => item.letterCode)
</td>
<td>
#Html.DisplayFor(modelItem => item.nic)
</td>
<td>
#Html.DisplayFor(modelItem => item.client)
</td>
<td>
#Html.EditorFor(modelItem => item.energy)
</td>
<td>
#Html.EditorFor(modelItem => item.money)
</td>
</tr>
}
</table>
</div>
<br />
<div style="width:100%; text-align:right;">
<input class="btn-addUser" type="submit" value="Save" />
</div>
}
</div>
So when I run it and click on my first button, the POST Index parameter receives just the parameters part of the object, the table part is null
And when I click on my second button, the POST Save parameter comes null in both properties.
I have tried so many different ways of seding the Model as parameter but nothing is working. Could you tell me what's wrong? Am I using he BeginForm in the correct way?
Thank you in advance.

Categories