Reloading model in mvc - asp.net-mvc

I want get some qualification about reloading model in mvc action. For example:
I have some class model:
public class PresentationItemModel()
{
public int Id { get; set; }
public string Name { get; set; }
public string Title { get; set; }
public string Type { get; set; }
public List<int> PresentationIdList { get; set; }
}
And some controller action:
public ActionResult PostAction(PresentationItemModel model)
{
...
if(model.PresentationIdList == null)
{
model.PresentationIdList = new List<int>();
}
model.PresentationIdList.Add(model.Id);
...
...
...
}
I can call PostAction method several times and I want to save model.PresentationIdList result with all id's. But every time my PresentationIdList reloading with all model. But it's standard behavior.
Can I resolve it?

All you need to do is return the model object from your PostAction:
public ActionResult PostAction(PresentationItemModel model)
{
...
if(model.PresentationIdList == null)
{
model.PresentationIdList = new List<int>();
}
model.PresentationIdList.Add(model.Id);
...
...
...
return new ActionResult(model);
}

Related

Adding new entries over entity navigation property collection

I need to create a generic way to add missing languages entries to all entities in which implements an specific interface. I found out how to get my collection property, but I still don't know how to add new values on it before proceed to save.
Following a piece of my public override int SaveChanges() handling.
foreach (var translationEntity in ChangeTracker.Entries(<ITranslation>))
{
if (translationEntity.State == EntityState.Added)
{
var translationEntries = translationEntity.Entity.GetType()
.GetProperties(BindingFlags.Public | BindingFlags.Instance)
.Where(x => x.CanWrite &&
x.GetGetMethod().IsVirtual &&
x.PropertyType.IsGenericType == true &&
typeof(IEnumerable<ILanguage>).IsAssignableFrom(x.PropertyType) == true);
foreach (var translationEntry in translationEntries)
{
//Add missing items.
}
}
}
Classes code samples
public partial class FileType : ITranslation
{
public long FileTypeId { get; set; }
public string AcceptType { get; set; }
public virtual ICollection<FileTypeTranslation> FileTypeTranslations { get; set; }
public FileType()
{
this.FileTypeTranslations = new HashSet<FileTypeTranslation>();
}
}
public class FileTypeTranslation : EntityTranslation<long, FileType>, ILanguage
{
[Required]
public string TypeName { get; set; }
}
public partial class ElementType : ITranslation
{
public long ElementTypeId { get; set; }
public string Code { get; set; }
public virtual ICollection<ElementTypeTranslation> ElementTypeTranslations { get; set; }
public ElementType()
{
this.ElementTypeTranslations = new HashSet<FileTypeTranslation>();
}
}
public class ElementTypeTranslation : EntityTranslation<long, ElementType>, ILanguage
{
[Required]
public string Description { get; set; }
}
Entries from ChangeTracker have property called Entity which holds original entity
foreach (var fileType in ChangeTracker.Entries(<FileType>))
{
fileType.Entity.FileTypeTranslations.Add();
}
and for ElementType:
foreach (var elementType in ChangeTracker.Entries(<ElementType>))
{
elementType.Entity.ElementTypeTranslations.Add();
}
I didn't test, but it was too long to paste in comment.

MVC5: Foreign Key and data access

