ASP.NET mvc pass parameter to form - asp.net-mvc

1) How to pass id in AddBookInCategory form in #Html.EditorFor(model=>model.CategoryID).
2) And second how after adding new item in public ActionResult AddBookInCategory(Books book) return to category with id it must be something like return RedirectToAction("ShowBooksFromCategory", 1); but it does not work.
HomeController:
public class HomeController : Controller
{
//
// GET: /Home/
TEntities TE = new TEntities();
public ActionResult Index()
{
return View();
}
public ActionResult ShowCategories()
{
return View(TE.Category.ToList());
}
public ActionResult ShowBooksFromCategory(int id)
{
return View(TE.Books.Where(key => key.CategoryID == id).ToList());
}
public ActionResult AddBookInCategory(int id)
{
return View();
}
[HttpPost]
public ActionResult AddBookInCategory(Books book)
{
TE.Books.Add(book);
TE.SaveChanges();
return View();
//return RedirectToAction("ShowBooksFromCategory", 1);
}
}
AddBookInCategory.cshtml:
#model TestDataBase.Models.Books
#{
ViewBag.Title = "AddBookInCategory";
}
<h2>AddBookInCategory</h2>
#using(#Html.BeginForm())
{
<p>Book Name:</p>
<br />
#Html.EditorFor(model=>model.BookName)
<p>Category:</p>
<br />
#Html.EditorFor(model=>model.CategoryID)
<input type="submit" value="Create"/>
}
Index.cshtml
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
#Html.ActionLink("ShowCategories", "ShowCategories")
ShowBooksFromCategory.cshtml
#model IEnumerable<TestDataBase.Models.Books>
#{
ViewBag.Title = "ShowBooksFromCategory";
}
<h2>ShowBooksFromCategory</h2>
<table>
#foreach(var item in Model)
{
<tr>
<td>
#item.BookName
</td>
</tr>
}
</table>
#Html.ActionLink("Add item", "AddBookInCategory", new {id=Model.Select(key=>key.CategoryID).FirstOrDefault() })
ShowCategories.cshtml
#model IEnumerable<TestDataBase.Models.Category>
#{
ViewBag.Title = "ShowCategories";
}
<h2>ShowCategories</h2>
<table>
#foreach(var item in Model )
{
<tr>
<td>
#item.CategoryName
</td>
<td>
#Html.ActionLink("ShowBooksFromCategory", "ShowBooksFromCategory", new { id=item.CategoryID})
</td>
</tr>
}
</table>
Models:
public partial class Books
{
public int CategoryID { get; set; }
public string BookName { get; set; }
public int BookID { get; set; }
}
public partial class Category
{
public int CategoryID { get; set; }
public string CategoryName { get; set; }
}

Hi #A191919 To redirect with an int you can do the following (this is exactly the same thing you did within your actionlink to get the first form..)
return RedirectToAction("ShowBooksFromCategory", new { id = book.CategoryID });
To get the ID into your form you could use ViewBag.
public ActionResult AddBookInCategory(int id)
{
ViewBag.id = id;
return View();
}
The use the viewbag value to fill in your form input.

Related

Get Total of a field in mvc entitymodel 1st

