Pass id value from view which is receiving IEnemerable List - asp.net-mvc

I want to pass id value from my view . I am using Html.ActionLink attribute.
I am performing like this
#foreach (var item in Model)
{
<div class="grid_1_of_4 images_1_of_4">
<img src="/#item.p_imageUrl" alt="" />
<h2>#item.p_name </h2>
<div class="price-details">
<div class="price-number">
<p><span class="rupees">#item.p_price</span></p>
</div>
#Html.ActionLink("Add to Cart", "Mobiles", new { id = item.ProductId }, new { #class = "add" })
<div class="clear"></div>
</div>
</div>
}
but this doesnot posting it instead get action is calling in controller.How to fix that

You can use the one action for both things using optional parameter feature, no need of making another action:
public ActionResult Mobiles(int id=0)
{
// id will be initialized 0 when no id passed to action
if(id > 0)
{
// if id is coming do something here
var q = from n in db.Mobiles
where n.ProductId == id
select n;
return View(q);
}
else
{
var q = from n in db.Mobiles
select n; // id is not passed
return View(q);
}
}

Related

PagedList MVC stay on the same page after a post

I have a view where the side menu (where PagedList is populating data with no problems) that are also links to display another set of data on the same view. Once these links are clicked, I want to have the data on that field to be changed and have the side menu (PagedList) to stay on the same page. I can pass the id value to my controller and display the data, but the "page number" value is not being passed.
Any ideas on how to accomplish that.
Here's what my code looks like
[HttpPost]
public ActionResult Index(string id, int? page)
{
try
{
id = Request.Form["newsLinkButton"];
ViewBag.Id = id;
using (myEntities db = new myEntities())
{
var getNews = db.News.Where(x => x.Show == "Yes").OrderByDescending(x => x.Date).ToList();
return View(getNews.ToPagedList(page ?? 1, 5));
}
}
catch (Exception ex)
{
return View(ex);
}
}
<div class="sidebar blue-sidebar news-sidebar no-mobile">
<h2>Recent News</h2>
#using (Html.BeginForm("Index", "News", FormMethod.Post))
{
<form id="newsForm" name="newsForm">
<ul class="white-text">
#foreach (var item in Model.OrderByDescending(x => x.Date))
{
<li>
<button id="newsLinkButton" name="newsLinkButton" type="submit" value="#item.Id">#item.Title</button>
</li>
}
</ul>
</form>
<div class="center-block">
#Html.PagedListPager(Model, page => Url.Action("Index", new { page }),
new PagedListRenderOptions()
{
DisplayLinkToFirstPage = PagedListDisplayMode.Always,
DisplayLinkToPreviousPage = PagedListDisplayMode.Always,
DisplayLinkToLastPage = PagedListDisplayMode.Always,
DisplayLinkToNextPage = PagedListDisplayMode.Always,
MaximumPageNumbersToDisplay = 3, // number of pages in line
DisplayEllipsesWhenNotShowingAllPageNumbers = false
})
</div>
}
</div>
Once again, thanks for your help in advance. I appreciate.
I found out that the property PageNumber is what holds the value for the page number (yeah, I know huh?). Therefore, I created #{ Session["page"] = Model.PageNumber; } and passed on to the controller. Problem solved. I hope this can help someone else in the future.

Pass HiddenFor ID from View to a another ActionResult which is a PartialView

My title I think is a little confusing, let me explain:
I have an IndexView where I display all the Jobs of Companies and I am trying to add a PartialView with the coresponding Image.
I do not want to save the Image on the JobTable when I submit a Job. I want Images to be separate and linked only by UserID. In the page details I had an int? ID in the ActionResult header, I made two LINQ queries, first selects UserID with the int? ID, in second query I selected the ImageID with UserID from first query so I am trying to do the same but here I have no ID in URL because I display a list.
Since this is a list I tried to get the value from each #Html.HiddenFor(model => item.ID) which is inside a foreach but I couldn't pass it back to my ActionResult (which is PartialView not Index), I tried with ViewBag, Sessions everything is null everytime. I gave it a name, a Value(uppercase and lowercase) with # and without.
Here code:
public ActionResult ImgPanel(Job job, int? ID)
{
var JobUserID = (from j in db.Jobs
where j.ID == ID /*Here should be the ID from the View of each job object*/
select j.UserID).FirstOrDefault();
var img = (from j in db.Images
where j.UserID == JobUserID
select j).ToList();
return View(img);
}
Well the ActionResult for ImgPanel in this state returns an Image, but only first(in all Jobs same Image), the second time my breakpoints are telling me only null on everything.
View Code:
#foreach (var item in Model)
{
#Html.HiddenFor(model => item.ID) /*I removed all tries with name Value Viewbags etc*/
#Html.Action("ImgPanel", "Jobs") /*Here I call the PartialView ImgPanel*/
<div class="row">
<div class="col-sm-6 col-md-4">
<div class="thumbnail">
<h3>#Html.DisplayFor(modelItem => item.ApplicationUsers.CompName)</h3>
<div class="caption">
<h4>#Html.DisplayFor(modelItem => item.Name)</h4>
<h5><strong>Days Left: </strong>#Convert.ToInt32((item.DateExp - DateTime.Now).TotalDays)</h5>
<p>
Details
Bookmark
Hide
</p>
</div>
</div>
</div>
</div>
}
Try passing in a viewmodel which contains your IDs.
In your view:
#Html.Action("ImgPanel", "Jobs", new MyViewModel() { ItemId = item.ID })
In your controller:
public ActionResult ImgPanel(MyViewModel viewmodel)
{
var JobUserID = (from j in db.Jobs
where j.ID == viewmodel.ItemId /*Here you use the ID stored in the viewmodel*/
select j.UserID).FirstOrDefault();
var img = (from j in db.Images
where j.UserID == JobUserID
select j).ToList();
return View(img);
}
Hope that helps!