I am looking for selecting a list from my table based on another table. I need to retrieve system names that are part of a particular system family. i have already added foreign keys. I created a ViewModel containing both these classes but it throws a null pointer exception. I am new to MVC and I am not sure where I am wrong.
Model Class : Systems
public class Systems
{
public int SystemsID { get; set; }
public string SystemName { get; set; }
public DateTime CreatedOn { get; set;}
public string CreatedBy { get; set; }
public int SystemFamilyID { get; set; }
public virtual SystemFamily SystemFamily { get; set; }
}
Class SystemFamily
public class SystemFamily
{
public int SystemFamilyID { get; set;}
public int SystemsID {get;set;}
public string FamilyName { get; set; }
public DateTime DateCreated { get; set; }
public string CreatedBy { get; set; }
public virtual ICollection<Systems> Systems { get; set; }
}
ViewSystem is a method in my SystemFamilyController.
public ActionResult ViewSystem(int? id)
{
var viewmodel = new Sys_SysFam();
ViewBag.SystemFamilyID = id.Value;
//if (id != null)
//{
// ViewBag.SystemFamilyID = id.Value;
// viewmodel.Systems = viewmodel.SystemFamily.Where(
// i => i.SystemFamilyID == id.Value).Single().Systems;
//}
return View(viewmodel);
}
the view :
#model SystemFam_System.ViewModel.Sys_SysFam
#{
ViewBag.Title = "ViewSystem";
}
<h2>ViewSystem</h2>
<p>#ViewBag.SystemFamilyID</p>
<table>
#foreach (var item in Model.Systems)
{
string selectedRow = "";
if (item.SystemFamilyID == ViewBag.SystemFamilyID)
{
//{
// selectedRow = "success";
//}
<tr class="#selectedRow">
<td>
#item.SystemName
</td>
<td>
#item.SystemsID
</td>
<td>
#item.SystemFamily
</td>
</tr>
}
}
</table>
I get null pointer Exception. I want to view the system that belongs to a particular family in view system.
Thanks in advance!!
Vini
Edit :
public class Sys_SysFam
{
public IEnumerable<Systems> Systems { get; set; }
public SystemFamily SystemFamily { get; set; }
}
Ok i have checked Sys_SysFam class too. As per your current code it will always throw null reference exception becasue in your controller code you are using:
public ActionResult ViewSystem(int? id)
{
var viewmodel = new Sys_SysFam();
ViewBag.SystemFamilyID = id.Value;
//if (id != null)
//{
// ViewBag.SystemFamilyID = id.Value;
// viewmodel.Systems = viewmodel.SystemFamily.Where(
// i => i.SystemFamilyID == id.Value).Single().Systems;
//}
return View(viewmodel);
}
here you are creating an object of Sys_SysFam as viewmodel and as your if part is commented so you are returning same viewmodel in which viewmodel.Systems will always be null. Here i did not see any request to database for getting the data from db but i think your data in viewmodel will come from database and if i uncomment your if condition then too you are not sending any request to database you are using same viewmodel object created above.
viewmodel.Systems = viewmodel.SystemFamily.Where(
i => i.SystemFamilyID == id.Value).Single().Systems;
in right side you are using viewmodel.SystemFamily with where condition but as viewmodel.SystemFamily is null it will always throw exception. Your solution should be something like this:
public ActionResult ViewSystem(int? id)
{
DataContext context = new DataContext();
var viewmodel = new Sys_SysFam();
ViewBag.SystemFamilyID = id.Value;
if (id != null)
{
ViewBag.SystemFamilyID = id.Value;
var sysFamily = context.SystemFamily.Include(x => x.Systems).FirstOrDefault(x => x.SystemFamilyID == id.Value);
if (sysFamily != null)
{
viewmodel.Systems = sysFamily.Systems;
}
}
return View(viewmodel);
}
here first i am creating object of DataContext which is my main context to access the database using entity framework. so first i will get the system family based on passed id from database and if system family is not null then i will set the data of systems in viewmodel. Include method will bring data for Systems based on system family from database.
Also improve your Sys_SysFam class to initialize systems so that it will not throw exception in your view when there is no data in viewmodel.Systems like this:
public class Sys_SysFam
{
public Sys_SysFam()
{
this.Systems = new List<Systems>();
}
public SystemFamily SystemFamily { get; set; }
public IEnumerable<Systems> Systems { get; set; }
}
Hope this will help you.
Remove SystemsID property from SystemFamily class because it is not used for ICollection virtual property. so your SystemFamily class should be like this:
public class SystemFamily
{
public int SystemFamilyID { get; set;}
public string FamilyName { get; set; }
public DateTime DateCreated { get; set; }
public string CreatedBy { get; set; }
public virtual ICollection<Systems> Systems { get; set; }
}
A friend of mine could find me a way. But it doesnt use any ViewModel. I would like to know how it need to be done with ViewModel as well..
public ActionResult ViewSystem(int? id)
{
var model = from item in db.Systems
orderby item.SystemsID
where item.SystemFamilyID == id
select item;
return View(model);
}

MVC multiple ViewModel and ModelState

I Have two simple model Model1, Model2 as below:
public class Model1
{
public int Id { get; set; }
[Required]
public string Name { get; set; }
}
public class Model2
{
public int Id { get; set; }
[Required]
public string Code { get; set; }
}
I Have a BigModel contains two other model as:
public class BigModel
{
public BigModel()
{
Model1 = new Model1 ();
Model2 = new Model2();
}
public Model1 Model1 { get; set; }
public Model2 Model2 { get; set; }
}
and in my Controller:
public ActionResult Register(BigModel bigModel)
{
if (ModelState.IsValid)
{
//do somthing
return RedirectToAction("Index");
}
return View(bigModel);
}
my question is Why ModelState.IsValid is always true? though data annotations are set. and How can I validate two models in one action?
Please don't use above way.Always try to use ViewModel with your views.Put all your data annotations on that ViewModel and check that inside the action method.
Plese check below mentioned sample ViewModel as an example.
public class ProductViewModel
{
public Guid Id { get; set; }
[Required(ErrorMessage = "required")]
public string ProductName { get; set; }
public int SelectedValue { get; set; }
public virtual ProductCategory ProductCategory { get; set; }
[DisplayName("Product Category")]
public virtual ICollection<ProductCategory> ProductCategories { get; set; }
}
Inside the Action Method:
[HttpPost]
public ActionResult AddProduct(ProductViewModel productViewModel) //save entered data
{
//get product category for selected drop down list value
var prodcutCategory = Repository.GetProductCategory(productViewModel.SelectedValue);
//for get all product categories
var prodcutCategories = Repository.GetAllProductCategories();
//for fill the drop down list when validation fails
productViewModel.ProductCategories = prodcutCategories;
//for initialize Product domain model
var productObj = new Product
{
ProductName = productViewModel.ProductName,
ProductCategory = prodcutCategory,
};
if (ModelState.IsValid) //check for any validation errors
{
//save recived data into database
Repository.AddProduct(productObj);
return RedirectToAction("AddProduct");
}
else
{
//when validation failed return viewmodel back to UI (View)
return View(productViewModel);
}
}