I am trying to get total on my view.
I am confused what should i do? Please help me out..
I am not understanding where should i use query and ofc I need it in my view to show but how?
Model class
namespace BOL1
{
public class ADetailsVm
{
public List<BOL1.tbl_Transiction> Payables { get; set; }
public List<BOL1.tbl_Transiction> Reciveables { get; set; }
}
}
DbContext
public partial class bankingEntities : DbContext
{
public bankingEntities()
: base("name=bankingEntities")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public virtual DbSet<tbl_Accounts> tbl_Accounts { get; set; }
public virtual DbSet<tbl_Transiction> tbl_Transiction { get; set; }
public virtual DbSet<tbl_TransictionType> tbl_TransictionType { get; set; }
public DbSet<ADetailsVm> ADetailsVm { get; set; }
}
}
Controller
public class Details : Controller
{
private TransictionBs objbs;
public Details()
{
objbs = new TransictionBs();
}
// GET: Shinwari/AccountDetails
[HttpGet]
public ActionResult Index(int accountid)
{
ADetailsVm v = new ADetailsVm();
//Load both the collection properties
v.Payables = objbs.GetALL().Where(p => p.AId == accountid && p.tbl_TransictionType.Type.Contains("Payable")).ToList();
v.Reciveables = objbs.GetALL().Where(r => r.AId==accountid && r.tbl_TransictionType.Type.Contains("Reciveable")).ToList();
return View(v);
View
#model BOL1.ADetailsVm
#{
ViewBag.Title = "Index";
}
<h2>AccountDetails</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table id="Payables" class="table">
<tr>
<th>
Date
</th>
<th>
Discription
</th>
<th>
Amount
</th>
</tr>
#foreach (var item in Model.Payables)
{
<tr>
<td>
#item.Date
</td>
<td>
#item.TDiscription
</td>
<td>
#item.Amount
</td>
</tr>
}
</table>
Use the LINQ Sum extension method on the Amount property(assuming it is of numeric type) of your Payables collection property of the view model.
<h2> #Model.Payables.Sum(s=>s.Amount) </h2>
Or if you do not like adding so much C# code in razor views(like me :)), You may add a new property to store the total in your view model.
public class ADetailsVm
{
public decimal TotalPayableAmount { set;get;}
public List<BOL1.tbl_Transiction> Payables { get; set; }
public List<BOL1.tbl_Transiction> Reciveables { get; set; }
}
and in your action method, call the Sum method and set the value to our new TotalPayableAmount property.
public ActionResult Index(int accountid)
{
var v = new ADetailsVm();
v.Payables = objbs.GetALL().Where(p => p.AId == accountid &&
p.tbl_TransictionType.Type.Contains("Payable")).ToList();
v.Reciveables = objbs.GetALL().Where(r => r.AId == accountid &&
r.tbl_TransictionType.Type.Contains("Reciveable")).ToList();
v.TotalPayableAmount= v.Payables.Sum(s=>s.Amount)
return View(v);
}
and in your view
#model ADetailsVm
<h2>#Model.TotalPayableAmount</h2>

For each loop with submitting form

Model Room:
public class Room
{
public int Id { get; set; }
public string NumberRoom { get; set; }
public double CostPerNight { get; set; }
public virtual Category Category { get; set; }
}
My view model code
public class RoomModel
{
public IList<Room> Rooms { get; set; }
}
My Razor code:
#model hotel.Models.RoomModel
#using (Html.BeginForm("ComfortLevelView", "Category"))
{
for (int i = 0; i < Model.Rooms.Count(); i++)
{
<table class="simple-little-table" cellspacing='0'>
<tr>
<td>#Html.DisplayFor(m => Model.Rooms[i].NumberRoom) </td>
<td>#Html.DisplayFor(m => Model.Rooms[i].Categoryid)</td>
<td>#Html.DisplayFor(m => Model.Rooms[i].NumberOfSeats) </td>
<td>
#{ var result = Model.Rooms[i].CostPerNight * numberNights; }
<p>#ViewBag.NumberNights ночей</p>:#result
</td>
<td>
<input type="submit" id="submit" value="Booking" />
</td>
</tr>
</table>
</div>
}
}
Controller:
public ActionResult ComfortLevelView(int NumberNights, int CategoryId, int NumberPeoples ,DateTime SelectedDate)
{
IRoomService roomService = new RoomService();;
return View(roomService.GetRoomsByCategory(CategoryId, SelectedDate, NumberNights, NumberPeoples));
}
[HttpPost]
public ActionResult ComfortLevelView(RoomModel model)
{
//
}
The model item passed into the dictionary is of type 'System.Data.Entity.Infrastructure.DbQuery`1[Hotel.BusinessObject.Room]', but this dictionary requires a model item of type 'hotel.Models.RoomModel'.
The error message is self explanatory. You have this in your view
#model hotel.Models.RoomModel
but you pass an instance of System.Data.Entity.Infrastructure.DbQuery<Hotel.BusinessObject.Room> to your view because of this line of code in your controller
return View(roomService.GetRoomsByCategory(CategoryId, SelectedDate, NumberNights, NumberPeoples));
You need to pass an instance of RoomModel instead of System.Data.Entity.Infrastructure.DbQuery<Hotel.BusinessObject.Room>. I would suggest changing your controller code to below
public ActionResult ComfortLevelView(int NumberNights, int CategoryId, int NumberPeoples, DateTime SelectedDate)
{
IRoomService roomService = new RoomService();
var rooms = roomService.GetRoomsByCategory(CategoryId, SelectedDate, NumberNights, NumberPeoples);
RoomModel model = new RoomModel();
model.Rooms = rooms.ToList();
return View(model);
}

Use Html.DropDownListFor to get a selected value

I am trying to use Html.DropDownListFor to build a dropdown list and get the user selected value. I can get the list to display but cannot figure out how to get the link to pass the selected value.
I have the following model:
public partial class ProductVariant
{
public int ID { get; set; }
public string Sku { get; set; }
}
The following ViewModel:
public class SkuToDiscountViewModel
{
public int ID { get; set; }
public string Sku { get; set; }
public IEnumerable<ProductVariant> Products { get; set; }
}
The following Controller action:
public ViewResult Index()
{
SkuToDiscountViewModel sModel = new SkuToDiscountViewModel();
List<ProductVariant> prodSkus = db.ProductVariants.ToList();
sModel.Products = prodSkus;
return View(sModel);
}
The following view:
#model mySpace.ViewModel.SkuToDiscountViewModel
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
#using(Html.BeginForm())
{
Html.DropDownListFor(x=>x.ID,
new SelectList(Model.Products,"ID", "Sku", Model.ID), " select ")
<p>
#Html.ActionLink("Edit", "Edit")
</p>
}
Any help is appreciated.
You need to a submit button to your form:
#model mySpace.ViewModel.SkuToDiscountViewModel
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
#using(Html.BeginForm())
{
Html.DropDownListFor(x=>x.ID,
new SelectList(Model.Products,"ID", "Sku", Model.ID), " select ")
<p>
<input type="submit" value="Save" />
</p>
}
Then you need to add an Action to your controller like this:
[HttpPost]
public ActionResult Index(SkuToDiscountViewModel postedModel)
{
// postedModel.ID will contain the value selected in the drop down list
}

How do I use the DropDownList in ASP.NET MVC 3

I am new to MVC and am trying to populate a DropDownList in my view with a list of 'rules' from my controller. When I do it the way listed, I just get a dropdownlist with a bunch of items that say CellularAutomata.Models.Rules. I know I am doing this incorrectly, I'm just wondering how I actually get it to show the rule description for each rule in the dropdownlist.
I have a Model
public class Rule
{
public int ID { get; set; }
public int Name { get; set; }
public string Description{ get; set; }
public Rule(int name, string description)
{
Name = name;
Description = description;
}
public Rule()
{
Name = 0;
Description = "";
}
}
A Controller
public ActionResult Index()
{
var rules = from rule in db.Rules
select rule;
return View(rules.ToList());
}
And a view
#model IEnumerable<CellularAutomata.Models.Rule>
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<table>
<tr>
<td>
#Html.DropDownList("Test", new SelectList(Model))
</td>
</tr>
</table>
You could have a view model:
public class MyViewModel
{
public string SelectedRuleId { get; set; }
public IEnumerable<Rule> Rules { get; set; }
}
and then in your controller:
public ActionResult Index()
{
var model = new MyViewModel
{
Rules = db.Rules
};
return View(model);
}
and in the view:
#model CellularAutomata.Models.MyViewModel
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
#Html.DropDownListFor(
x => x.SelectedRuleId,
new SelectList(Model.Rules, "ID", "Description")
)

