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 })
Related
Hello again stackoverflow! Newbie still learning here, I am now trying to create a small MVC with entity framework application(website?). I've gotten to the point where I can create, a new user, edit, delete them. Now I've created a new page and from a dropdownlist I want to select a persons name (that I've entered on the other base) from the database, now after the dropdownlist is populated, I want to be able to click on their name and either automatically redirect to the persons edit page, or click an edit button that takes me to their page.
[dropddownlist] < This contains the names
[John Smith 1] < Now I would click on a name, the 1 represents his student ID and both "john" and "smith" are separate parts of the table in the database.
[John Smith 1] [Edit] < now that I have his name selected in the dropdownlist I can click the little edit button and it takes me to another part of my little project the edit page! localhost/employees/edit/1
In my drop down list controller I have this (FirstN is First Name and LastN is Last Name in the database).
public ActionResult Index(string ddl)
{
ViewBag.ddl = (from r in db.Students select r.FirstN + "," + r.LastN);
}
public ActionResult Edit(string ddl)
{
Student student = db.Students.Find(ddl);
if (student== null)
{
return HttpNotFound();
}
return View(student);
}
Under the view I have this
#Html.DropDownList("Edit", new SelectList(ViewBag.ddl));
#Html.ActionLink("Edit", "Edit", new SelectList(ViewBag.ddl))
This doesn't seem to be working and I'm not really getting anywhere. So I want to try a different approach on how to get there.
My question I'm asking help for is: I want to set their names to a value of their studentID (this is from the database and can't be hard coded FirstN: John LastN=Smith StudentID=1) but then click the edit or search button and go from localhost/EditStudent to localhost/student/edit/1 and it would take you to the "John Smith" edit page.
Thanks to anyone who takes the time to read this!
Ok... Let me explain you the way that I know.. Maybe someone else will have a more simple way...
I am explaining this without trying it in a code editor, So if there is any error that anyone notice, then please notify me.
I hope you need to get the selected value to the post method in controller.
Consider we have a Model name as Students. So getting our job done We need to create a Model as
public class StudentListModel
{
public List<Student> StudentList{ get; set;}
public SelectList StudentSelectList { get; set;}
public int SelectedStudentId { get; set;}
}
[HttpGet]
public ActionResult StudentList()
{
StudentListModel studentList = new StudentListModel();
studentList.StudentList = //Code to load the student.
studentList.StudentSelectList = new SelectList(studentList.StudentList, "StudentId", "StudentName");
return View(studentList);
}
And in View
#Html.DropDownListFor(m=>m.SelectedStudentId , Model.StudentSelectList, "Select Student")
Then in controller the post method will be like.
[HttpPost]
public ActionResult StudentList(StudentListModel studentListModel)
{
int SelectedStudentValue = studentListModel.SelectedStudentId;
// Do other operations with the id
return View();
}
I'm filling values to a session's like following to retrive those in _LayoutPartial view
if (userdata != null)
{
Session["userdata"] = new SampleViewModel { FirstName = userdata.UserFirstName, LastName = userdata.UserLastName };
FormsAuthentication.SetAuthCookie(loginmodel.UserName, false);
return RedirectToAction("Dashboard", "Home", new { username = loginmodel.UserName });
}
I want to retrive those values in _LayoutPartial View , So I tried somethin like following
<a class="sa">
(#Session["userdata"] as ProjectName.Models.SampleViewModel).FirstName
(#Session["userdata"] as ProjectName.Models.SampleViewModel).LastName
</a>
But this is not retrieving data properly . In this _LoginPartial I'm not Referencing any model also
You have your parenthesis in the wrong spot, and you need a double set - one for the casting (inner set) and one for the razor execution (outer set). It needs to be
#((Session["userdata"] as ProjectName.Models.SampleViewModel).Name)
Here is a paste of the action method MovieCustomer in the EverythingController.
The Viewmodel is used to Combine two Models: Customer & Movies, and is populated with information from the Database via the ApplicationDbContext (_context).
The Routeing works successfully and renders the page when there are values for MovieId and CustomerId
e.g. /Everything/MovieCustomer/1/1
I want the page to also load if one or both of the values are null. So far both of the int parameters were made nullable and there is an if statement in the method to change the parameters to 1 if either is null.
So far if the values are null the browser returns a 404 error.
How can I get the page to function when one or either of the parameters are null? Thanks
[Route("Everything/MovieCustomer/{movieId}/{customerId}")]
public ActionResult MovieCustomer(int? movieId, int? customerId)
{
var viewmodel = new ComboViewModel
{
_Customers = new List<Customer>(),
_Movies = new List<Movies>(),
_customer = new Customer(),
_movie = new Movies()
};
viewmodel._Customers = _context.Customers.ToList();
viewmodel._Movies = _context.Movies.ToList();
if (!movieId.HasValue)
movieId = 1;
if (!customerId.HasValue)
customerId = 1;
viewmodel._customer = viewmodel._Customers.SingleOrDefault(a => a.Id == customerId);
viewmodel._movie = viewmodel._Movies.SingleOrDefault(a => a.Id == movieId);
return View(viewmodel);
}
You can achieve this using separate routes, or change your parameters to be optional.
When using 3 attributes, you add separate routes for each of the options that you have - when no parameters are specified, when only movieId is specified, and when all 3 parameters are specified.
[Route("Everything/MovieCustomer/")]
[Route("Everything/MovieCustomer/{movieId}")]
[Route("Everything/MovieCustomer/{movieId}/{customerId}")]
public ActionResult MovieCustomer(int? movieId, int? customerId)
{
// the rest of the code
}
Alternatively you an combine change your route parameters to optional (by adding ? in route definition) and this should cover all 3 cases that you have:
[Route("Everything/MovieCustomer/{movieId?}/{customerId?}")]
public ActionResult MovieCustomer(int? movieId, int? customerId)
{
// the rest of the code
}
Keep in mind that neither sample supports the case where you provide only customerId.
Keep in mind that neither sample supports the case where you provide only customerId.
Check it out. I think you can use the multiple route method with EVEN ANOTHER route like this if you do want to provide only customerId:
[Route("Everything/MovieCustomer/null/{customerId}")]
Interstingly, I had to add optional parameter to the signature as well for it to work from Angular client like so:
[HttpGet]
[Route("IsFooBar/{movieId?}/{customerId?}")]
[Route("IsFooBar/null/{customerId?}")]
public bool IsFooBar(int? movieId = null, int? customerId = null)
{
// the rest of the code
}
In Angular
public IsFoobar(movieId: number | null, customerId: number | null): Observable<boolean> {
return this.httpService.get<boolean>(`api/IsFooBar/${movieId}/${customerId}`);
}
I'm developing a site using MVC5 in VS2013, and I have an entity, for example:
Subcategory {
ID_Subcategory int,
ID_Category int,
ID_Product int,
Value string
}
In the Create View it shows me DropDowns for the foreign keys.
Now, I reach this page/action from the Product/Edit/5 view using this:
<a href="#Url.Action("Create", "Subcategory", new { ID_Product = Model.ProductID })">
and in my Create action I have this
// GET: Subcategory/Create
public ActionResult Create(int? ID_Product )
{
ViewBag.ID_Category = new SelectList(db.Category, "ID_Category ", "Description");
ViewBag.ID_Product = new SelectList(db.Product, "ID_Product ", "Name");
Categories categories = new Categories();
categories.ProductID = (int)ID_Product ;
return View(categories);
}
And it works fine, now the Product which I came from is set in the corresponding DropDown, but the URL looks like this:
http://localhost:54372/Subcategory/Create?ID_Product=2
And I think it could be a security risk, so, please tell me:
Could it be a security risk?
Is it to show the ID/foreign key in the URL a bad practice?
I don't want to show the foreign ID in the URL, so, Is there a better way to pass the foreign key in this context?
thanks
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.