I am doing a project in asp.net mvc. I want to show a particular person's details in the view. I have to join 2 tables to display data. For that I did:
Controller:
[HttpGet]
public ViewResult DisplayData()
{
ViewBag.Designation1up = new SelectList(db.Designations, "Designation1up", "DesignationInternal", "DesignationExternal");
return View();
}
[HttpPost]
public ActionResult DisplayData(Employee emp)
{
try
{
object s = Session["EmployeeID"];
var sessval = s.ToString();
var data1 = (from e in db.Employees.Where(c => c.EmployeeID == sessval) join d in db.Designations on e.Designation1up equals d.Designation1up select e).SingleOrDefault();
return View(data1);
}
catch (Exception e)
{
}
ViewBag.Designation1up = new SelectList(db.Designations, "Designation1up", "DesignationInternal",emp.Designation1up);
return View(emp);
}
The view:
<%# Page Language="C#" Inherits="System.Web.Mvc.ViewPage<ResourceTracking.ViewModel.AdminDetailsModel>" %>
<!DOCTYPE html>
<html>
<head runat="server">
<title>DisplayData</title>
</head>
<body>
<fieldset>
<legend>AdminDetailsModel</legend>
<div class="display-label">EmployeeID</div>
<div class="display-field"> <%: Html.DisplayFor(model => model.EmployeeID) %> </div>
<!--...(same DIV 4 other fields)-->
</fieldset>
</body>
</html>
My problem is that, when I debug the code, the compiler is not going into the HttpPost method. It's just debugging the HttpGet method and giving output, but unless HttpPost will run, output will not be proper. What should I do for this?
I think you're a little confused about how ASP.NET MVC works. Normally to display data on a view you will call the HttpGet action (DisplayData), create a model, populate it with the relevant data (the employee) and display it.
Something like this (untested)
[HttpGet]
public ViewResult DisplayData()
{
ViewBag.Designation1up = new SelectList(db.Designations, "Designation1up", "DesignationInternal", "DesignationExternal");
SomeModel model = new SomeModel();
object s = Session["EmployeeID"];
if (s != null)
{
var employeeId = s.ToString();
model.EmployeeData = GetEmployeeData(employeeId);
}
return View(model);
}
private Employee GetEmployeeData(string employeeId)
{
return (from e in db.Employees.Where(c => c.EmployeeID == employeeId)
join d in db.Designations
on e.Designation1up equals d.Designation1up
select e).SingleOrDefault();
}
Related
My first ever Ajax request is failing, and I'm not quite sure as to why.
I've used the MVC scaffolding in order to create a table (which uses a default #Html.Actionlink). However, I'm looking to include an 'edit' section on the same page via ajax requests.
So my table now has:
<td>
#Ajax.ActionLink("Edit", "Edit", new { id=item.OID}, new AjaxOptions {
UpdateTargetId = "editblock",
InsertionMode = InsertionMode.Replace,
HttpMethod = "GET" }
) |
As suggested here.
Within the same view i have a div defined as:
<div id="editblock">
Edit Section Here
</div>
And My controller is defined as:
public PartialViewResult Edit(int? id)
{
if (id == null)
{
return PartialView(new HttpStatusCodeResult(HttpStatusCode.BadRequest));
}
TableModel tablevar = db.TableModel.Find(id);
if (tablevar == null)
{
return PartialView(HttpNotFound());
}
return PartialView("Edit", tablevar );
}
[HttpPost]
[ValidateAntiForgeryToken]
public PartialViewResult Edit( TableModel tablevar )
{
if (ModelState.IsValid)
{
db.Entry(tablevar ).State = EntityState.Modified;
db.SaveChanges();
}
return PartialView("Edit",tablevar );
}
My "Edit.cshtml" looks like:
#model Project.Models.TableModel
<body>
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/jqueryval")
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
Could anyone suggest as to why this is failing, and what I should be doing instead to render this partial view onto the page (as currently it keeps redirecting to new page and not showing on 'index' screen)?
Place those scripts at the bottom of your view. By the time they execute your form isn't present (and therefore the auto-wireup fails). In general, you want <script> tags as close to the </body> tag as possible to your content is there before the script executes.
Other than that, you look fine.
I would like to pass a value from a link to a View and display the fields of the single record on the page.
Lets say I have #Html.ActionLink(item.Title, "Article/"+#item.ID, "News") which outputs /News/Article/1, I would need a Controller called NewsController with a /News/Article View.
I already have the following:
NewsController:
namespace WebApplication1.Controllers
{
public class NewsController : Controller
{
private WebApplication1Entities db = new WebApplication1Entities();
public ActionResult Article()
{
var articleModel = (from m in db.News where (m.Id == 1) && (m.Active == true) select m);
return View(articleModel);
}
[ChildActionOnly]
public ActionResult LatestNews()
{
var latestModel = (from m in db.News where (m.Id != 1) && (m.Active == true) select m);
return View(latestModel);
}
}
Not sure if I should use FirstOrDefault() as it can only be one record as the Id is unique, but unsure how to reference item objects inside the View without an IEnumerable list. At present the Id is set to 1 but I would like the recordset to reflect the Id passed.
Not sure what code to put inside the View, Article though, here is what I have so far:
Article.cshtml
#model IEnumerable<WebApplication1.Models.News>
#foreach (var item in Model) {
ViewBag.Title = #item.Title;
<div class="row">
<article class="span9 maxheight">
<section class="block-indent-1 divider-bot-2">
<h2>#item.Title</h2>
#item.Summary
#item.Content
</section>
</article>
<article class="span3 divider-left maxheight">
<section class="block-indent-1">
<h2>Latest News</h2>
#{ Html.RenderAction("LatestNews", "News"); }
</section>
</article>
</div>
}
LatestNews.cshtml
#{ Layout = null; }
#model IEnumerable<Shedtember.Models.News>
<ul class="nav sf-menu clearfix">
#foreach (var item in Model)
{
#Html.MenuLink(item.Title, "Article/"#item.ID, "News")
}
</ul>
This works for Id 1 but this needs to be dynamic.
Any help would be much appreciated :-)
In your RouteConfig class map a route as follows:
routes.MapRoute("Article", "Article/{id}", new {controller = "News", action = "Article"});
then in your Article method you can add and use the id parameter as follows:
public ActionResult Article(int id)
{
var articleModel = (from m in db.News where (m.Id == id) && (m.Active == true) select m);
return View(articleModel);
}
I am basically trying to display a dropdownlist on my data entry view, and the dropdownlist keeps giving me the error "An expression tree may not contain a dynamic operation". I have added "#Model MyModel" to the top of my view, but still can't get past this error. Does anyone have an idea of how to resolve this issue? I have a controller that looks like this
using MvcApplication1.Models;
namespace MvcApplication1.Controllers
{
public class MyController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult EnterInfo()
{
GetUT myGetUT = new GetUT();
ViewBag.uts = GetOptions();
return View(myGetUT);
}
[HttpPost]
public ActionResult EnterInfo(GetUT myGetUT)
{
ViewBag.uts = GetOptions();
return View(myGetUT);
}
private List<UT> GetOptions()
{
List<UT> uts = new List<UT>();
uts.Add(new UT() { ID = 1, Name = "1st" });
uts.Add(new UT() { ID = 2, Name = "2nd" });
uts.Add(new UT() { ID = 3, Name = "3rd" });
uts.Add(new UT() { ID = 4, Name = "4th" });
return uts;
}
}
}
and a view that looks like
#Model MyModel
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<title>EnterInfo</title>
</head>
<body>
<div>
#Html.DropDownListFor(x => x.UTID, new SelectList(ViewBag.uts, "ID", "Name", Model.UTID))
Enter an Amount :-<input type="text" name="Amount" /><br />
<input type="submit" value="Submit Info" />
</div>
</body>
</html>
Thanks for all the help.
Well, ViewBag is a dynamic type, so I assume that is what it is complaining about. Try putting public List<UT> UTs { get; set; } as a property on MyModel and change your helper to use the UTs property from your model. Like this:
Controller:
public ActionResult EnterInfo()
{
GetUT myGetUT = new GetUT();
myGetUT.UTs = GetOptions();
return View(myGetUT);
}
View:
#Html.DropDownListFor(x => x.UTID,
new SelectList(Model.UTs, "ID", "Name", Model.UTID))`
Edit: If it isn't obvious, your view should be typed to a GetUT type (because that's what you are passing in to the View() function in the EnterInfo action) - I assume that's what you mean when you said #Model MyModel. If not, change it to #Model GetUT and put the property on the GetUT class.
I have a class and create an instance and fill a property in my index but when I push the submit button in my view and return again to my index action the property of my class is null.
How can I save the data when I return to my action and retrieve it? Is it possible?
I used viewbag and viewdata in my index and fill theme but when returned to index action again all of theme were null :(
public class myclass
{
public string tp { get; set; }
}
public class HomeController : Controller
{
//
// GET: /Home/
myclass myc = new myclass();
public ActionResult Index()
{
myc.tp = "abc";
return View(myc);
}
}
View:
#model MvcApplication2.Controllers.myclass
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<title>Index</title>
</head>
<body>
#using (Html.BeginForm())
{
<input id="Submit1" type="submit" value="submit" />
}
</body>
</html>
simply use either GET or POST method in your Controller according to your form method like,
[HttpGet]
public ActionResult Index(string id)
{
myc.tp = id;
return View(myc);
}
In your HttpPost you can get the model and see it's properties if you provided input fields for the properties in your view.
[HttpPost]
public ActionResult Index(myclass myc)
{
//check the myc properties here
return View(myc);
}
Then in your View:
#using (Html.BeginForm())
{
#Html.TextBoxFor(m => m.tp)
Requirment: I have a drop down and a table on my cshtml page. The drop down displays a list of vendors and the details corresponding to selected vendor are displayed in table. I am submitting the form using jquery when the value of the drop down changes.
Problem: How to cath selected value of drop down in controller?
Code:
#Html.DropDownList("VendorList", new SelectList(Model.vendorList, "vendorId", "vendorName"))
#using (Html.BeginForm("VendorDetails", "VendorLookUp", FormMethod.Post, new { id = "vendorDetailsForm" }))
{
<div class="margin-10-top" >
<table id= "VendorDetail" class="VendorDetail">
........ details of vendor.........
</table>
</div>
}
<script type="text/javascript" charset="utf-8">
$(document).ready(function () {
$('#VendorList').change(function () {
$('#vendorDetailsForm').submit();
});
});
</script>
the code in my controller is:
[AcceptVerbs("POST")]
public ActionResult SearchResult(FormCollection collection)
{
try
{
string vendorName = collection["searchItem"].ToString();
vendorName = vendorName.Trim();
List<Vendor> vendorList = Queries.compiledVendorQuery(dbContext, vendorName).ToList<Vendor>();
if(vendorList.Count() == 0)
return View("EmptySearch");
Vendor selectedVendor = vendorList[0];
VendorDetails vendorDeatils = Queries.compiledVendorDetailsQuery(dbContext, selectedVendor.vendorId.ToString()).FirstOrDefault();
VendorResult vendorResult = new VendorResult();
vendorResult.vendorList = vendorList;
vendorResult.vendorDetails = vendorDeatils;
return View(vendorResult);
}
catch (Exception e)
{
return View("EmptySearch");
}
}
[AcceptVerbs("POST")]
public ActionResult VendorDetails(FormCollection collection)
{
**here comes the control after postback
require value of the selected item**
Vendor selectedVendor = ??
VendorDetails vendorDeatils = Queries.compiledVendorDetailsQuery(dbContext, selectedVendor.vendorId.ToString()).FirstOrDefault();
VendorResult vendorResult = new VendorResult();
vendorResult.vendorDetails = vendorDeatils;
return View(vendorResult);
}
Since you're not really using the FormCollection, you could just use an int (or whatever the ID is on your model) in your action method:
[HttpPost]
public ActionResult VendorDetails(int vendorId = 0)
{
Vendor selectedVendor = // Load from your data source using vendorId
... // Do the rest of your work
}
In your HTML, move your #Html.DropDownListFor() into your form, rename it to the argument name, then submit the form as normal. Since the display doesn't seem to have any affect on what gets sent to the server, I would pull this out and just leave the #Html.DropDownListFor() in the form:
#using (Html.BeginForm("VendorDetails", "VendorLookUp", FormMethod.Post, new { id = "vendorDetailsForm" }))
{
#Html.DropDownList("vendorId", new SelectList(Model.vendorList, "vendorId", "vendorName"))
}
<div class="margin-10-top" >
<table id= "VendorDetail" class="VendorDetail">
........ details of vendor.........
</table>
</div>
<script type='text/javascript'>
$(document).ready(function () {
$('#vendorId').change(function () {
$('#vendorDetailsForm').submit();
});
});
</script>
Edit
Take a look at this article about MVC's model binding for an idea of how vendorId gets injected from the submitted form. Basically, the binder will match property names with the name attribute (by default) to your model. In this case, our model is just an int.