Binding difficulty upon postback of list

I am having the difficulty to post back the new data being entered. It seems that the data sent to the view are sent back to the controller, despite changes made to the data before submit.
My code is as follows:
Controller
public class GroupRateController : Controller
{
//
// GET: /GroupRate/
public ActionResult Index()
{
GroupRateModel model = new GroupRateModel();
return View(model);
}
[HttpPost]
public ActionResult Index(GroupRateModel model)
{
model.Save(model);
return View(model);
}
}
View
#model MvcApplication1.Models.GroupRateModel
#{
View.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Index</h2>
#using (Html.BeginForm())
{
#Html.ValidationSummary()
<table>
<thead>
</thead>
<tr><th>Rate Group</th><th>Default Amount</th><th>Client Amount</th></tr>
#foreach (var item in #Model.ClientRateDetails)
{
<tr><td>#item.RateGroupName</td><td align="right">#Html.DisplayFor(m => #item.RateGroupID)</td><td>#Html.EditorFor(model => item.ClientRate)</td></tr>
}
</table>
<p> <input type ="submit" value="Save" id="submit" /></p>
}
Model
using System.ComponentModel.DataAnnotations;
namespace MvcApplication1.Models
{
public class GroupRateModel
{
public List<ClientRateDetailsModel> ClientRateDetails = new List<ClientRateDetailsModel>() ;
public string Name { get; set; }
public GroupRateModel()
{
ClientRateDetails.Add(new ClientRateDetailsModel
{
RateGroupID = 1,
RateGroupName = "Test1",
ClientRate = 100
});
ClientRateDetails.Add(new ClientRateDetailsModel
{
RateGroupID = 2,
RateGroupName = "Test2",
ClientRate = 200
});
ClientRateDetails.Add(new ClientRateDetailsModel
{
RateGroupID = 3,
RateGroupName = "Test3",
ClientRate = 300
});
}
public void Save(GroupRateModel model)
{
foreach (var item in model.ClientRateDetails)
{
//...;
}
}
}
public class ClientRateDetailsModel
{
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:00.00}", NullDisplayText = "")]
[Range(0, (double)decimal.MaxValue, ErrorMessage = "Please enter a valid rate")]
public decimal? ClientRate { get; set; }
public int? RateGroupID { get; set; }
public string RateGroupName { get; set; }
}
}
This might be because the names of your input controls don't have correct names for the model binder to be able to fetch the values correctly. Also I see that the ClientRateDetails is not a property but a field in your model which won't be bound correctly. So here's how I would suggest you to improve your code:
Start with the model:
public class GroupRateModel
{
public IEnumerable<ClientRateDetailsModel> ClientRateDetails { get; set; }
public string Name { get; set; }
public GroupRateModel()
{
// Remark: You cannot assign your ClientRateDetails collection here
// because the constructor will be called by the default model binder
// in the POST action and it will erase all values that the user
// might have entered
}
public void Save(GroupRateModel model)
{
foreach (var item in model.ClientRateDetails)
{
//...;
}
}
}
public class ClientRateDetailsModel
{
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:00.00}", NullDisplayText = "")]
[Range(0, (double)decimal.MaxValue, ErrorMessage = "Please enter a valid rate")]
public decimal? ClientRate { get; set; }
public int? RateGroupID { get; set; }
public string RateGroupName { get; set; }
}
then a controller:
public class HomeController: Controller
{
public ActionResult Index()
{
var model = new GroupRateModel();
model.ClientRateDetails = new[]
{
new ClientRateDetailsModel
{
RateGroupID = 1,
RateGroupName = "Test1",
ClientRate = 100
},
new ClientRateDetailsModel
{
RateGroupID = 2,
RateGroupName = "Test2",
ClientRate = 200
},
};
return View(model);
}
[HttpPost]
public ActionResult Index(GroupRateModel model)
{
model.Save(model);
return View(model);
}
}
and then the corresponding view:
#model MvcApplication1.Models.GroupRateModel
#{
View.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Index</h2>
#using (Html.BeginForm())
{
#Html.ValidationSummary()
<table>
<thead>
<tr>
<th>Rate Group</th>
<th>Default Amount</th>
<th>Client Amount</th>
</tr>
</thead>
#Html.EditorFor(x => x.ClientRateDetails)
</table>
<p><input type ="submit" value="Save" id="submit" /></p>
}
and then have a corresponding editor template (~/Views/Home/EditorTemplates/ClientRateDetailsModel.cshtml):
#model MvcApplication1.Models.ClientRateDetailsModel
<tr>
<!-- Make sure you include the ID as hidden field
if you want to get it back inside the POST action
-->
#Html.HiddenFor(x => x.RateGroupID)
<td>#Model.RateGroupName</td>
<td align="right">#Model.RateGroupID</td>
<td>#Html.EditorFor(x => x.ClientRate)</td>
</tr>

Resources