Updating collection property in explicit model binding VS implicit model binding? - asp.net-mvc

I have an entity model that has a collection property (many-to-many relationship) of Users signed up for the application.
in the Edit view I used implicit model binding to edit task object with the single properties (Title, DueDate, etc..) and Users (checkboxes) :
public ActionResult Edit([Bind(Include = "Id,Title,Description,DueDate,Status")] UserTask task, string[] asndUsers/*users IDs*/)
{
if (ModelState.IsValid)
{
task.Users = new List<ApplicationUser>();
if (asndUsers != null)
{
foreach (var userId in asndUsers)
{
var user = context.Users.Find(userId);
task.Users.Add(user);
}
}
context.Entry(task).State = EntityState.Modified;
context.SaveChanges();
return RedirectToAction("Index");
}
return View(task);
}
but this didn't work, the single properties was updated but the Users couldn't be updated.
I then used the explicit model binding
var task = context.Tasks.Include(t => t.Users).SingleOrDefault(s => s.Id == id);
task.Users = new List<ApplicationUser>();
foreach (var userId in asndUsers)
{
var user = context.Users.Single(u => u.Id == userId);
task.Users.Add(user);
}
if (TryUpdateModel(task, "", new string[] { "Title", "Description", "DueDate", "Status" }))
{
context.SaveChanges();
return RedirectToAction("Index");
}
it works, but have no idea what it did that implicit binding didn't

Related

How can I throw a sql query into the Viewbag

Hi I have 2 tables in my database. I want to compare and list the news items in table A that are not in table B.
I wrote a sql query.
SELECT ID FROM News_TB
where ID not in ( select News_ID From Slider_TB)
I need a Viewbag that uses this query to do the listing.On account controller.
MY View Code in Account Controller
public ActionResult SliderCategoryDetay(int ID)
{
var kontrol = _udb.SliderCategoryTB_Select().Where(m => m.SliderCategoryID == ID).First();
ViewData["ID"] = kontrol.SliderCategoryID;
ViewBag.slider = _udb.SliderTB_Select().Where(m => m.SliderID == ID);
ViewBag.sliderhabercek = _udb.NewsTB_Select(); /*THİS*/
return View();
}
I want to do it on this page.Thanks for your help.
you can use viewbag.data like this
public ActionResult SliderCategoryDetay(int ID)
{
var kontrol = _udb.SliderCategoryTB_Select().Where(m => m.SliderCategoryID == ID).First();
ViewData["ID"] = kontrol.SliderCategoryID;
ViewBag.data = kontrol;
ViewBag.slider = _udb.SliderTB_Select().Where(m => m.SliderID == ID);
ViewBag.sliderhabercek = _udb.NewsTB_Select(); /*THİS*/
return View();
}
And in your view use following example
#foreach(var item in ViewBag.data)
{
#item.Value
}

Some errors in controller (asp.net mvc)

I am getting some errors in my controller.
At first, I got Suppliers List, then I got Id for all Suppliers, then I got all Users for every Supplier.
public ActionResult Grid(bool? active)
{
var suppliers = Context.Suppliers.AsNoTracking()
.WhereIf(active != null, e => e.Active == active)
.Select(e => new SupplierRow
{
Id = e.Id,
FullName = e.FullName,
Active = e.Active,
Visits = e.Visits,
})
.ToList();
List<int> supplierIds = new List<int>();
foreach (SupplierRow sr in suppliers)
{
supplierIds.Add(sr.Id);
}
var users = Context.Users.AsNoTracking()
.Where(e => supplierIds.Contains(e.SupplierId))
.Select(e => new UserRow
{
Id = e.Id,
FullName = e.FullName,
Email = e.Email,
Name = e.Name,
Status = e.Status,
Role = e.Role,
SupplierId = e.SupplierId
}).toList();
foreach (UserRow ur in users)
{
foreach (SupplierRow sr in supplier)
{
if (ur.SupplierId == sr.Id)
{
sr.Users.Add(ur);
}
}
}
return PartialView("_Grid", suppliers);
}
here
and here
What's wrong with my code? How to fix that?
The problem is that you are trying to add Guid object to a collection that only accepts int values. Your User.SupplierId is an object of type Guid? (or Nullable<Guid>), while Supplier.Id is Guid. Fix the collection by declaring it as:
List<Guid> supplierIds = new List<Guid>();
Then in you code use:
foreach(SupplierRow sr in suppliers)
{
supplierIds.Add(sr.Id);
}
Do the same thing for users except that you will have to use SupplierId.HasValue and SupplierId.Value to check whether it has a value and to read the value. This is because it is declared as nullable Guid.

Creating a dropdown list in MVC nhibernate

