view profile after click on hyperlink using view model and find() - asp.net-mvc

I'm new to mvc 4 and having trouble with loading profile after click on hyperlink in View.I'm using view model for combining several classes to one class. Below I h'v added View of Index.
<h3>Place</h3>
#foreach (var item in Model)
{
<div class="item1">
<img src="data:image/png;base64,#Convert.ToBase64String(item.pic,0,item.pic.Length)" width="100" />
<p class="name">#Html.ActionLink(item.Sp_name, "Details", new { id = item.SPID })</p>
</div>
}
once I click on hyperlink in Index View. I want to load it's profile.I'm having problem with where to add find(id) in controller. given below is my controller method for View profile.
public ActionResult Details(int id = 0)
{
List<ImageData> details = new List<ImageData>();
var sp_details = (from s in db.service_provider
join p in db.pictures on s.SPID equals p.SPID
join c in db.cities on s.City_ID equals c.City_ID
where s.SPID == id
select new { s.Sp_name, s.Sp_location, s.Sp_rate, s.service_type, c.Cityname, p.pic });
foreach (var item in sp_details)
{
ImageData SpView = new ImageData(); // ViewModel
SpView.Sp_name = item.Sp_name;
SpView.Sp_location = item.Sp_location;
SpView.Cityname = item.Cityname;
SpView.Sp_rate = item.Sp_rate;
SpView.pic = item.pic;
details.Add(SpView);
}
if (details == null)
{
return HttpNotFound();
}
return View(details);
}
can somebody kindly help me to load profile after click on hyperlink in view.

Try this :
#Html.ActionLink(item.Sp_name, "Details", new { id = item.SPID },null)

Related

Implement and populate view model db first