not show take(4) Data in Partial View

i Creating News Site in ASP.Net MVC .
I Want to Show 4 last Row Data in Database When Them Type Is ("SP") .
But When i Run Project Show Me Just Last Row .
How I Resolve it ?
My Database : Database Record
I Create Repository This .
public List<Tbl_News> GetSpecialNews()
{
try
{
List<Tbl_News> qGetSpecialNews = (from a in db.Tbl_News
where a.Type.Equals("sp")
select a).OrderByDescending(s => s.ID).Skip(0).Take(4).ToList();
return qGetSpecialNews;
}
catch (Exception)
{
return null;
}
}
Partial View :
#{
foreach (var item in RNews.GetSpecialNews())
{
<div class="sec-special-page-news-img">
<img src="~/Content/img/NewsPic/#item.Image" />
</div>
<div class="sec-special-page-news-body">
#item.Title
<ul class="mini-info">
<li>#item.Date<span class="glyphicon glyphicon-time"></span></li>
</ul>
</div>
}
}
Home Controll :
public class HomeController : Controller
{
Rep_News RNews = new Rep_News();
// GET: Home
public ActionResult Index()
{
var q = RNews.GetSpecialNews();
return View(q);
}
}
Quoting from comments
Your code should return 4 records. Also, you do not need to call
RNews.GetSpecialNews() method again in your view as your are doing
that in your action method and passing it to the view. Just do a
foreach on the Model
public List<Tbl_News> GetSpecialNews() {
try {
List<Tbl_News> qGetSpecialNews =
(from a in db.Tbl_News
where a.Type.Equals("sp")
select a)
.OrderByDescending(s => s.ID)
.Take(4)
.ToList();
return qGetSpecialNews;
}
catch (Exception) {
return null;
}
}
View
#model List<Tbl_News>
#{
foreach (var item in Model)
{
<div class="sec-special-page-news-img">
<img src="~/Content/img/NewsPic/#item.Image" />
</div>
<div class="sec-special-page-news-body">
#item.Title
<ul class="mini-info">
<li>#item.Date<span class="glyphicon glyphicon-time"></span></li>
</ul>
</div>
}
}

When i try to execute foreach statement i am getting -Object reference not set to an instance of an object

i am working on mvc project. In my controller i am calling my stored procedure from terms class and I am returning Index page if it returns true or return terms page if it returns false.
Calling stored procedure in terms page :
public class Accept
{
public void Check()
{
using (var ctx = new termsEntities())
{
ctx.usp_ChkTerms(8, new ObjectParameter("Accepted", typeof(bool)));
ctx.SaveChanges();
}
}
}
Now i am calling this in my controller :
public ActionResult App()
{
// calling Stored procedure from Model to class
var accept = new Accept();
accept.Check();
// checking if accepted is true then return view else return another view
AppEntities Accepted = new AppEntities();
AppTerm user = new AppTerm();
AppHist history = new AppHist();
user = (from AppTerm app in Accepted.AppTerms
where app.userID == 8
select app).ToList().FirstOrDefault();
if (user != null)
{
if (user.Accepted)
{
return View("Index");
}
else
{
return View("terms");
}
}
And this is the code i am using in my terms view :
#{
ViewBag.Title = "terms";
}
<html>
<body>
<ul>
#foreach ( var item in Model)
{
<div class="Page" onclick="location.href='#Url.Action("Info", new { id = item.ID })'">
span class="Col1">
<br />
#item.ID
</span>
<span class="Title">#item.Name</span>
}
</ul>
</body>
</html>
Here when condition is true it is displaying Index page but when condition falls and when it tries to display terms page i am getting Object reference not set to an instance of an object and error is pointing to foreach loop. so what mistake i am doing here? i need help..
It is ugly, but you may try
<div class="Page" onclick='location.href="#Url.Action("Info", new { id = item.ID })"'>
<div class="Page" onclick="location.href='#Url.Action("Info", new { id = item.ID })'">
Change this to:
<div class="Page" onclick="location.href='#Url.Action('LinkText','Info', new { id = item.ID })'">
Note the quote marks around Info
edit:
Added extra argument to link.

I cannot get just the selected values from dropdownlists in my view back in my controller

