Html.HiddenFor helper throwing null exception - asp.net-mvc

I want to pass a value from the model...
#Html.HiddenFor(model => model.ProductId)
Exception thrown: 'System.ArgumentException' in System.Web.Mvc.dll
Additional information: Value cannot be null or empty.
But it is throwing this exception and I don't know why... And no ProductId isn't null.
Action
[HttpGet]
public ActionResult Edit(int ProductId = 0)
{
PCsViewModel pcViewModel = new PCsViewModel();
ProductRepository productRepo = new ProductRepository();
Product dbProduct = productRepo.GetAll(item=>item.ID==ProductId);
PCsRepository pcsRepo = new PCsRepository();
PC dbPC = pcsRepo.GetAll(item=>item.ProductID==ProductId);
if (dbProduct != null && dbPC != null)
{
pcViewModel = new PCsViewModel(dbProduct,dbPC);
}
return View(pcViewModel);
}
ViewModel
public int ProductId { get; set; }
[Required]
public string Name { get; set; }
public string PCsInfo { get; set; }//for the front view
[Required]
public double Price { get; set; }
[Required]
public string ImagePath { get; set; }
[Required]
public string Processor { get; set; }
[Required]
public string OS { get; set; }
[Required]
public int RAM { get; set; }
[Required]
public int Storage { get; set; }
[Required]
public string VideoCard { get; set; }
[Required]
public int CategoryID { get; set; }
public PCsViewModel()
{
}
public PCsViewModel(Product product, PC pc)
{
this.ProductId = product.ID;
this.CategoryID = product.CategoryID;
this.OS = product.OS;
this.Processor = product.Processor;
this.Name = product.Name;
this.RAM = product.RAM;
this.Storage = product.Storage;
this.VideoCard = pc.VideoCard;
this.PCsInfo = "PC "+product.Name + "with processor " + product.Processor;
this.Price = (double)product.Price;
this.ImagePath = Path.Combine(Constants.ImagesPCsDirectory, product.ImageName);
}

Based of the discussion in the comments, it looks like your actual issue wasn't related to the ProductId property but instead your ImagePath property, which was being passed into a Url.Content() helper (to resolve the appropriate path).
This would work as expected if the path existed, but if that property was null or empty, you would receive the ArgumentNullException that you currently are. The best approach would likely be to just only render the specific path if that specific property wasn't null:
#if (!string.IsNullOrEmpty(Model.ImagePath)) {
// Use Url.Content(Model.ImagePath) within here safely
}
There are multiple different ways to handle this, such as adding an additional property on your model to clean things up:
public bool HasImage => !string.IsNullOrEmpty(ImagePath);
And then use:
#if (Model.HasImage) {
// Use Url.Content(Model.ImagePath) within here safely
}

Related

Asp.net Mvc display list depending on User

What i have initially on my App is a list of expensives that is created based on the Scarfolding System but that list is the same for each User, and what i want is that each user can create his own list of expensives and see his own data.
So in the expensive class i did this:
public class Despesa
{
public int TipoDespesaId { get; set; }
public int DespesaId { get; set; }
public string UserId { get; set; }
[Display(Name = "Descrição da Despesa")]
[Required]
public string DespesaDescricao { get; set; }
[Display(Name = "Valor")]
[Required]
public decimal DespesaValor { get; set; }
public int TipoPagamentoId { get; set; }
[Display(Name = "Data")]
[DataType(DataType.Date)]
[CustomValidation(typeof(Validator), "ValidateEndTimeRange")]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}",ApplyFormatInEditMode = true)]
[Required]
public DateTime Data { get; set; }
public TipoDespesa TipoDespesa { get; set; }
public TipoPagamento TipoPagamento { get; set; }
[Display(Name = "Comentário")]
public string Comentario { get; set; }
}
i just passed the UserId to the model and then in the Index controller of my Expensive View i did a linq query to compare the currentUserID to the Id of the expensive User here is my code:
public ActionResult Index()
{
String userId = User.Identity.GetUserId();
var despesas = from r in db.Despesas.Include(d => d.TipoDespesa).Include(d => d.TipoPagamento).Include(d => d.UserId)
where r.UserId.Equals(userId)
select r;
return View(despesas.ToList());
}
what i need to know is what i am doing wrong cause i get a invalidOperationException
Only navigation properties can be used with .Include() it seems.
You are trying to include a primitive property (UserId), and it then throws the error when converting to a list because it has no navigation property.
var despesas = from r in db.Despesas.Include(d => d.TipoDespesa).Include(d => d.TipoPagamento).Where(x => x.UserId == userId) select r;

