Check, Nothing is changed in Model values MVC3 - asp.net-mvc-3

I've a Model like following:
public class Page
{
private readonly IndianTime _g = new IndianTime();
public Page()
{
CreatedOn = _g.DateTime;
Properties = "Published";
Tags = "Page";
RelativeUrl = string.Empty;
}
public string Path
{
get { return (ParentPage != null) ? ParentPage.Heading + " >> " + Heading : Heading; }
}
[Key]
public int Id { get; set; }
[StringLength(200), Required, DataType(DataType.Text)]
public string Title { get; set; }
[StringLength(200), Required, DataType(DataType.Text)]
public string Heading { get; set; }
[MaxLength, Required, DataType(DataType.Html)]
public string Content { get; set; }
[Display(Name = "Reference Code"), ScaffoldColumn(false)]
public string ReferenceCode { get; set; }
[Required]
[Remote("CheckDuplicate", "Page", ErrorMessage = "Url has already taken", AdditionalFields = "initialUrl")]
public string Url { get; set; }
[Display(Name = "Created On"), ScaffoldColumn(false)]
public DateTime CreatedOn { get; set; }
//Parent Page Object (Self Reference: ParentId = > Id)
[Display(Name = "Parent Page")]
public int? ParentId { get; set; }
[DisplayFormat(NullDisplayText = "Root")]
public virtual Page ParentPage { get; set; }
public virtual ICollection<Page> ChildPages { get; set; }
}
During Update, is there any to check Model values are "Changed" or "Nothing has changed" after POST method?
Say for example: (See the commented lines)
[HttpPost, ValidateAntiForgeryToken]
public ActionResult Edit(WebPage webpage)
{
try
{
if (ModelState.IsValid)
{
// If (webpage object values are unchanged, submitted as it is
// {
// Do not insert any values into Another Table
// }
// else
// {
// Inert into another table
// }
_db.Entry(webpage).State = EntityState.Modified;
_db.SaveChanges();
return RedirectToAction("Index");
}
}
catch (DataException)
{
ModelState.AddModelError("", ErrorCode.Msg.ContactSystemAdmin.ToString());
}
return View(webpage);
}

You can do something like this
[HttpPost, ValidateAntiForgeryToken]
public ActionResult Edit(WebPage webpage)
{
try
{
if (ModelState.IsValid)
{
var dbEntry=_db.GetEntryById(webpage.Id);
//check here if properties in webPage and column values in dbEntry are
//same then decide whether to insert in another table or not
_db.Entry(webpage).State = EntityState.Modified;
_db.SaveChanges();
return RedirectToAction("Index");
}
}
catch (DataException)
{
ModelState.AddModelError("", ErrorCode.Msg.ContactSystemAdmin.ToString());
}
return View(webpage);
}
Or Not Sure if this works
Try using $(form).serialize() at client side
CHECK THIS FIDDLE

Related

insert data in two class(table) in Entity Framwork by rerlation many to many

