Automatically call controller method and generate partial view. How? - c#

I want to automatically generate a list in a partial view.
_Layout.cshtml
#Html.Partial("../Transaction/_Transaction")
TransactionController
public JsonResult transactionlist()
{
List<Transaction> TransactionList = new List<Transaction>().ToList();
string Usercache = MemoryCache.Default[User.Identity.Name] as string;
int UsercacheID = Convert.ToInt32(Usercache);
if (Usercache == null)
{
int UserID = (from a in db.UserProfiles
where a.UserName == User.Identity.Name
select a.UserId).First();
UsercacheID = UserID;
MemoryCache.Default[User.Identity.Name] = UsercacheID.ToString();
}
var Account = (from a in db.UserAccount
where a.UserId == UsercacheID
select a).First();
var DBTransaction = from a in db.Transaction
where a.AccountId == Account.AccountId
select a;
var DBTransactionList = DBTransaction.ToList();
for (int i = 0; i < DBTransactionList.Count; i++)
{
TransactionList.Add(DBTransactionList[i]);
}
ViewBag.acountsaldo = Account.Amount;
return Json(TransactionList, JsonRequestBehavior.AllowGet);
}`
How should my _Transaction.cshtml be coded to make a simple list without submit buttons etc.?

One way is to have a page return a list of items and feed them into your partial.
function ActionResult GetMainTransactionView()
{
List<Transaction> transactions=GetTransactions();
return PartialView("TransactionIndex",transactions);
}
TransactionIndex.cshtml
#model List<Transaction>
#Html.Partial("../Transaction/_Transaction",model)
Main.chtml
<a id="transactionLink" href='#Url.Action("GetMainTransactionView","Transaction")'/>

You should call your controller action and have it return your partial view. Also, use a view model instead of viewbag.
Layout or parent view/partial view:
#Html.Action("Transaction", "YourController")
Partial view:
#model TransactionModel
#foreach (Transaction transaction in Model.TransactionList) {
// Do something with your transaction here - print the name of it or whatever
}
View Model:
public class TransactionModel {
public IEnumerable<Transaction> TransactionList { get; set; }
}
Controller:
public class YourController
{
public ActionResult Transaction()
{
List<Transaction> transactionList = new List<Transaction>().ToList();
// Your logic here to populate transaction list
TransactionModel model = new TransactionModel();
model.TransactionList = transactionList;
return PartialView("_Transaction", model);
}
}

Related

Perform CRUD in controller with ViewModel in ASP.NET MVC

From my two models Student and InventoryRecord. I created a ViewModel named TestViewModel. I'm confused as to how do I write my controller?
public class TestViewModel
{
//from Student model
[Key]
public string UserID { get; set; }
public string PhoneNumber{ get; set; }
public string Address{ get; set; }
//other properties
//from Inventory model
public string FathersName { get; set; }
public string FathersAddress { get; set; }
//other properties
}
When I'm using only my main model Student. This is how I write my controller:
// GET: Students/CreateEdit
public ActionResult InventoryRecord()
{
var currentUserId = User.Identity.GetUserId();
var newid = db.Students.FirstOrDefault(d => d.UserID == currentUserId);
if (newid == null)
{
newid = db.Students.Create();
newid.UserID = currentUserId;
db.Students.Add(newid);
}
Student student = db.Students.Find(newid.UserID);
if (student == null)
{
return HttpNotFound();
}
return View(student);
}
// POST: Students/CreateEdit
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult InventoryRecord(Student student)
{
var currentUserId = User.Identity.GetUserId();
var userName = User.Identity.GetUserName();
var u = db.Students.FirstOrDefault(d => d.UserID == currentUserId);
if (u == null)
{
u = db.Students.Create();
u.UserID = currentUserId;
db.Students.Add(u);
}
if (ModelState.IsValid)
{
u.PhoneNumber = student.PhoneNumber;
u.Address = student.Address;
//other properties
db.SaveChanges();
TempData["Message"] = "User: " + userName + ", details successfully updated!";
}
return View(student);
}
Now, I'm really confused how to proceed here. How should I write my controller if I'm using my TestViewModel? Someone please point me in the right direction. Thank you.
Well personally I would move the code out of the controller.
However for example you just need to create an instance of your TestViewModel and pass that to your view. You may also need to update your View if you specific the model in the cshtml.
public ActionResult InventoryRecord()
{
var currentUserId = User.Identity.GetUserId();
var newid = db.Students.FirstOrDefault(d => d.UserID == currentUserId);
if (newid == null)
{
newid = db.Students.Create();
newid.UserID = currentUserId;
db.Students.Add(newid);
}
Student student = db.Students.Find(newid.UserID);
if (student == null)
{
return HttpNotFound();
}
TestViewModel model = new TestViewModel
{
UserID = student.UserId,
PhoneNumber = student.PhoneNumber,
//add the rest.
};
return View(model);
}
Rather than returning Student , return TestViewModel
Student student = db.Students.Find(newid.UserID);
if (student == null)
{
return HttpNotFound();
}
TestViewModel tvm = new TestViewModel()
{
UserID =student.Id,
PhoneNumber = student.PhoneNumber,
Address= student.Address
};
return View(tvm);
}
and second method will be
public ActionResult InventoryRecord(TestViewModel tvm)

ASP.NET MVC : Attends / Likes Post

I have an Event with info about it on a Display Event View. On that view, I am trying to to make Attend functuality, similar to Liking, but I have little problems. My logic is very simple and I would like to keep it so: on click, it will increase int Attends by 1, but ...
First-I am getting inside the if(events==null)... And second is there a way to make it clickable once per User?
Here is my code:
Model:
[Key]
public int Id { get; set; }
public string EventName { get; set; }
...
public int Attends { get; set; }
Event Create Action:
//POST: Event/Create
[HttpPost]
public ActionResult Create(EventViewModel model)
{
if (ModelState.IsValid)
{
using (var database = new EventSpotDbContext())
{
var events = new Event(model.EventName,...);
...
events.Attends = 0;
database.Events.Add(events);
database.SaveChanges();
return RedirectToAction("Main");
}
}
return View(model);
}
Event Attend Action:
public ActionResult Attend(int? id)
{
using (var database = new EventSpotDbContext())
{
var events = database.Events.FirstOrDefault(a => a.Id == id);
if (events == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
events.Attends += 1;
database.SaveChanges();
}
return RedirectToAction("Details");
}
Event Details Action:
//GET: Event/Details
public ActionResult Details(int? id)
{
using (var database = new EventSpotDbContext())
{
var events = ... .First();
return View(events);
}
}
Details View
#model EventSpot.Models.Event
...
#Html.ActionLink("Attend Event", "Attend", "EventController", new {#id=Model.Id} )
#Model.Attends
#Html.ActionLink("Attend Event", "Attend", "EventController", new {#id=Model.Id}, null )
the isse that he was dealing with {#id=Model.Id} as html attributes not route attributes

Iterating over a session variable in view

I am wondering how can an iterate over a session , to which I am assigning a list of string in an action method.
I want to display each of the elements in the session as links via the for loop.
Any help is appreciated.
Here is my index method :
public ActionResult Index()
{
Session["num"] = Posts;
//Posts = new List<string> { "element1", "element2", "element3" };
return View();
}
And here is my view :
<h2>Index</h2>
#foreach (#item c in #Session["num"])
{
}
You will need to cast your session variable since it's an object.
Something like...
#{
var posts = Session["num"] as List<string>;
if (posts != null) {
foreach (var item in posts) {
...
}
}
}
You have tagged this question as asp.net-mvc, why not take advantage of the framework?
Model
class MyModel
{
public List<string> Posts { get; set; }
}
View (Index.cshtml)
#model MyModel
<h2>Index</h2>
#foreach(var post in Model.Posts)
{
<span>#post</span>
}
Controller
public ActionResult Index()
{
var model = new MyModel();
model.Posts = Posts; //Posts = new List<string> { "element1", "element2", "element3" };
return View(model);
}

Mvc how to keep dropdownlist selected value if ModelState is not valid

I am trying to keep dropdownlist selected value if ModelState is not valid
Because i want to keep the data the user selected even if the ModelState is not
valid
My code looks like this
Get Method:
[HttpGet]
public ActionResult Edit(int? Id)
{
using (var db = new NewsDatabaseEntities())
{
db.Configuration.LazyLoadingEnabled = false;
var Result = (from n in db.News.Include("Categories")
from c in db.Categories
where n.NewsId == Id
select new { news = n, neweCategories = n.Categories, cate = c }).ToList();
News NewsDetails = (from news in Result
select new News
{
NewsId = news.news.NewsId,
NewsTitle = news.news.NewsTitle,
NewsBody = news.news.NewsBody,
NewsImagePath = news.news.NewsImagePath,
Categories = news.neweCategories
}).FirstOrDefault();
var AllCategories = (from c in Result
select new Category
{
CategoryId = c.cate.CategoryId,
CategoryName = c.cate.CategoryName
}).ToList();
if (NewsDetails != null)
{
var model = new NewsViewModel();
model.NewsId = NewsDetails.NewsId;
model.AllCategories = AllCategories;
model.Categories = NewsDetails.Categories;
model.NewsTitle = NewsDetails.NewsTitle;
model.NewsBody = NewsDetails.NewsBody;
model.NewsImagePath = NewsDetails.NewsImagePath;
Session["AllCategories"] = new MultiSelectList(AllCategories, "CategoryId", "CategoryName", model.Categories.Select(J => J.CategoryId).ToArray());
Session["model"] = model;
return View(model);
}
else
{
return RedirectToAction("Index", "Home");
}
}
return View();
}
Post Method:
[HttpPost]
[ValidateInput(false)]
public ActionResult Edit(NewsViewModel model,FormCollection col)
{
if (!ModelState.IsValid)
{
model = (NewsViewModel)Session["model"];
return View(model);
}
View:
#Html.DropDownListFor(c => c.SelectedCategoriesIds, (MultiSelectList)Session["AllCategories"], new { id = "DropDownList1", multiple = "multiple", #class = "form-control" })
Because you are overwriting the view model object(which has the selected option value) with your session data which you set in your GET action.
You should read the selected option value to a temp variable and use that.
[HttpPost]
[ValidateInput(false)]
public ActionResult Edit(NewsViewModel model,FormCollection col)
{
if (!ModelState.IsValid)
{
var selected= model.SelectedCategoriesIds;
model = (NewsViewModel)Session["model"];
model.SelectedCategoriesIds =selected;
return View(model);
}
//save and return something**strong text**
}
A better solution is not not use session here. You may simply read the values again from your db table/or cache. Also for rendering the dropdown, you may simply add a property to your view model and use that.
public class NewsViewModel
{
public List<SelectListItem> AllCategories {set;get;}
//Other properties
}
and in your GET action, instead of setting the categories to Session, set it to this property
public ActionResult Edit(int? id)
{
var vm = new NewsViewModel();
vm.AllCategories = GetCategories();
return View(vm);
}
private IEnumerable<SelectListItem> GetCategories()
{
return db.Categories
.Select(s=>new SelectListItem { Value=s.Id.ToString(),
Text=s.Name).ToList();
}
and in your view
#model NewsViewModel
#using(Html.BeginForm())
{
<label> Select items <label>
#Html.ListBoxFor(s=>s.SelectedCategoriesIds,AllCategories )
<input type="submit" />
}
Now in your HttpPost action, when model validation fails, you do not need to use session, just call the same method to re-load the AllCategories property.
if (!ModelState.IsValid)
{
model.AllCategories=GetCategories();
return View(model);
}

Two dropdowns in one view, second dependent on what is selected on first

Just started messing around with MVC and have been trying to accomplish this by looking at this example:
http://forums.asp.net/t/1670552.aspx
I keep getting this error:
Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.
Line 9: #using (Html.BeginForm("Index","Home",FormMethod.Post, new{id = "ID"})){
Line 10: #Html.DropDownListFor(m=>m.id, new SelectList(Model.list, "id","name"),"selectThis")
Line 11: }
Here is the code:
Model classes (stupid names, I know):
These are in a console application used only to store models.
namespace Model
{
public class Model
{
public int id { get; set; }
public string name { get; set; }
}
public class List
{
public int id { get; set; }
public List<Model> list = new List<Model>();
}
public class subModel
{
public int id { get; set; }
public int modId { get; set; }
public string name { get; set; }
}
public class subList
{
public List<subModel> list = new List<subModel>();
}
}
Controller: (was populating subList.list and List.list with methods in the class, but decided to try it this way now, was getting the same error)
namespace DropboxTest.Controllers
{
public class HomeController : Controller
{
//
// GET: /Model/
public ActionResult Index()
{
LoadModel();
return View();
}
[ValidateInput(false)]
[AcceptVerbs("POST")]
public ActionResult Index([Bind(Exclude = "id")]Model.Model model)
{
var modId = Request["id"];
LoadModel();
LoadSubCategory(Convert.ToInt32(modId));
return View();
}
public void LoadModel()
{
Model.List listM = new Model.List();
listM.id = 0;
Model.Model mod1 = new Model.Model();
mod1.id = 1;
mod1.name = "me";
Model.Model mod2 = new Model.Model();
mod2.id = 2;
mod2.name = "me";
listM.list.Add(mod1);
listM.list.Add(mod2);
ViewBag.Model = listM;
}
public void LoadSubCategory(int id)
{
Model.subList subList = new Model.subList();
Model.subModel sub1 = new Model.subModel();
Model.subModel sub2 = new Model.subModel();
sub1.id = 1;
sub1.name = "notme";
sub1.modId = 1;
sub2.id = 1;
sub2.name = "notme";
sub2.modId = 1;
subList.list.Add(sub1);
subList.list.Add(sub2);
List<Model.subModel> sel = new List<Model.subModel>();
foreach (var item in subList.list)
{
if (item.modId == id)
{
sel.Add(item);
}
}
ViewBag.SubModel = sel;
}
}
}
View: (I have no idea if anything for subModel dropdown is working as I haven't even gotten to that part yet, but w/e.)
#model Model.List
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Index</h2>
#using (Html.BeginForm("Index","Home",FormMethod.Post, new{id = "ID"})){
#Html.DropDownListFor(m=>m.id, new SelectList(Model.list, "id","name"),"selectThis")
}
#if (ViewBag.SubModel != null)
{
#Html.DropDownList("SubModel",ViewBag.SubModel as SelectList, "select one")
}
It's probably something really stupid but I've been stuck for a couple of hours trying different things.
PS: This is just a test app. After I see how it is done I will be doing one with and SQL DB, using models in ConsoleApplications to retrieve and store data from the DB and display it in views, so any advice on that will be also appreciated.
A big thank you to all that have read up to here and have a nice day.
You never pass a model to the view in the controller, you just store in ViewBag.Model.
Try something as follows:
[ValidateInput(false)]
[AcceptVerbs("POST")]
public ActionResult Index([Bind(Exclude = "id")]Model.Model model)
{
var modId = Request["id"];
//get model
var model = LoadModel();
//pass it to the view
return View(model);
}

Categories