Currently trying to build a bulletin in my application where the logged in user simply types in something in a text box and the results are then displayed with a list of other bulletins.
My problem is that I don't want to display the dropdown box of names, I just want the admins' ID who is logged in to post. FYI, I messed up my admin in this app, their ID is different to their userID but their usernames are the same and that is how I get their ID.
I want to store the result of a linq query in the HiddenFor in my razor page. I've been trying with ViewBags but I just get cannot implicitly convert type 'int' to 'system.collections.ienumerable'
Here is my Create part of my controller:
// GET: Bulletins/Create
public ActionResult Create()
{
string username = Membership.GetUser().UserName;
var getAdmin = (from a in db.Admins
where username == a.AdminUsername
select a.AdministrationId).SingleOrDefault();
ViewBag.AdministrationId = new SelectList(db.Admins, "AdministrationId", "AdministratorName");
return View();
}
// POST: Bulletins/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see https://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "BulletinsID,DetailsOfBulletin,AdministrationId")] Bulletins bulletins)
{
if (ModelState.IsValid)
{
string username = Membership.GetUser().UserName;
var getAdmin = (from a in db.Admins
where username == a.AdminUsername
select a.AdministrationId).SingleOrDefault();
db.Bulletins.Add(bulletins);
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.AdministrationId = new SelectList(db.Admins, "AdministrationId", "AdministratorName", bulletins.AdministrationId);
return View(bulletins);
}
And my Razor View:
#Html.HiddenFor(model => model.AdministrationId)
Honestly couldn't find anything so any help would be appreciated. x
First, you should materialize your query to get all admin object from your db:
var adminIds = db.admins.Select(a => a.Id).ToList();
ViewBag.AdministrationIds = adminIds;
Then, if you are using ViewBag to access those admin ids in the view, you will need to foreach over them and render a hidden input with the ID as the value:
#{
foreach (var item in ViewBag.AdministrationIds)
{
<input type ="hidden" value="#item" />
}
}
Related
I have an MVC page (Not .Net Core) which contains the below code
#Html.Partial("~/Views/ProductLanding/product.cshtml", Model.Product(1))
The query in the address bar is similar to ..../products/product?id=4
How could i pass in the query value of 4 (or whatever it might be) into the Model.Product(ID) which then calls some code in my database to retrieve that product?
Using a hardcoded value works so im not sure if i should be doing this differently or if there is a better approach?
Finally hopefully this wont make a difference but once i have this working i would like to change the URL to something more friendly i.e. ..../products/product/4
method 1 : get route data in razor view
{
var id = Context.GetRouteData().Values["id"];
}
#Html.Partial("~/Views/ProductLanding/product.cshtml", Model.Product(id))
method 2 : pass id with controller (viewbag or model)
public ActionResult Product(int id){
var model= {
...
Id = id
}
//ViewBag.Id = id;
return View(model)
}
view:
#model ViewModel
{
var id = int.Parse(ViewBag.Id); // alternative sln.
}
#Html.Partial("~/Views/ProductLanding/product.cshtml", Model.Product(Model.Id))
I have been using the below method and it works for me you can also try this
#Html.Action(, , new { #<Parameter_name> = })
Eg:
#Html.Action("DetailsProducts", "CREDITNOTEs", new { #id = Model.ID })
So I'm trying to update ONLY specific data in my MVC application. Whenever I only edit a list view, I would edit the data (which works) but the rest of the database table would be NULL.
So for example -
Fields in List View
EmployeeID, FirsName, LastName, Email, Moderator, Admin
Fields not in list view
LoginID
So in my edit page, I have set up read-only for the info like EmployeeID, FirstName, LastName, and Email with two checkboxes for Moderator and Admin which are the only values I want to edit.
They work fine but when doing so, the data in the database for LoginID only becomes NULL.
Here is the code from my edit GET and POST methods
GET
public ActionResult Edit(int id)
{
EmpContext ec = new AppContext();
Employee e = ec.Employees.Single(x => x.Id == id);
return View();
}
POST
public ActionResult Edit(Employee employee)
{
if (ModelState.IsValid)
{
EmpContext ec = new EmpContext();
ec.Entry(employee).State = EntityState.Modified;
ec.SaveChanges();
return RedirectToAction("List");
}
return View(employee);
}
So, how would I stop this executing in the field LoginID within the database when there are no text boxes at all for LoginID, even on the edit page?
According to Attaching an existing but modified entity to the context
When you change the state to Modified all the properties of the entity
will be marked as modified and all the property values will be sent to
the database when SaveChanges is called.
Thus, this Entry method will update all the properties. For my recommendation, to update some Entity's columns only, you have to manually query the record and update desired properties only.
In your Edit (POST) method, change the Entry() way to:
EmpContext ec = new EmpContext();
Employee _employee = ec.Employees.Single(x => x.Id == employee.Id);
// TO-DO Update required properties only
_employee.FirstName = employee.FirstName;
ec.SaveChanges();
I have a fictional website in ASP.NET MVC4 that's designed to simulate a private jet hire company ticket booking system. However, I am struggling a bit when it comes to implementing the features I want to have, one of which is using a dropdown menu to store data into another database
To give you a better idea of what I'm really aiming towards
Users to log in to the website
Go to the flights page
Have a look at the flights
Eventually go on to the make a booking page
Then
Select their desired flight from a dropdown menu
Input the number of tickets they want to purchase. (The dropdown is working but the reset isn't implemented)
The user database should then check for the user's age (which is already
stored in the database) is between 18 and 64
If they're outside of that range, an error message should appear
and prevent them from booking a ticket.
If they're within that range, the amount of seats left should decrement by the number of tickets "purchased"
Also
The booking page should prompt the user to log in if they haven't already done so.
This is where it gets really confusing for me.
I have two pages related to the flights:
Page 1 (Flights.cshtml - shows a table of the available flights): http://gyazo.com/2ab67e35bdd1967e4a24706e398ba759
Page 2 (BookFlight shows a dropdown menu, allowing the user to select the flight they want): http://gyazo.com/67948e5e8be82c72f7ee0914dfa9b5f6
(Screenshot of the project files in solution explorer)
Here are my relevant files related to the flights table (on page 1)
https://gist.github.com/anonymous/144ed06e1d4f2011161e
Page 2 reads from the list on page 1 and here's how it's done:
View:
#model List<Project_v3.Models.FlightsTable>
#{
ViewBag.Title = "Book Flight | Open Airlines";
Layout = "~/Views/Shared/_MyLayout.cshtml";
}
<h2>Book A Flight</h2>
<select id='SelectedFlight' name='SelectedFlight'>
#foreach (var flight in Model)
{
<option value='#flight.FlightID'>#String.Format("{0} to {1}", flight.Departure, flight.Arrival)</option>
}
</select>
Controller:
public ActionResult BookFlight()
{
using (var context = new FlightsDBEntities())
{
// Get all of the flights within your table
var flights = context.FlightsTables.ToList();
// Pass the flights to your View
return View(flights);
}
}
My Question is
How do I make the data from the dropdown menu a field in another database table named 'Booking' for example? (I have not made this table yet). If that makes sense?
How do I take the information (from the dropdown) that the user has selected and store it with a press of a button? Is this even possible? Would anyone be able to show me a working example of this based on the code I listed above?
First you have to create a model where you will store the item that will be selected.
public class BookingModel
{
public string SelectedFlightId {get;set;}
public List<SelectListItem> Flights {get;set;}
}
You need to modify the Action that make use of the new model.
public ActionResult BookFlight()
{
using (var context = new FlightsDBEntities())
{
// Get all of the flights within your table
var flights = context.FlightsTables.ToList();
var booking = new BookingModel();
booking.Flights = flights.Select(f => new SelectListItem
{
Text = String.Format("{0} to {1}", f.Departure, f.Arrival),
Value = f.FlightID.ToString()
}).ToList();
return View(booking);
}
}
Modify the View to make use of our new Model
#model Project_v3.Models.BookingModel
#{
ViewBag.Title = "Book Flight | Open Airlines";
Layout = "~/Views/Shared/_MyLayout.cshtml";
}
<h2>Book A Flight</h2>
#using(Html.BeginForm())
{
#Html.DropDownListFor(x => x.SelectedFlightId, Model.Flights)
<input type="submit" value="Submit" />
}
Create a new Action that have the same name as the first action, but put HttpPost attribute. In this action you will get SelectedFlightId after the form was submited
[HttpPost]
public ActionResult BookFlight(BookingModel booking)
{
using (var context = new FlightsDBEntities())
{
if(ModelState.IsValid)
{
var flightId = Int32.Parse(booking.SelectedFlightId);
var flight = context.FlightsTables.First(f => f.FlightID == flightId);
var user = context.UsersTables.First(u => u.UserId == User.Identity.GetUserId());
user.Flights.Add(flight)
context.SaveChanges();
}
// repopulate again the flights (this can be cached and/or be refactored a under method)
var flights = context.FlightsTables.ToList();
booking.Flights = flights.Select(f => new SelectListItem
{
Text = String.Format("{0} to {1}", f.Departure, f.Arrival),
Value = f.FlightID.ToString()
}).ToList();
}
return View(booking);
}
I'll explain a quiet better here. I've this method wich returns me some lines of ma table according to a searchstring I informed in my textbox.
public ActionResult Index(string site, string searchString)
{
var user = from m in db.OrderDetails
select m;
if (!String.IsNullOrEmpty(searchString))
{
user = user.Where(s => s.Order.ClientID.Contains(searchString));
}
if (!String.IsNullOrEmpty(site))
{
user = user.Where(c => c.Order.SiteNumber.Contains(site));
}
return View(user);
}
In the same class, I've an other method which generate a pdf file (all the backend process is set up in a second project include in the first).
public ActionResult PrintOrders()
{
var user = from m in db.OrderDetails
select m;
return this.ViewPdf("Facture", "PrintView", user);
}
This second method, when it generate my pdf file, displays all the entries of my table. I would like that, when I click on my link (on the same page view wich display my table entries) for generate my pdf file, if I did a search before, I juste have fields that match my searchstring (or site string).
How can I implement it ? There is a way do to it ?
Thanks for your help, and sorry for the title which is maybe not too relevant. Also sorry for my english, hope you'll understand my aim.
EDIT INFORMATIONS
After looking, when I set up my PrintOrders() method like my Index() method as follow :
public ActionResult PrintOrders(string searchString, string username)
{
var user = from m in db.OrderDetails select m;
if (!String.IsNullOrEmpty(searchString))
{
user = user.Where(s => s.Order.ClientID.Contains(searchString));
}
if (!String.IsNullOrEmpty(site))
{
user = user.Where(c => c.Order.SiteNumber.Contains(site));
}
return this.ViewPdf("Facture Krys-Group", "PrintView", user);
}
and set my view like this :
#using (Html.BeginForm("PrintOrders", "Historic", FormMethod.Get))
{
Seach by ID : #Html.TextBox("searchString")
Search by Site : #Html.TextBox("site")
<input type="submit" value="Search" /></p>
}
then it works. But I've already the same form in my view for "Index" instead of "PrintOrders". How can I combine both ?
I am not sure I follow you completely but I think you achieve what you are looking for with the use of partial views. The form you mention can be a partial view that gets rendered into the pdf view and like that you really have one form but displayed in both pages. Hopefully I understood what you were after and this helps you.
I'm using a code-first approach to display data from multiple tables using SQL Server. For my C# semester project, I'm building a social networking website. In my index view I want to display data from two tables, that is, from Posts and Comments.
I'm trying a lot but nothing below is in my Index action.
First, I was using this but later I think it performs only a simple join between tables.
public ActionResult Index()
{
var myobj = DB.Comments.Include("Post").ToList();
return View(myobj);
}
If I use the SQL query below instead of above inside my Index action and pass them to the view, it generates an exception. How do I avoid that?
public ActionResult Index()
{
var myobj = from u in DB.Posts
join b in DB.Comments
on u.UserID equals b.UserID
into obj
from ua in obj.DefaultIfEmpty()
select new { userComments = (ua == null) ? "" : ua.UserComments, UserPosts = u.UserPosts };
return View(myobj);
}
where inside Index.cshtml I'm using a strongly typed View:
#model IEnumerable<myApp.Models.DB.Comment>
and then display all posts and comments using a foreach loop.
But it displays only those posts which postID is present in the Comments table (foreign key from post is in the comment table).
How would I display all posts along with their comments (if any)?
I'm using an .edmx file for the backend while for retrieving/adding data from the database I'm using a code-first approach.
Here's a code example:
private SocialNetworkingEntities net = new SocialNetworkingEntities();
public void Add(RegisterView user)
{
DB.UserInfo User = new DB.UserInfo();
User.Name = user.UserName;
User.Password = user.UserPassword;
User.Email = user.UserEmail;
User.Birthday = user.UserDOB;
User.Sex = user.UserSex;
net.UserInfoes.Add(User);
net.SaveChanges();
}
If you want to display the posts with optional comments, then Post and not Comment is your main model type. Also, you don't have to manually join tables like you do in your second approach - that is done by EF automatically.
So first use the pattern of your first approch and change it to return the posts. The comments are accessible by your navigation property (Posts):
public ActionResult Index()
{
var allPosts = DB.Posts.Include("Comments").ToList();
return View(allPosts);
}
Second, change the modeltype in your view to Post:
#model IEnumerable<myApp.Models.DB.Post>
Now you should be able to enumerate all Posts and optional the Comments:
#foreach (Post post in Model) {
// display post
foreach (Comment comment in post.Comments) {
// display comment
}
}
The problem with your second approach is that your View is expecting a ViewModel of type Comment. But if you look at the query you return an anonymous type instead of a comment.
In your first query you start with Comments and load all the Posts for the comments. This way you wouldn't get posts that don't have any comments.
I think the easiest way is to define an association from Posts to Comments and change your query to:
var myobj = DB.Posts.Include("Comments").ToList();
If you then modify your View to accept a Model of type Post everything should work.