I have created a page were the user searches for a book and the book details are loaded using partial view. I have successfully done this.
The action method in the controller used to do this:
[HttpGet]
public ActionResult LoanSearch(string q)
{
var loans = GetLoans(q);
return PartialView(loans);
}
private List<Loan> GetLoans(string searchString)
{
return db.Loans
.Where(a => a.Book.Name.Contains(searchString))
.ToList();
}
As you can see the LoanSearch action method is decorated with HTTPGET.
The View for this:
#using (Html.BeginForm())
{
foreach (var item in Model)
{
<ul>
<li>#item.ISBN</li>
<li>#item.Book.Name</li>
<li>#item.Book.Author</li>
<li> #item.FinePrice</li>
</ul>
#Html.ActionLink("Return Book", "LoanSearch", new { id = item.LoanId });
}
}
What I would like to do is update the finePrice in loans db and change onLoan from 1 to 0 in the books db. This should happen when the user clicks on the above Html.ActionLink above.
To achieve this I created the following HTTPPOST action method and also used a view model as I needed to update 2 tables (Loan,Book) at the same time.(is a view model needed?)
[HttpPost]
public ActionResult LoanSearch(BookReturnVM model, string searchString)
{
var bookquery = db.Loans.Where(a => a.Book.Name.Contains(searchString));
var loanquery = db.Loans.Where(a => a.Book.Name == model.BookTitle);
var finePrice = db.Loans.Where(g => g.FinePrice == model.FinePrice);
BookReturnVM model1 = new BookReturnVM
{
OnLoan = model.OnLoan,
FinePrice = model.FinePrice,
};
if (ModelState.IsValid)
{
var fine = db.Loans.FirstOrDefault(g => g.FinePrice == model.FinePrice);
var bookLoan = db.Loans.FirstOrDefault(a => a.Book.Name.Contains(searchString));
if (bookLoan != null)
{ //changes the onloan status to 1 which makes it 'on loan'
bookLoan.Book.OnLoan = 0;
};
db.Entry(bookLoan).State = EntityState.Modified;
db.SaveChanges();
}
return View();
I would like the finePrice found in the Loan table to be updated based on the calculation below. The finePrice calculation is done in the Loan model:
private decimal? _FinePrice;
public decimal? FinePrice
{
get
{
if(DateTime.Now>CheckOutDate)
{
this._FinePrice= ((DateTime.Now - CheckOutDate).Days)*0.50M;
}
else
{
this._FinePrice = 0M;
}
return this._FinePrice;
}
set
{
this._FinePrice = value;
}
}
In conclusion when I search for a book, the details of the book appears(in partial view,which it does), and when I click a button(on the same partial view page) the OnLoan (book table) changes from 1 to 0 and the finePrice (loan table)is updated for that particular book.
I assume the problem lies within the HTTP POST action method but do not know how to solve this in order to solve the above question.
Thanks for your time
You can do something like this:
Tables:
USE [Breaz]
GO
/****** Object: Table [dbo].[Loan] Script Date: 6/26/2017 11:15:15 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Loan](
[LoanId] [int] IDENTITY(1,1) NOT NULL,
[ISBN] [varchar](20) NULL,
[Name] [varchar](20) NULL,
[Author] [varchar](20) NULL,
[FinePrice] [money] NOT NULL,
CONSTRAINT [PK_Loan] PRIMARY KEY CLUSTERED
(
[LoanId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
Controller
public class HomeController : Controller
{
[HttpGet]
public PartialViewResult LoanSearchByIdAndUpdate(int id)
{
//DO your database update here
//I will change the find to 2.37
Loan loan = new Loan();
var bookName = String.Empty;
using (BreazEntities26 db = new BreazEntities26())
{
loan = db.Loans.Find(id);
loan.FinePrice = 2.37M;
bookName = loan.Name;
}
IList<Loan> loans = new List<Loan>();
loans.Add(loan);
return PartialView("_LoanSearch", loans););
}
[HttpGet]
public PartialViewResult LoanSearch(string q)
{
var loans = GetLoans(q);
return PartialView("_LoanSearch", loans););
}
private List<Loan> GetLoans(string searchString)
{
using (BreazEntities26 db = new BreazEntities26())
{
return db.Loans
.Where(a => a.Name.Contains(searchString))
.ToList();
}
}
IndexValid2.cshtml
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>IndexValid2</title>
<script src="~/Scripts/jquery-1.12.4.min.js"></script>
#*MAKE SURE to put the next script in*#
<script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script>
<script type="text/javascript">
$(function () {
$('#passSearchValue').click(function () {
var searchValue = $('#q').val();
this.href = this.href + '?q=' + encodeURIComponent(searchValue);
});
})
</script>
</head>
<body>
<div>
Search for book:
#Html.TextBox("q", null, new { id = "q" })
#*https://stackoverflow.com/questions/5838273/actionlink-routevalue-from-a-textbox*#
#Ajax.ActionLink(
"Search",
"LoanSearch",
null,
new AjaxOptions
{
UpdateTargetId = "result",
InsertionMode = InsertionMode.Replace,
HttpMethod = "GET"
},
new { id = "passSearchValue" })
</div>
<div id="result"></div>
</body>
</html>
partial view in shared, _LoanSearch.cshtml
#model IEnumerable<Testy20161006.Models.Loan>
#foreach (var item in Model)
{
<ul>
<li>#item.ISBN</li>
<li>#item.Name</li>
<li>#item.Author</li>
<li> #item.FinePrice</li>
</ul>
#Html.ActionLink("Update", "LoanSearchByIdAndUpdate", new { id = item.LoanId });
<p />
#Html.ActionLink("Return to Search", "IndexValid2");
}

Pass an id and get it from actionLink to view page

I have this ActionLink into view named catalog
#Html.ActionLink("Formations", "Index", "Formation", new { id = item.Id },null)
and I want to get the list of formations of this catalog id.
How can I do this ?
In my database I have two tables :
Catalog:idC (PK),NameC,Date
Formation:idF(PK),idC(FK),NameF.
If your view's name is Catalog, you need to change your ActionLink to point to the corresponding action:
#Html.ActionLink("Formations", "Catalog", "Formation", new { id = item.Id }, null)
action:
public ActionResult Catalog(int id)
{
var formations = db.Formations.Where(f => f.idC == id).ToList;
return View(formations);
}
view:
#model IEnumerable<ProjectName.Models.Formation>
// loop your formations
#foreach (var item in Model)
{
// each formation iteration loops here
}

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.

How to use a dynamic var in ActionLink to call a different controller's action

Part of ControllerA:
public ActionResult Index()
{
ViewBag.Message = "ToolScope Testing";
var Baselines = from b in db.Baselines
orderby b.Name
select b;
ViewBag.Baselines = Baselines;
return View();
}
Part of View for ControllerA
#foreach (var item in #ViewBag.Baselines)
{
<tr>
<li> #Html.ActionLink( item.Name, "Details", "BaseLine",new { id = item.BaselineID }, null) </li>
</tr>
}
The item.Name is causing problem, however, it works if I use something like
<li> #Html.ActionLink( "SomeName", "Details", "BaseLine",new { id = item.BaselineID }, null) </li>
What should I do to have the dynamic names, i.e., the first ActionLink?
P.S.: I am new to MVC
I see you are new to MVC. Good news, you've already gotten the V(iew) and the C(ontroller). Now it's time to master the M(odel). In your example, you are using the ViewBag to transport knowledge from the Controller to your View. This is a typical responsibility of the Model. So you need to create a new class in your Models directory. It will probably look something like this:
public class MyFirstModel
{
public IEnumerable<MyCustomType> Baselines { get; set; }
public MyFirstModel() { }
}
Edit your Controller
public ActionResult Index()
{
ViewBag.Message = "ToolScope Testing";
var baselines = from b in db.Baselines
orderby b.Name
select b;
var model = new MyFirstModel
{
Baselines = baselines
};
return View(model);
}
Then, add this to the top of your View:
#model MvcApplication.Models.MyFirstModel
Now you can use this code in your view instead:
#foreach (var item in Model.BaseLines)
{
<tr>
<li> #Html.ActionLink( item.Name, "Details", "BaseLine",new { id = item.BaselineID }, null) </li>
</tr>
}

Sorting a list of UserProfiles in mvc3 asp.net application

I'm having trouble sorting a list of user profiles which I am passing to the view. I want to display the list of all users in a certain role and I want to sort them by familyName attribute.
I tried using OrderBy but it has no effect.
Code in the controller
public ActionResult Index()
{
//get all patients
var patients = Roles.GetUsersInRole("user").ToList();
//set up list of patient profiles
List<UserProfile> pprofiles = new List<UserProfile>();
foreach (var i in patients) {
pprofiles.Add(ZodiacPRO.Models.UserProfile.GetUserProfile(i));
}
pprofiles.OrderBy(x => x.familyName); //<-this has no effect the list produced is
// exactly the same it was without this line
return View(pprofiles);
}
And the View
<ul id= "patientList">
#foreach (var m in Model)
{
<li>
<ul class="patient">
<li class="ptitle">#m.title</li>
<li class="pname"> #Html.ActionLink(#m.givenName + " " + #m.familyName, "View", "Account", new { #username = #m.UserName.ToString() }, new { id = "try" })</li>
<li class="pprofile">#Ajax.ActionLink("Profile", "PatientSummary", new { #username = #m.UserName }, new AjaxOptions { UpdateTargetId = "pContent"},new{ #class = "profpic" })</li>
</ul>
</li>
}
</ul>
I will need to reuse this in more than one place and there could be a large number of users so not ordering them in someway would be terrible. How should I go about this?
pprofiles.OrderBy(x => x.familyName); will return an IEnumerable<T>, not sorting the array where it was called on.
You can change your code like this :
public ActionResult Index()
{
//get all patients
var patients = Roles.GetUsersInRole("user").ToList();
//set up list of patient profiles
List<UserProfile> pprofiles = new List<UserProfile>();
foreach (var i in patients) {
pprofiles.Add(ZodiacPRO.Models.UserProfile.GetUserProfile(i));
}
var ordered = pprofiles .OrderBy(x => x.familyName);
return View(ordered );
}
Or in a more Linq-styled way :
var orderedPatients = Roles.GetUsersInRole("user")
.Select(u=>ZodiacPRO.Models.UserProfile.GetUserProfile(u))
.OrderBy(u=>u.FamilyName);
return View(orderedPatients);
Or :
var orderedPatients = from u in Roles.GetUsersInRole("user")
let userProfile = ZodiacPRO.Models.UserProfile.GetUserProfile(u)
order by userProfile.FamilyName
select userProfile;
return View(orderedPatients);
OrderBy does not modify the order of pprofiles elements, rather it returns a new collection with the elements ordered. You can try this:
pprofiles = pprofiles.OrderBy(x => x.familyName);
Or you can use List(T).Sort
You need to assign it back to your variable, OrderBy returns sorted collection:
pprofiles = pprofiles.OrderBy(x => x.familyName);

Resources