I hava a view where I have a list of links, being each link a region where the companies has offices.
Everytime I select a region, I get a list of processes. For every process, I get a dropdowlist from where to choose a owner of the process and a list of checkboxs of tests to choose.
In my controller, I get string[] OwnerId as the values selected in the dropdowlists.
The thing is, I get all values from all dropdowlists, not just those that were selected. How can I get just the ones I selected??
This is my view
#using CTTModel
#using TestingTool.ViewModels
#model TestRunModel
#{
ViewBag.Title = "Create";
}
<h2>
Create</h2>
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<fieldset>
<legend>Regions</legend>
#foreach (Region region in Model.Regions)
{
#Html.ActionLink(#region.Name, "Create", new { id = region.Id })<br />
}
<div class="editor-field">
#foreach (ProcessModel process in Model.Processes)
{
<h1>#process.Name</h1>
**List<User> users = ViewBag.Users;
<select id="OwnerId" name="OwnerId" >
#foreach (User user in users)
{
<option value="#user.Id">#user.Name</option>
}
</select>**
<table>
<tr>
#{
int cnt = 0;
foreach (TestModel testModel in process.Tests)
{
if (cnt++ % 3 == 0)
{
#: </tr> <tr>
}
#: <td>
<input type="checkbox"
name="selectedTests"
value="#testModel.Id/#testModel.ProcessId/#testModel.RegionId"
#(Html.Raw(testModel.Active ? "checked=\"checked\"" : "")) />
#testModel.Name #:: #testModel.Description
#:</td>
}
#: </tr>
}
</table>
}
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
<fieldset>
<legend>Test Screen</legend>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
And this is my controller. The Create Post does nothing yet, I'm trying to get the right values first.
//
// GET: /TestPreparation/Create
public ActionResult Create(int id = 1)
{
TestRunModel testRunModel = new TestRunModel();
foreach (Region region in _db.Regions)
{
testRunModel.Regions.Add(region);
}
TestRun testRun = _db.TestRuns.OrderByDescending(x => x.Id).First();
foreach (TestRunProcessRegion region in testRun.GetProcessesForRegion(_db.Regions.Single(i => i.Id == id)))
{
ProcessModel process = new ProcessModel
{
Code = region.ProcessRegion.Process.Code,
Description = region.ProcessRegion.Process.Description,
Name = region.ProcessRegion.Process.Name,
Process = region.ProcessRegion.Process.Id
};
foreach (SubProcess subProcess in region.ProcessRegion.Process.SubProcesses)
{
foreach (Risk risk in subProcess.Risks)
{
foreach (Test test in risk.Tests)
{
TestModel testModel = new TestModel
{
Id = test.Id,
Name = test.Name,
Description = test.Description,
ProcessId = region.ProcessRegion.Process.Id,
RegionId = region.ProcessRegion.Id
};
process.Tests.Add(testModel);
}
}
}
testRunModel.Processes.Add(process);
}
var users = new List<User>();
foreach (User user in _db.Users)
{
users.Add(new User
{
Id = user.Id,
Name = user.Name,
});
}
ViewBag.Users = users;
return View(testRunModel);
}
//
// POST: /TestPreparation/Create
[HttpPost]
public ActionResult Create(string[] OwnerId, string[] selectedTests, string[] processes)
{
if (ModelState.IsValid)
{
//_db.TestRunStatus.Add(testrunstatus);
//_db.SaveChanges();
return RedirectToAction("Index");
}
return View();
}
The reason why you are not getting any data back is because the method signature of your Post Action needs to be
public ActionResult Create(string OwnerId ...) //preferably int depending on what OwnerId is
This is because you only select one item out of the drop down box. So if you use this signature as opposed to string[], the Model binder will pass the selected value back to your action.
Having said this, it is better practice and the "MVC Way" to use,
Html.DropDownFor(x => x.UserID) it really makes things easier :)
This applies to all html input controls:
http://www.asp.net/mvc/tutorials/getting-started-with-aspnet-mvc3/cs/examining-the-edit-methods-and-edit-view
UPDATE
I think the best thing to do would be to add an OwnerID to the ProccessModel class.
Becuase ProccessModel looks to be IEnumberable<ProccessModel> Processes contained in the ViewModel you can get the Model to Bind in the following way using the defult MVC model binder.
Phil Haack has bloged about binding to lists here:
http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx
Adapting from Phil's post I think you will have to do something like this:
<% for (int i = 0; i < Model.Processes.Count; i++) { %>
<%: Html.SelectListFor(model => model.Processes[i].OwnerID, (IEnumerable<SelectListItem>)ViewBag.Users) %>
<% } %>
Change the ViewBag.User to:
var users = _db.Users.Select(x => new SelectListItem(){
text = x.Name,
value = x.Value
});
Modify the Post Action:
[HttpPost]
public ActionResult Create(TestRunModel model)
{
foreach(var process in model.Porcesses)
{
process.OwnerID // This should be a user selected value
}
// code removed for brevity
}
I could help with getting the TestModel values if you like but I need to do some work now ;)

Resources