Object reference not set to an instance of an object.

i have 3 model:
1st one:
public class CreateFieldModel
{
public FieldModel fm { get; set; }
public CategoryModel cm { get; set; }
}
2nd one:
public class FieldModel
{
public string field_Name { get; set; }
public InputTypeModel itm { get; set; }
public string input1 { get; set; }
public string input2 { get; set; }
public string input3 { get; set; }
public string input4 { get; set; }
public List<InputTypeModel> inputs { get; set; }
}
3rd One:
public class InputTypeModel
{
public string inputTypeName { get; set; }
public string inputTypeDesc { get; set; }
}
2 methods:
1st One:
public List<InputTypeModel> getInputTypes()
{
var inptypes = edu.InputTypes;
List<InputTypeModel> listInputTypes = new List<InputTypeModel>();
foreach (var inpType in inptypes)
{
listInputTypes.Add(new InputTypeModel { inputTypeName = inpType.Input_Type_Name, inputTypeDesc = inpType.Input_Type_Description });
}
return listInputTypes;
}
when this method executes listInputTypes has three different values.. i check it by debugging.. so no roblem here. This methos is under the class FormManagement.. I am calling this method from the following action method:
[HttpGet]
public ActionResult createNewField(CreateFieldModel cfm, string fcode)
{
FormManagement ffm = new FormManagement();
cfm.fm.inputs = ffm.getInputTypes();
return View(cfm);
}
when cfm.fm.inputs = ffm.getInputTypes(); executes it is showing "Object reference not set to an instance of an object." message... I am quite beginner to mvc.. please help
Without knowing what you really want to achieve with cfm-parameter in your action, the only thing I can suggest is to check for null references and create new instances before you assign them:
[HttpGet]
public ActionResult createNewField(CreateFieldModel cfm, string fcode)
{
FormManagement ffm = new FormManagement();
if (cfm == null)
{
cfm = new CreateFieldModel();
}
if (cfm.fm == null)
{
cfm.fm = new FieldModel();
}
cfm.fm.inputs = ffm.getInputTypes();
return View(cfm);
}
Of course, this supposes that your not relying on incoming data through your route parameters. If you are, you need to check why the values are not getting passed in, but I'm guessing you don't need it as a parameter in the first place.

Chaining multiple classes in a MVC4 view

Let's say I have a model like this (simplified from the original):
public class Location
{
public int ID { get; set; }
public string BinNumber { get; set; }
}
public class Item
{
public int ID { get; set; }
public string Description { get; set; }
public virtual Location Bin { get; set; }
}
public class LineOnPickList
{
public int ID { get; set; }
public virtual Item Item { get; set; }
}
The usual thing to do here on the LineOfPickList Create view would be to have a dropdownlist that listed all the Item Descriptions and put the selected item in the newly created LineOnPickList record when Create was clicked.
What I need to do however is show a dropdownlist of Location BinNumbers, yet still have the Item associated with that Location in the newly created LineOnPickList record.
How would that be done?
Define a view model for your drop down
public class ItemViewModel
{
public int ID { get; set; }
public string BinNumber { get; set; }
}
Then build the drop down list data in your controller action as follows
public class CreateLineOnPickListViewModel
{
public int ItemId { get; set; }
public IEnumerable<ItemViewModel> Items { get; set; }
}
public ActionResult Create()
{
var model = new CreateLineOnPickListViewModel();
model.Items = db.Items
.Select(i => new ItemViewModel { ID = i.ID, BinNumber = i.Bin.BinNumber });
return View(model);
}
Then in your view
#model CreateLineOnPickListViewModel
#Html.DropDownListFor(m => m.ItemId, new SelectList(Model.Items, "ID", "BinNumber"), "-")
Then your post action method in your controller would look like this
public ActionResult Create(CreateLineOnPickListViewModel model)
{
var item = new Item { ID = model.ItemID };
db.Items.Attach(item);
var lineOnPickList = new LineOnPickList { Item = item };
db.SaveChanges();
return View(model);
}

Resources