i create two class in my model and create relation many to many by Entity
in sql my classes is created tables Properly
when i try to insert data in this table get show error "Object reference not set to an instance of an object." my cod is:
public class News
{
public int ID { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public DateTime Date { get; set; }
public virtual Picture Picture { get; set; }
public virtual NewsType NewsType { get; set; }
public ICollection<Tag> Tag { get; set; }
public News(int id, string title, string content, DateTime date)
{
this.ID = id;
this.Title = title;
this.Content = content;
this.Date = date;
}
public News()
{
}
}
public class Tag
{
public int ID { get; set; }
public string Title { get; set; }
public ICollection<News> News { get; set; }
public Tag()
{
}
}
public class DatabaseContext : DbContext
{
public DatabaseContext()
: base("News")
{
}
static DatabaseContext()
{
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<DatabaseContext>());
}
public DbSet<News> newsInfo { get; set; }
public DbSet<Picture> pictures { get; set; }
public DbSet<NewsType> Types { get; set; }
public DbSet<Tag> Tags { get; set; }
}
[HttpPost]
public ActionResult AddNews(NewsViewModel newsInfo)
{
using (Models.DatabaseContext dbContext = new DatabaseContext())
{
ViewData["Type"] = new SelectList(dbContext.Types.ToList(), "Id", "Title");
}
if (!ModelState.IsValid)
{
return View();
}
else
{
Models.DatabaseContext dbContext = new Models.DatabaseContext();
Models.News news = new Models.News();
news.Title = newsInfo.Title;
news.Content = newsInfo.Content;
news.Date = DateTime.Now;
string newsinput = newsInfo.Tag.cleanTag();
string[] tags = new string[] { };
if (newsinput != null)
{
tags = newsinput.Split(',');
}
foreach (string item in tags)
{
Tag findTag = dbContext.Tags.Where(x => x.Title == item).FirstOrDefault();
if (findTag != null)
{
news.Tag.Add(findTag)
////////////////////////show error in this line
}
}
news.NewsType = dbContext.Types.Find(Convert.ToInt32(Request.Form["rdb"]));
dbContext.newsInfo.Add(news);
dbContext.SaveChanges();
return View();
}

How do I custom validate collections withing MVC5

I am building an MVC5 application and I have the following viewmodels:
public class UserPartyViewModel
{
public UserPartyViewModel()
{
Entitlements = new Collection<AssignedClaims>();
}
public Guid PartyID { get; set; }
public string PartyName { get; set; }
public ICollection<AssignedClaim> AssignedClaims{ get; set; }
}
public class AssignedClaims
{
public AssignedClaims()
{
ClaimValues = new Collection<AssignedClaimValue>();
}
public string Name { get; set; }
public int Max { get; set; }
public int Min { get; set; }
public ICollection<AssignedClaimValue> ClaimValues { get; set; }
}
public class AssignedClaimValue
{
public Guid ClaimValueID { get; set; }
public string ClaimValue { get; set; }
public bool Assigned { get; set; }
}
Contained in the UserPartyViewModel will always be an assignedclaim with a name of "Security" and the assignedclaimvalue with a claimvalue of "User"
If the ClaimValue of user is Assigned then I need to validate the rest of the model. If it is not then no further validation should take place.
Within AssignedClaims there is a min and max, these are the minimum and maximum number of assignedclaimvalues that should be Assigned.
I have tried to use AttributeValidate cannot stop it validating the rest of the model.
I have also looked at the IValidatableObject interface but also can't work out how to control the validation of the child collections depending on the User claim.
What's the best way to achieve this?
Found a solution which appears to do what I want:
public class UserPartyViewModel : IValidatableObject
{
public UserPartyViewModel()
{
Entitlements = new Collection<AssignedClaims>();
}
public string AccessLevel { get; set; }
public Guid PartyID { get; set; }
public string PartyName { get; set; }
public ICollection<AssignedClaims> Entitlements { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
var isUser = Entitlements.Any(c => c.Name == "Security" && c.ClaimValues.Any(v => v.Assigned == true && v.ClaimValue == "User"));
if (isUser)
{
int i = 0;
foreach (var result in Entitlements)
{
yield return result.Validate(i++);
}
}
else
{
yield return ValidationResult.Success;
}
}
}
public class AssignedClaims
{
public AssignedClaims()
{
ClaimValues = new Collection<AssignedClaimValue>();
}
public string Name { get; set; }
public string Description { get; set; }
public int Max { get; set; }
public int Min { get; set; }
public ICollection<AssignedClaimValue> ClaimValues { get; set; }
public ValidationResult Validate(int item)
{
int min = Min;
int max = (ClaimValues.Count() < Max) ? ClaimValues.Count() : Max;
int assignedCount = ClaimValues.Where(i => i.Assigned == true).Count();
if (!(min <= assignedCount && assignedCount <= max))
{
string errMessage = String.Format("{2} should have between {0} and {1} Security Claims checked.", min, max, Name);
return new ValidationResult(errMessage, new[] { string.Format("Entitlements[{0}]", item) });
}
else
{
return ValidationResult.Success;
}
}
}
The only issue I had was trying to get the error messages appearing in the correct place. In my view for assignedclaims I added:
#Html.ValidationMessageFor(model => model, "", new { #class = "text-danger" })
and passed the iteration through to the validate function on assignedclaim to ensure it was added to the correct member.

Select Foreign key data in EF

I have 2 models : Account and Task
public class Account
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Key]
public Guid UserId { get; set; }
public string UserType { get; set; }
public string Name { get; set; }
}
public class Task
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int id { get; set; }
[Key]
public Guid TaskId { get; set; }
[ForeignKey("TaskSubType")]
public Guid TaskSubTypeId { get; set; }
public virtual TaskSubType TaskSubType { get; set; }
[ForeignKey("Account")]
public Guid TaskCreator { get; set; }
public virtual Account Account { get; set; }
}
I call getTasks:
public List<TaskOverViewViewModel> GetTasks()
{
IEnumerable<Task> result = db.Tasks.AsEnumerable();
List<TaskOverViewViewModel> list = ToViewModelMapper.toViewModel(result);
return list;
}
public class ToViewModelMapper
{
internal static List<TaskOverViewViewModel> toViewModel(IEnumerable<Task> entitys )
{
List<TaskOverViewViewModel> modelList = new List<TaskOverViewViewModel>();
foreach (var entity in entitys)
{
TaskOverViewViewModel model = new TaskOverViewViewModel();
model.SubTaskName = entity.TaskSubType.Name;
model.TaskCreator = entity.Account.LoginName;
model.ToolsAccesable = entity.ToolsAccesable;
modelList.Add(model);
}
return modelList;
}
}
But it fails because i entity.TaskSubType and entity.Account is null. But if i return IEnumerable<Task> result = db.Tasks.AsEnumerable(); in the call everything works fine and i can see that Json contains all TaskSubtype and Account models.
From linq-to-entities, you can project directly to your ViewModel class.
public List<TaskOverViewViewModel> GetTasks()
{
List<TaskOverViewViewModel> result = (from t in db.Tasks
select new TaskOverViewViewModel
{
SubTaskName = t.TaskSubType.Name;
TaskCreator = t.Account.LoginName;
ToolsAccesable = t.ToolsAccesable;
}).ToList();
return result;
}
If you prefer method syntax, you can use this:
List<TaskOverViewViewModel> result = db.Tasks.Select(t => new TaskOverViewViewModel
{
SubTaskName = t.TaskSubType.Name;
TaskCreator = t.Account.LoginName;
ToolsAccesable = t.ToolsAccesable;
}).ToList();