Why Web Api include properties in response that are not projected

I have a view model
public class MyViewModel
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Position { get; set; }
public string Email { get; set; }
public string Office { get; set; }
public DateTime? StartDate { get; set; }
public int? Age { get; set; }
public int? Salary { get; set; }
public int? Extn { get; set; }
}
And I am doing projection on my entity
public List<ViewModel.StaffViewModel> GetAll()
{
var context = new GistDemoDbEntities();
var model = context.Staff
.Select(s => new ViewModel.StaffViewModel
{
FirstName = s.FirstName,
LastName = s.LastName,
Position = s.Position,
Salary = s.Salary
}).ToList();
return model;
}
And use Web Api to return back as json, but in reponse I found out it includes other properties as well that define in the View Model with vlaue null. I only want to have those properties that I need in reponse, how is it possible?
You can either:
Remove them from your ViewModel, a view model should only conta9in
what you intend to use anyway.
or
Use [JsonIgnore] on your properties to prevent JSON.Net from mapping
them.
Json Ignore is an attribute, look here;
http://james.newtonking.com/json/help/index.html?topic=html/SerializationAttributes.htm

Convert TimeSpan to String in MVC 3 Controller

I have a question , I have a Timespan in my Database and i want to use it in my controller but this error appears
Cannot implicitly convert type 'string' to 'System.TimeSpan'
Controller :
int id = Convert.ToInt32(clientId);
clientShift = (from a in db.Client_Shift
where a.ID == id
select a).SingleOrDefault();
clientShift.DayFrom_LookID = Convert.ToInt32(dateFrom);
clientShift.DayTo_LookID = Convert.ToInt32(dateTo);
This is where the error occur --> clientShift.EndTime = endTime.Trim();
clientShift.DateModified = DateTime.UtcNow;
clientShift.ModifiedBy = User.Identity.Name;
Model :
public partial class Client_Shift
{
public int ID { get; set; }
public int Client_ID { get; set; }
public int DayFrom_LookID { get; set; }
public int DayTo_LookID { get; set; }
public System.TimeSpan StartTime { get; set; }
public System.TimeSpan EndTime { get; set; }
Thanks for someone who can help me :D
You need to Parse the TimeSpan:
clientShift.EndTime = TimeSpan.Parse(endTime.Trim());
If the string does not represent a valid time span, you will get an exception.

MVC 4 Web API NullException Error (Noobie)

I'm working on my first MVC 4 app, following the MVC First Web API Tutorial on Asp.net. I've left the names the same, but changed the model and controller code. Here's my model:
public class Product
{
public string SID { get; set; }
public string name { get; set; }
public string givenName { get; set; }
public string sn { get; set; }
public string mail { get; set; }
public string telephoneNumber { get; set; }
public string mobile { get; set; }
public string otherMobile { get; set; }
public string title { get; set; }
public string Manager { get; set; }
public DateTime whenChanged { get; set; }
}
public class ProductModel
{
public ProductModel()
{
ProductList = new List<Product>();
}
public IList<Product> ProductList { get; set; }
}
And here's my APIcontroller:
public class ProductsController : ApiController
{
ProductModel products = new ProductModel();
public IEnumerable<Product> GetAD()
{
DirectoryEntry domainRoot = new DirectoryEntry(LDAP_server);
DirectorySearcher searcher = new DirectorySearcher(searchStr);
SearchResultCollection results = searcher.FindAll();
foreach (SearchResult srchResult in results)
{
DirectoryEntry dirEntry = srchResult.GetDirectoryEntry();
if (dirEntry.Properties["givenName"].Value != null && dirEntry.Properties["sn"].Value != null && !dirEntry.Parent.Name.Contains("Terminated"))
{
products.ProductList.Add(new Product()
{
SID = dirEntry.Properties["sid"].Value.ToString(),
name = dirEntry.Properties["name"].Value.ToString(),
givenName = dirEntry.Properties["givenName"].Value.ToString(),
sn = dirEntry.Properties["sn"].Value.ToString(),
mail = dirEntry.Properties["mail"].Value.ToString(),
telephoneNumber = dirEntry.Properties["telephoneNumber"].Value.ToString(),
mobile = dirEntry.Properties["mobile"].Value.ToString(),
otherMobile = dirEntry.Properties["otherMobile"].Value.ToString(),
title = dirEntry.Properties["title"].Value.ToString(),
Manager = dirEntry.Properties["Manager"].Value.ToString(),
whenChanged = Convert.ToDateTime(dirEntry.Properties["whenChanged"].Value.ToString()),
});
}
}
return products.ProductList;
}
}
I'm getting the NullException on 'products.ProductList.Add(new Product()', am I missing something simple? Please forgive my coding, as I'm just trying to get this up and running, thanks.
the problem mostly likely is dealing with dirEntry, not Web API itself. rather than introduce LDAP into this, just create a bunch of dummy products to return.
FYI... there is also a memory leak issue with the use of LDAP objects. They need to be properly disposed of, both along the happy path and if an exception is thrown.
I'm an idiot. 'sid' is not the correct property name from AD, it is 'objectSid', thus always returning a null. I knew it was something simple.

The model item passed into the dictionary is of type 'ViewModels.SiteModel',

I'm newbie to MVC architecture.When I'm trying to update, its showing error ,Its totally strange but the data is updating.
The model item passed into the dictionary is of type 'CMS.Domain.Models.Site', but this dictionary requires a model item of type 'CMS.Web.ViewModels.SiteModel'.'.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.InvalidOperationException: The model item passed into the dictionary is of type 'CMS.Web.ViewModels.SiteModel', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable`1[CMS.Web.ViewModels.SiteModel]'.
My code looks like:
ViewModels:
namespace CMS.Web.ViewModels
{
public class SiteModel
{
public SiteModel()
{
SiteStatus = new List<SelectListItem>();
}
[Key]
public int ID { get; set; }
[Required(ErrorMessage = "Site Name is required")]
[Display(Name = "Site Name")]
public string Title { get; set; }
[Display(Name = "Require Login")]
public bool RequiresLogin { get; set; }
[Display(Name = "Force HTTPS")]
public bool ForceHTTPS { get; set; }
[Display(Name = "Enable Approval")]
public bool Approval { get; set; }
[AllowHtml]
public IList<SelectListItem> SiteStatus { get; set; }
public bool Deleted { get; set; }
public string CreatedBy { get; set; }
public DateTime CreatedOn
{
get { return _createdOn; }
set { _createdOn = value; }
}
private DateTime _createdOn = DateTime.Now;
public string LastUpdatedBy { get; set; }
public DateTime LastUpdatedOn
{
get { return _lastUpdatedOn; }
set { _lastUpdatedOn = value; }
}
private DateTime _lastUpdatedOn = DateTime.Now;
[Display(Name = "Site State")]
public string SiteState { get; set; }
}
}
Model:
namespace CMS.Domain.Models
{
public partial class Site : Model
{
public string Title { get; set; }
public bool Approval { get; set; }
public bool RequiresLogin { get; set; }
public bool ForceHTTPS { get; set; }
public virtual string SiteStatus { get; set; }
public bool Deleted { get; set; }
}
}
Controller:
public ActionResult Index()
{
var _sites = _siterepository.FindAll();
return View(_sites);
}
public ActionResult Add()
{
var model = new SiteModel();
var _SiteStatus = _siterepository.GetSiteStatus();
foreach (var _sitestatus in _SiteStatus)
{
model.SiteStatus.Add(new SelectListItem()
{
Text = _sitestatus.StatusName,
Value = _sitestatus.StatusName.ToString()
});
}
return View(model);
}
[HttpPost]
public ActionResult Add(SiteModel _sitemodel)
{
var model = _sitemodel.ToEntity();
_siterepository.Add(model);
return View(model);
}
public ActionResult Edit(int id)
{
var model = new SiteModel();
var Site = _siterepository.Find(id);
model = Site.ToModel();
var _SiteStatus = _siterepository.GetSiteStatus();
foreach (var _sitestatus in _SiteStatus)
{
model.SiteStatus.Add(new SelectListItem()
{
Text = _sitestatus.StatusName,
Value = _sitestatus.StatusName.ToString(),
Selected = _sitestatus.StatusName == Site.SiteStatus
});
}
return View(model);
}
[HttpPost]
public ActionResult Edit(SiteModel _sitemodel)
{
var model = _sitemodel.ToEntity();
_siterepository.Update(model);
return View(model);
}
I'm struggling to resolve this , please help.
Check your View's model declaration. It is expecting an enumerable list (IEnumerable<CMS.Web.ViewModels.SiteModel>), but you are passing it a single instance of CMS.Web.ViewModels.SiteModel

Resources