I created a piece of code that sets the property of a model to null when it is combined with another propert;
my model:
public partial class IngredientAmount
{
public string Id { get; set; }
public string MealId { get; set; }
public string IngredientId { get; set; }
public string Amount { get; set; }
[NotMapped]
public string DayId { get; set; }
[NotMapped]
public List<Ingredient> Ingredients { get; set; } = new List<Ingredient>();
public virtual Ingredient Ingredient { get; set; }
public virtual Meal Meal { get; set; }
}
My script that loads my model into a certain div by calling an url.action:
<script>
function loadCreateIngredientAmountPartial() {
$("#AddIngredient").load('#Url.Action("CreatePartial", "IngredientAmount", new IngredientAmount() { MealId = Model.Id, DayId = "2" })');
}
</script>
My controller method:
public ActionResult CreatePartial(IngredientAmount ingredient)
{
dbContext = new NutritionzContext();
IngredientAmount ingredientAmount = new IngredientAmount() { MealId = ingredient.MealId, DayId = ingredient.DayId };
ingredientAmount.Ingredients = dbContext.Ingredient.OrderBy(x => x.Name).ToList();
return PartialView("~/Views/IngredientAmount/Create.cshtml", ingredientAmount);
}
If I only send the DayId within the new IngredientAmount the property is filled, however when I add a mealId it turns empty.
I've found a way around my own question, the problem was that it wasn't routed correctly, so I created a new instance in the controller and just sent the two parameters via the action like so:
<script>
function loadCreateIngredientAmountPartial() {
$("#AddIngredient").load('#Url.Action("CreatePartial", "IngredientAmount", new { mealId = Model.Id, dayId = Model.DayId })');
}
</script>
Then I tasked the controller to route that specific action like so:
[Route("IngredientAmountController/CreatePartial/{mealId}/{dayId}")]
Related
I have 3 entities for main menus. and sub menus. I created menu view model.
My Entities:
MainMenu.cs:
public UstMenuler()
{
AltMenuler = new HashSet<AltMenuler>();
}
public int ID { get; set; }
public string Name { get; set; }
public bool AktifMi { get; set; }
public int YetkiID { get; set; }
public string ControllerName { get; set; }
public string ActionName { get; set; }
public virtual Yetkilendirme Yetkilendirme { get; set; }
public virtual ICollection<AltMenuler> AltMenuler { get; set; }
SubMenu.cs:
public partial class AltMenuler
{
public AltMenuler()
{
UstMenuler = new HashSet<UstMenuler>();
}
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int ID { get; set; }
public int? YetkiID { get; set; }
public string Name { get; set; }
public string ActionName { get; set; }
public string ControllerName { get; set; }
public virtual Yetkilendirme Yetkilendirme { get; set; }
}
MyViewModel:
public class MenuViewModel
{
public UstMenuler UstMenuler { get; set; }
public AltMenuler AltMenuler { get; set; }
}
My Controller:
dbContext = new MarkettingDbContext();
int sessionYetkiID = (int)Session["yetkiID"];
MenuViewModel menuler = new MenuViewModel();
var query = (from menu in dbContext.UstMenuler
where (menu.YetkiID == sessionYetkiID)
select new MenuViewModel
{
menuler.UstMenuler.ID = menu.ID,
menuler.UstMenuler.Name = menu.Name,
menuler.UstMenuler.YetkiID = menu.YetkiID,
menuler.UstMenuler.ControllerName = menu.ControllerName,
menuler.UstMenuler.ActionName = menu.ActionName
}).ToList();
I am getting error when I execute my query. For example my sessionID is 1, I want to take my main and submenus.
The problem is your object initializer:
select new MenuViewModel
{
menuler.UstMenuler.ID = menu.ID,
menuler.UstMenuler.Name = menu.Name,
menuler.UstMenuler.YetkiID = menu.YetkiID,
menuler.UstMenuler.ControllerName = menu.ControllerName,
menuler.UstMenuler.ActionName = menu.ActionName
}
Firstly you're using menuler in the object initializer, and I'm not sure why. Next, you're trying to assign to subproperties, which even if it did compile, would result in a NullReferenceException. Collectively, that's basically not what you want to do :)
Instead, I'd use one of the two options below.
If you're happy to just copy the UstMenuler reference from the menu parameter into the new view model instance, you can do that really easily:
select new MenuViewModel { UseMenuler = menu }
Or if you want to create a new UstMenuler and copy properties from menu:
select new MenuViewModel
{
UstMenuler = new UstMenuler
{
ID = menu.ID,
Name = menu.Name,
YetkiID = menu.YetkiID,
ControllerName = menu.ControllerName,
ActionName = menu.ActionName
}
}
Either way, you don't need your menuler variable which you appear not to be using anywhere else.
As it sounds like you're using LINQ to Entities, it sounds like you may want to separate the database query part from the projection part. The simplest way to do that in your case is to avoid the query expression syntax, so you can call AsEnumerable easily. So for example:
var query = dbContext.UstMenuler
.Where(menu => menu.YetkiID == sessionYetkiID)
.AsEnumerable() // Do the projection in-process
.Select(menu => new MenuViewModel
{
UstMenuler = new UstMenuler
{
ID = menu.ID,
Name = menu.Name,
YetkiID = menu.YetkiID,
ControllerName = menu.ControllerName,
ActionName = menu.ActionName
}
})
.ToList();
I have a problem which I'm unable to solve so any help would be appreciated. I have a view in which I'm dynamically adding textboxes (depending of a value chosen in dropdownlist).
Basically, I'm entering data for the product which depending of the category it belongs to has specific attributes added to it. For example, if the product is soft dring it could have following attributes: type of packaging, flavor, volume, etc. while some other product like cell phone may have attributes like: weight, RAM, CPU clock, CPU type, etc.
This is how the database looks like:
Dynamically creating controls isn't a problem and it is done with this code:
<script type="text/javascript">
$(document).ready(function () {
$("#ProductCategoryId").change(function () {
if ($("#ProductCategoryId").val() != "") {
var options = {};
options.url = "http://localhost:59649/Product/GetProductCategoryAttributes";
options.type = "POST";
options.data = JSON.stringify({ id: $("#ProductCategoryId").val() });
options.dataType = "json";
options.contentType = "application/json";
options.success = function (productCategoryAttributes) {
$("#atributtes").empty();
for (var i = 0; i < productCategoryAttributes.length; i++) {
$("#atributi").append("<div class='editor-label'><label>" + productCategoryAttributes[i].Name + "</label></div>")
.append("<div class='editor-field'><input class='text-box single-line' id='" + productCategoryAttributes[i].Name + "' name='" + productCategoryAttributes[i].Name + "' type='text'>");
}
};
options.error = function () { alert("Error retrieving data!"); };
$.ajax(options);
}
else {
$("#atributtes").empty();
}
});
});
</script>
Method in controller that retrieves ProductAttributeCategory names depending of ProductCategoryId selected:
public JsonResult GetProductCategoryAttributes(int id)
{
var productCategoryAttributes = db.ProductCategoryAttribute
.Where(p => p.ProductCategoryId == id)
.Select(p => new { Name = p.Name, p.DisplayOrder })
.OrderBy(p => p.DisplayOrder)
.ToList();
return Json(productCategoryAttributes, JsonRequestBehavior.AllowGet);
}
Controller code for POST:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Product product)
{
if (ModelState.IsValid)
{
db.Product.Add(product);
db.SaveChanges();
var productCategoryAttributes = db.ProductCategoryAttribute
.Where(p => p.ProductCategoryId == product.ProductCategoryId)
.OrderBy(p => p.DisplayOrder);
foreach (ProductCategoryAttribute productCategoryAttribute in productCategoryAttributes)
{
//Find HTML element that matches productCategoryAttribute.Name
ProductProductCategoryAttribute productCategoryAttributeValue = new ProductProductCategoryAttribute();
productCategoryAttributeValue.ProductId = product.ProductId;
//productCategoryAttributeValue.ProductCategoryAttributeId = Find HTML element that matches ProductCategoryAttributeID and pass its id here
//productCategoryAttributeValue.Value = Find HTML element that matches ProductCategoryAttributeID and pass its value here
db.ProductProductCategoryAttribute.Add(productCategoryAttributeValue);
db.SaveChanges();
}
return RedirectToAction("Index");
}
ViewBag.LanguageId = new SelectList(db.Language, "LanguageId", "Name", product.LanguageId);
ViewBag.ProductCategoryId = new SelectList(db.ProductCategory, "ProductCategoryId", "Name", product.ProductCategoryId);
return View(product);
}
Product model:
public partial class Product
{
public Product()
{
this.ProductPhoto = new HashSet<ProductPhoto>();
this.ProductProductCategoryAttribute = new HashSet<ProductProductCategoryAttribute>();
}
public int ProductId { get; set; }
public int LanguageId { get; set; }
public int ProductCategoryId { get; set; }
public string Name { get; set; }
public string EAN { get; set; }
public string Description { get; set; }
public virtual Language Language { get; set; }
public virtual ProductCategory ProductCategory { get; set; }
public virtual ICollection<ProductPhoto> ProductPhoto { get; set; }
public virtual ICollection<ProductProductCategoryAttribute> ProductProductCategoryAttribute { get; set; }
}
ProductCategory model:
public partial class ProductCategory
{
public ProductCategory()
{
this.Product = new HashSet<Product>();
this.ProductCategoryAttribute = new HashSet<ProductCategoryAttribute>();
}
public int ProductCategoryId { get; set; }
public int LanguageId { get; set; }
public string Name { get; set; }
public string PhotoLocation { get; set; }
public int DisplayOrder { get; set; }
public bool Active { get; set; }
public virtual Language Language { get; set; }
public virtual ICollection<Product> Product { get; set; }
public virtual ICollection<ProductCategoryAttribute> ProductCategoryAttribute { get; set; }
}
ProductCategoryAttribute model:
public partial class ProductCategoryAttribute
{
public ProductCategoryAttribute()
{
this.ProductProductCategoryAttribute = new HashSet<ProductProductCategoryAttribute>();
}
public int ProductCategoryAttributeId { get; set; }
public int ProductCategoryId { get; set; }
public string Name { get; set; }
public string MetaName { get; set; }
public string SymbolLocation { get; set; }
public int DisplayOrder { get; set; }
public bool Active { get; set; }
public virtual ProductCategory ProductCategory { get; set; }
public virtual ICollection<ProductProductCategoryAttribute> ProductProductCategoryAttribute { get; set; }
}
What I can't figure out is how to get the values from those dynamically created textboxes. Pseudocode (inside the controller) would be something like this:
Get the ProductCategoryId of the product
List all the attributes belonging to the selected product category
For each attribute find the appropriate textbox inside the view and get the value entered
Save the value to the database
I'm fairly new to the MVC so my approach may be wrong. Feel free to correct me.
It's very hard to read your code so here is a simplified version that should help you. Suppose you have these two models:
public class ProductCategory
{
public int CategoryId { get; set; }
public string CategoryName { get; set; }
}
public class Product
{
public Product()
{
Categories = new List<ProductCategory>();
}
public int ProductId {get;set;}
public string ProductName { get; set; }
public IEnumerable<ProductCategory> Categories { get; set; }
}
If these where your models then then the name attribute of your dynamically added textbox should be:
<input type="textbox" name="Categories[i].CategoryName" />
You can safely ignore the id attribute since name attribute is enough for proper model mapping/binding. Whatever value you enter in the textbox should map into an instance of a ProductCategory's CategoryName in the list of Categories attached to the Product model...
Thank you both of you. I've found a quick and, as it seems, dirty way of accomplishing this.
Basically, you can access any HTML control by using:
var value = Request["controlName"];
That is how I was able to get values from the form. I don't know if this is the right way but it sure worked for me. Any suggestion for improving this is more than welcome.
How can I fetch and insert data at a specific time in one view in mvc razor view? I mean to fill a dropdown list from the database in create view.
I want to fill the following when I add the subject and cheater models.
department list
semester list
standard list
stream list
cheater model:
namespace firstapp.Models
{
public class chepter
{
[ForeignKey("dip_id")]
public int dipart_id { get; set; }
public int chep_id { get; set; }
public string subject { get; set; }
public string chepter { get; set; }
public List<dipartment> dipartlist { get; set; }
public List<dipartment> stdlist { get; set; }
public List<dipartment> semlist { get; set; }
public List<dipartment> stremlist { get; set; }
}
}
department model:
namespace firstapp.Models
{
public class dipartment
{
public int dip_id { get; set; }
public string dipart { get; set; }
public string std { get; set; }
public string sem { get; set; }
public string strem { get; set; }
}
}
#Html.DropDownListFor(model => model.dipart_id, new SelectList(Model.dipartlist.Select(s => new SelectListItem() { Value = s.dip_id, Selected = false, Text = s.dipart })), "Select")
Change your model so the list property is a selectlist:
public SelectList<dipartment> dipartlist { get; set; }
Then, when you populate the model call a service class method(you might not have a service layer, I just prefer to not have database calls in the controller)
dipartlist = _departmentService.GetAsSelectList();
The GetAsSelectList service method looks like this:
public SelectList GetAsSelectList()
{
return (from d in _context.Set<department>().OrderBy(x => x.dipart)
select new
{
Id = d.dipart_id,
Name = d.dipart
}).ToList();
}
And finally your view:
#Html.DropDownListFor(model => model.dipart_id, Model.dipartlist)
This technique means you don't have linq in either the view or controller. Also as you're only creating the selectlist in one place (the service), you can cache it with MemoryCache to prevent multiple requests for the same data. And as it looks like you're populating 4 selectlists, this might be useful.
I am having an issue returning multiple models in one view. I have a model that has a collection of other models. So when I return the model (ProblemsVM) that has the collection of the other 2, I would like to attach the other 2 to the model being returned so I can access it's values in the view. Any help will be greatly appreciated and thank you for taking your time to read.
This is my ProblemsVM model and the 2 IEnumerables that I want to include in the views return.
public class ProblemsVM
{
public int Id { get; set; }
public string Title { get; set; }
public int ProjectId { get; set; }
public IEnumerable<Category> Categories { get; set; }
public IEnumerable<Type> Types {get; set;}
}
This is the action returning the view I want to attach the 2 models to. Right now it populates a table of different problems by ProjectId that it receives from the API.
public ActionResult ReturnProblems()
{
List<ProblemsVM> dv = new List<ProblemsVM>();
// return problems
var requestDef = new RestRequest("problem", Method.GET);
requestDef.AddHeader("id", userId);
requestDef.AddHeader("key", userKey);
requestDef.RequestFormat = DataFormat.Json;
var responseDef = Userclient.Execute(requestDef) as RestResponse;
List<ProblemsVM> problems = JsonConvert.DeserializeObject<List<ProblemsVM>>(responseDef.Content);
IEnumerable<ProblemsVM> problemsToReturn = problems.Where(d => d.ProjectId == item.ProjectId);
return View(problemsToReturn);
}
So what I am looking to do would be something like this that I have in another application. In this one it works fine when using a Model not in a list or IEnumerable. I am having trouble switching this over to the above method to be returned with the list of problems. ProbVM is the same as ProblemsVM in the other project.
ProbVM tt = new ProbVM();
tt.Cats = db.Categories.ToList();
tt.Typ = db.Types.ToList();
return View(tt);
This is my other 2 models that are stored in the SQL database:
public partial class Type
{
public int Id { get; set; }
public int Order { get; set; }
public string Description { get; set; }
public int CategoryId { get; set; }
public virtual Category Category { get; set; }
}
public partial class Category
{
public Category()
{
this.Types = new HashSet<Type>();
this.Companys = new HashSet<Company>();
}
public int Id { get; set; }
public string Title { get; set; }
public int CompanyId { get; set; }
public virtual ICollection<Company> Companys { get; set; }
public virtual ICollection<Type> Types { get; set; }
}
-----UPDATED PART------
So when this button(which is in the rows of the datatables) is clicked it pops up a modal:
Type
and on the button id "launch" is called in ajax by:
<script>
$(function () {
$("#type-modal").dialog({
autoOpen: false,
height: 600,
width: 500,
modal: true,
open: function () {
$("#accordion").accordion({ autoHeight: true });
}
});
$(".launch").click(function () {
Id.value = $(this).attr('value');
$("#type-modal").dialog("open");
})
});
</script>
and in the type-modal div is where I will use the Category and Type model to use razor(would like to use something like this like I did in the other project):
foreach (var item in Model.Cats)
{
#Html.Label(item.Title, new { cats = item.Title })<br/>
foreach(var tri in Model.types)
{
if (item.CategoryId == tri.CategoryId)
{
#Html.RadioButton(tri.Category.Title, tri.Order)
#Html.Label(tri.Description)<br/>
}
}
}
My task is to show multiple models into a single view.I've created a ViewModel for my requirement but I'm not meeting my requirement.
please have a look into the below code and rectify me where m i going wrong ???
public partial class StudentsDetail
{
public int StudentID { get; set; }
public int ParentID { get; set; }
public string StudentName { get; set; }
public string Gender { get; set; }
public string FatherName { get; set; }
public string MotherName { get; set; }
public Nullable<System.DateTime> DateOfBirth { get; set; }
public virtual ParentsDetail ParentsDetail { get; set; }
public virtual SchoolDetail SchoolDetail { get; set; }
}
//Model 2
public partial class ParentsDetail
{
public ParentsDetail()
{
this.StudentsDetails = new HashSet<StudentsDetail>();
}
public int ParentID { get; set; }
public string Occupation { get; set; }
public string Organization { get; set; }
public string AnnualIncome { get; set; }
public virtual ICollection<StudentsDetail> StudentsDetails { get; set; }
}
//ViewModel Which I have created
public class ParentsInformationViewModel
{
public List<StudentsDetail> StudentsDetails { get; set; }
public List<ParentsDetail> ParentsDetails { get; set; }
public ParentsInformationViewModel(List<StudentsDetail> _studentDetails, List<ParentsDetail> _parentsDetails) //Should i pass all the required parameters that i want to display in view ????
{
StudentsDetails = _studentDetails;
ParentsDetails = _parentsDetails;
}
//And finally this is my method defined in the StudentController (Have i defined it in a right place/way??)
public ActionResult StudentViewModel()
{
ViewBag.ParentsDetail = new ParentsDetail(); //ParentsDetail is my controller
List<StudentsDetail> studentListObj = StudentsDetailsDAL.GetStudentDetails();
List<ParentsInformationViewModel> ParentInfoVMObj = new List<ParentsInformationViewModel>();
//foreach (var student in studentListObj)
//{
// ParentInfoVMObj.Add(new ParentsInformationViewModel(student.StudentID, student.ParentID));
//}
//ParentInfoVMObj.Add(ParentInfoVMObj); /// don't know how to call the required viewmodel
return View(ParentInfoVMObj);
}
I know that the above method of a ViewModel is wrong but how to use it or where am i going wrong I can't get.
I want to display the ViewModel in the view as a detailed view .
Please, correct me as I'm a starter in MVC3 .
Thanks In Advance!!
In your controller, define your action method as follows.
public ActionResult ParentsDetails()
{
var studentDetails = new List<StudentDetail>();
var parentDetails = new List<ParentsDetail>();
// Fill your lists here, and pass them to viewmodel constructor.
var viewModel = new ParentsInformationViewModel(studentDetails, parentDetails)
// Return your viewmodel to corresponding view.
return View(viewModel);
}
In your view define your model.
#model MySolution.ViewModels.ParentsInformationViewModel
Is there in your view declared that you are receiving model of type
In view:
#model IEnumerable<ParentsInformationViewModel>