I'm creating an application in hibernate where i need to create a dropdown list in my Create View.
The dropdownlist items are fetched through a function called getHobbytype() and from that I need to store the selected value into a different database.
I have written this in my controller:
ViewData["Hobby_type"] =
new SelectList(new Hobby_MasterService().GetHobbyType(),"Hobby_Types");
And this in my Create View:
#Html.DropDownListFor(Model =>
Model.Hobby_Types,(IEnumerable<SelectListItem>)ViewData["Hobby_type"])
Through this I'm able to create the dropdown list but it is giving me this error inside my view on the dropdown:
There is no ViewData item of type 'IEnumerable' that has the key 'Hobby_Types'.
Here is my GetHobbyType Method:
public IList<String> GetHobbyType()
{
log.Debug("Started");
ISession session = DataAccessLayerHelper.OpenReaderSession();
IList<String> htype = null;
ITransaction transaction = null;
try
{
transaction = session.BeginTransaction();
htype = session.CreateSQLQuery("SELECT Hobby_Types FROM Hobby_Type").List<String> ();
session.Flush();
transaction.Commit();
}
catch (Exception ex)
{
if (transaction != null && transaction.IsActive)
transaction.Rollback();
log.Error(ex);
}
log.Debug("End");
return htype;
}
Please tell me where I'm going wrong.
Is this a typo:-
#Html.DropDownListFor(Model =>
Model.Hobby_Types,(IEnumerable<SelectListItem>)ViewData["Type"])
Should it not be
#Html.DropDownListFor(Model =>
Model.Hobby_Types,(IEnumerable<SelectListItem>)ViewData["Hobby_type"])
Also your error says 'IEnumerable' that has the key 'Hobby_Types'.
The key in ViewData is case sensitive (not to mention the error has an S on the end)
I would also reccomend using a ViewModel rather than ViewData. See this Google search
edit The GetHobbyType Method returns a List so try this:-
ViewData["Hobby_type"] =
new SelectList(
new Hobby_MasterService().GetHobbyType()
.Select(x => new SelectListItem { Text = x, Value = x }).ToList()
,"Hobby_Types");
I also suggest looking at using a viewmodel as it will save you lots of headaches!
You can try this all.
You have to write a service named GetAllStudents()
public IList<Student> GetAllStudents()
{
log.Debug("Started");
ISession session = DataAccessLayerHelper.OpenReaderSession();
IList<Student> students = null;
ITransaction transaction = null;
try
{
transaction = session.BeginTransaction();
ICriteria criteria = session.CreateCriteria(typeof(Student));
students = criteria.List<Student>();
session.Flush();
transaction.Commit();
}
catch (Exception ex)
{
if (transaction != null && transaction.IsActive)
transaction.Rollback();
log.Error(ex);
}
finally
{
if (transaction != null)
transaction.Dispose();
if (session != null && session.IsConnected)
session.Close();
}
log.Debug("End");
return students;
}
In controller:
ViewBag.std = new StudentService().GetAllStudents(); // ViewBag.std will hold all students.
In create View:
#Html.DropDownListFor(model => model.Name, new SelectList(ViewBag.std, "Id", "Name"), "-- Select --")
First parameter is responsible for Linq expression for class property which you want to place in dropdown.
Second one is IEnumerable item list.
Third data value field.(Primary key)
Last one is Data text field which you want to display in drop down list.

MVC C# Select Where

I am trying to add filter by ID for the following:
public ActionResult Index()
{
var model = from o in new MainDBContext().OffLinePayments
select new EditOffLinePayment
{
ID = o.ID,
Amount = o.Amount
};
return View(model);
}
What I would like to do is the following:
public ActionResult Index(long? id)
{
if (id != null)
{
var model = from o in new MainDBContext().OffLinePayments
**Where Assigned_ID == id**
select new EditOffLinePayment
{
ID = o.ID,
Amount = o.Amount
};
return View(model);
}
else
{
var model = from o in new MainDBContext().OffLinePayments
select new EditOffLinePayment
{
ID = o.ID,
Amount = o.Amount
};
return View(model);
}
}
try
var model = from o in new MainDBContext().OffLinePayments
where o.Assigned_ID == id
select new EditOffLinePayment
{
ID = o.ID,
Amount = o.Amount
};
If I understand correctly, your problem is that the compiler doesn't let you write where o.Assigned_ID == id in the query.
That's because id is a Nullable<long>, which is not implicitly convertible to a long (which OffLinePayment.Assigned_ID presumably is).
You need to write where o.Assigned_ID == id.Value instead. Take a look at what the Value property does so that you don't get any surprises.
A cleaner, shorter and much more readable syntax would look like this:
public ActionResult Index(long? id){
using (var ctx = new MainDBContext())
{
var entities = ctx.OfflinePayments.Where(e => !e.HasValue || e.Assigned_ID == id.Value);
var model = entities.Select(e => new EditOfflinePayment { ID = e.ID, Amount = e.Amount }).ToList();
return View(model);
}
}

parameter problem in asp.net mvc

I'm new to asp.net mvc. I have index method with parameter id :
public ActionResult Index(int id)
{
var dc = new ServicesDataContext();
var query = (from m in dc.Mapings
where m.CustomerID == id
select m);
// var a = dc.Customers.First(m => m.CustomerId == id);
// ViewData.Model = a;
// return View();
return View(query);
}
Now when I try to redirect to index from edit i get an error " The parameters dictionary contains a null entry for parameter 'id' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult Index(Int32)' in 'MVCServices.Controllers.CustomerserviceController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.
[HttpPost]
public ActionResult Edit( FormCollection form)
{
var id = Int32.Parse(form["CustomerServiceMappingID"]);
var datacontext = new ServicesDataContext();
var serviceToUpdate = datacontext.Mapings.First(m => m.CustomerServiceMappingID == id);
TryUpdateModel(serviceToUpdate, new string[] { "CustomerID", "ServiceID", "Status" }, form.ToValueProvider());
if (ModelState.IsValid)
{
try
{
var qw = (from m in datacontext.Mapings
where id == m.CustomerServiceMappingID
select m.CustomerID).First();
datacontext.SubmitChanges();
//return Redirect("/Customerservice/Index/qw");
return RedirectToAction("Index", new { qw = qw });
}
catch{
}
}
return View(serviceToUpdate);
}
This is the View:
#Html.ActionLink("Back to List", "Index")
The id in the Index method turns out to be the customerid fetched from another controller while id in Edit is from another table.Can you please let me know the mistake I've been doing and how to solve it?
Do this in the Edit action:
return RedirectToAction("Index", new { id = qw });

Resources