Resolving LINQ Error: Missing Query Pattern Implementation

I am receiving a strange LINQ error when trying to filter a collection in my view.
This is my model:
public class adminEditProductsPricelistProductsVM
{
public Product Product { get; set; }
public PricelistProduct pricelistProduct { get; set; }
}
This is my view:
#using Pp.Lib.Models;
#using System.Linq;
#model PpLib.viewModels.admin.adminEditProductsPricelistProductsVM
#{
//get corresponding PricelistProduct
PricelistProduct thisPP = new ProofPixLib.Models.PricelistProduct();
thisPP = (from x in Model.pricelistProduct where x.ProductId == Model.Product.ProductId select x).FirstOrDefault();
}
the Model.pricelistProduct line is underlined in VS and it says the following error:
Could not find an implementation of the query pattern for source type Pp.Lib.Models.PricelistProduct. 'Where' not found.
Thanks in advance for your help!
UPDATE
As requested - here is the code for the PricelistProduct model.
public partial class PricelistProduct
{
public PricelistProduct()
{
this.PricelistProductOptions = new List<PricelistProductOption>();
}
[ReadOnly(true)]
[Display(Name = "Pricelist Product ID")]
public int PricelistProductId { get; set; }
[ReadOnly(true)]
[Display(Name = "Pricelist ID")]
public int PricelistId { get; set; } //foregin key
public virtual Pricelist Pricelist { get; set; }
[ReadOnly(true)]
[Display(Name = "Product ID")]
public int ProductId { get; set; } //foreign key
public virtual Product Product { get; set; }
[HiddenInput]
public int ProductCategoryId { get; set; } // not a FK but data only
public virtual ProductCategory ProductCategory { get; set; }
[Display(Name = "Use formula")]
private bool _UsesFormula = true;
public bool UsesFormula { get { return _UsesFormula; } set { _UsesFormula = value; } }
private decimal _Price = 0;
public decimal Price { get { return _Price; } set { _Price = value; } }
[Display(Name = "Use discount pricing")]
private bool _HasDiscountPricing = false;
public bool HasDiscountPricing { get { return _HasDiscountPricing; } set { _HasDiscountPricing = value; } }
[Display(Name = "Local shipping price")]
private decimal _LocalShipPrice = 0;
public decimal LocalShipPrice { get { return _LocalShipPrice; } set { _LocalShipPrice = value; } }
[Display(Name = "Intl. shipping price")]
private decimal _IntlShipPrice = 0;
public decimal IntlShipPrice { get { return _IntlShipPrice; } set { _IntlShipPrice = value; } }
[Display(Name = "Item is taxable")]
private bool _isTaxable = true;
public bool isTaxable { get { return _isTaxable; } set { _isTaxable = value; } }
public virtual List<PricelistProductOption> PricelistProductOptions { get; set; }
}
Your PricelistProduct class doesn't implement IEnumerable or IQuerable interfaces, other words it's not a collection to query over it.
Maybe it should be Model.pricelistProduct.PricelistProductOptions in your query or your view model should be a collection?
Consecutive assignments don't make sense as well:
#{
//get corresponding PricelistProduct
PricelistProduct thisPP = new ProofPixLib.Models.PricelistProduct();
thisPP = ..;
}

Object reference error in unit testing

i have a controller action
[HttpPost]
public ActionResult CreateFocus(FocusFormModel focus)
{
var errors = focusService.CanAddFocus(Mapper.Map<FocusFormModel, Focus>(focus)).ToList();
ModelState.AddModelErrors(errors);
if (ModelState.IsValid)
{
focusService.CreateFocus(Mapper.Map<FocusFormModel, Focus>(focus));
var createdfocus = focusService.GetFocus(focus.FocusName);
return RedirectToAction("Focus", new { id = createdfocus.FocusId });
}
return View("CreateFocus", focus);
}
This action is working fine but when i am writing unit test it is showing error
Object Reference Not set to an instance of an object
the uni test is
[Test]
public void Create_Focus()
{
// Arrange
GroupController controller = new GroupController(groupService);
// Act
FocusFormModel focus = new FocusFormModel();
focus.GroupId = 1;
focus.FocusName = "t";
focus.Description = "t";
Mapper.CreateMap<FocusFormModel, Focus>().ForAllMembers(opt => opt.Ignore());
Mapper.AssertConfigurationIsValid();
var result = (RedirectToRouteResult)controller.CreateFocus(focus);
Assert.AreEqual("Index", result.RouteValues["action"]);
}
My Model is described below
public class Focus
{
public int FocusId { get; set; }
[StringLength(50)]
public string FocusName { get; set; }
[StringLength(100)]
public string Description { get; set; }
public int GroupId { get; set; }
public virtual Group Group { get; set; }
public DateTime CreatedDate { get; set; }
public Focus()
{
CreatedDate = DateTime.Now;
}
}
and i am writing my view model as
public class FocusFormModel
{
public int FocusId { get; set; }
[Required(ErrorMessage = "*")]
[StringLength(50)]
public string FocusName { get; set; }
[Required(ErrorMessage = "*")]
[StringLength(100)]
public string Description { get; set; }
public int GroupId { get; set; }
public virtual Group Group { get; set; }
public DateTime CreatedDate { get; set; }
public FocusFormModel()
{
CreatedDate = DateTime.Now;
}
}
Can any one please help me
This line actually provides 2 chances to get null reference exception:
var errors = focusService.CanAddFocus(Mapper.Map<FocusFormModel, Focus>(focus)).ToList();
first of all focusService might be null
if focusService is not null then method call CanAddFocus(Mapper.Map<FocusFormModel, Focus>(focus)) might return null
That are just assumptions.
As Greg Smith said stack trace would be very helpful here.

Resources