What does this model error says in asp.net mvc? - asp.net-mvc

My Html action link takes me to a view where i can see the details..
For Ex:http://localhost:1985/Materials/Details/4
But it shows error,
The model item passed into the dictionary is of type
'System.Data.Linq.DataQuery`1[CrMVC.Models.ConstructionRepository+Materials]'
but this dictionary requires a model item of type
'CrMVC.Models.ConstructionRepository+Materials'.
And my model is...
public IQueryable<Materials> GetMaterial(int id)
{
return from m in db.Materials
join Mt in db.MeasurementTypes on m.MeasurementTypeId equals Mt.Id
where m.Mat_id == id
select new Materials()
{
Id = Convert.ToInt64(m.Mat_id),
Mat_Name = m.Mat_Name,
Mes_Name = Mt.Name,
};
}
public class Materials
{
private Int64 id;
public string mat_Name;
public string mes_Name;
public Int64 Id
{
get
{
return id;
}
set
{
id = value;
}
}
public string Mat_Name
{
get
{
return mat_Name;
}
set
{
mat_Name = value;
}
}
public string Mes_Name
{
get
{
return mes_Name;
}
set
{
mes_Name = value;
}
}
}
}
and my controller method...
public ActionResult Details(int id)
{
var material = consRepository.GetMaterial(id).AsQueryable();
return View("Details", material);
}
Any suggestion what am i missing here?

Your GetMaterial(id) method should probably return just one Material instance because your View expects just one instance. E.g:
public Materials GetMaterial(int id)
{
return (from m in db.Materials
join Mt in db.MeasurementTypes on m.MeasurementTypeId equals Mt.Id
where m.Mat_id == id
select new Materials()
{
Id = Convert.ToInt64(m.Mat_id),
Mat_Name = m.Mat_Name,
Mes_Name = Mt.Name,
}).FirstOrDefault();
}

Related

public ActionResult Index5() { return RedirectToAction("Index","Student", new { name = "ATHUL",address="TVM" }); }

public ActionResult Index(string name, string address)
{
Student obj = new Student()
{
name = "VAZEEM",
address="CALCUT"
};
return View(obj);
}
public ActionResult Index5()
{
return RedirectToAction("Index","Student", new { name = "ATHUL",address="TVM" });
}
please corrept the code
change index detail to index5 detail

WCF---Consuming CRUD operation using Linq in ASP.NET MVC application?

enter image description here
First step...Opened WCF created IService:
namespace CRUDOperationWCFMVC
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IService1" in both code and config file together.
[ServiceContract]
public interface IService1
{
[OperationContract]
bool CreateDetails(EmployeeDetails employeeDetails);
[OperationContract]
bool UpdateDetails(EmployeeDetails employeeDetails);
[OperationContract]
bool DeleteDetails(int id);
[OperationContract]
List<EmployeeDetails> GetDetails();
}
public class EmployeeDetails
{
[DataMember]
public int EmpID { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public string Location { get; set; }
[DataMember]
public int? Salary { get; set; }
}
}
Step 2: then I implemented service code:
public class Service1 : IService1
{
DataClasses1DataContext dcd = new DataClasses1DataContext();
public bool CreateDetails(EmployeeDetails employeeDetails)
{
Nevint emp = new Nevint();
emp.EmpID= employeeDetails.EmpID;
emp.Name = employeeDetails.Name;
emp.Location = employeeDetails.Location;
emp.Salary = employeeDetails.Salary;
dcd.Nevints.InsertOnSubmit(emp);
dcd.SubmitChanges();
return true;
}
public bool DeleteDetails(int id)
{
var delete = (from v in dcd.Nevints where v.EmpID==id select v).FirstOrDefault();
dcd.Nevints.DeleteOnSubmit(delete);
dcd.SubmitChanges();
return true;
}
public List<EmployeeDetails> GetDetails()
{
List<EmployeeDetails> details = new List<EmployeeDetails>();
var select= (from v in dcd.Nevints select v);
foreach (var i in select)
{
EmployeeDetails emp = new EmployeeDetails();
emp.EmpID = i.EmpID;
emp.Name = i.Name;
emp.Location = i.Location;
emp.Salary = i.Salary;
details.Add(emp);
}
return details;
}
public bool UpdateDetails(EmployeeDetails employeeDetails)
{
var update = (from v in dcd.Nevints.ToList() where employeeDetails.EmpID==v.EmpID select v).FirstOrDefault();
update.EmpID = employeeDetails.EmpID;
update.Name = employeeDetails.Name;
update.Location = employeeDetails.Location;
update.Salary = employeeDetails.Salary;
dcd.SubmitChanges();
return true;
}
}
Step 3: then I add linq to sql, opened my ASP.NET MVC project for consuming, and added a controller and wrote this code:
namespace ConsumingClient.Controllers
{
public class EmpdetailsController : Controller
{
ServiceReference1.Service1Client serobj=new ServiceReference1.Service1Client();
ServiceReference1.EmployeeDetails empdetails=new ServiceReference1.EmployeeDetails();
// GET: Empdetails
public ActionResult Index()
{
List<employee> lstemp = new List<employee>();
var result = serobj.GetDetails();
foreach (var i in result)
{
employee emp = new employee();
empdetails.EmpID = i.EmpID;
empdetails.Name = i.Name;
empdetails.Location = i.Location;
empdetails.Salary = i.Salary;
lstemp.Add(emp);
}
return View(result);
}
// GET: Empdetails/Details/5
public ActionResult Details(int id)
{
Employees emp = new Employees();
return View();
}
// GET: Empdetails/Create
public ActionResult Create()
{
return View();
}
// POST: Empdetails/Create
[HttpPost]
public ActionResult Create(Employees employees)
{
try
{
// TODO: Add insert logic here
empdetails.EmpID=employees.EmpID;
empdetails.Name = employees.Name;
empdetails.Location = employees.Location;
empdetails.Salary = employees.Salary;
serobj.CreateDetails(empdetails);
return RedirectToAction("Index");
}
catch
{
return View();
}
}
// GET: Empdetails/Edit/5
public ActionResult Edit(int id)
{
Employees emp = new Employees();
var result = serobj.GetDetails().FirstOrDefault(a=>a.EmpID==id);
emp.EmpID = result.EmpID;
emp.Name = result.Name;
emp.Location = result.Location;
emp.Salary = result.Salary;
return View(emp);
}
// POST: Empdetails/Edit/5
[HttpPost]
public ActionResult Edit(Employees employees)
{
try
{
// TODO: Add update logic here
empdetails.EmpID = employees.EmpID;
empdetails.Name = employees.Name;
empdetails.Location = employees.Location;
empdetails.Salary = employees.Salary;
serobj.UpdateDetails(empdetails);
return RedirectToAction("Index");
}
catch
{
return View(employees);
}
}
// GET: Empdetails/Delete/5
public ActionResult Delete(int id)
{
Employees emp = new Employees();
var result = serobj.GetDetails().FirstOrDefault(a=>a.EmpID==id);
emp.EmpID = result.EmpID;
emp.Name = result.Name;
emp.Location = result.Location;
emp.Salary = result.Salary;
return View(emp);
}
// POST: Empdetails/Delete/5
[HttpPost]
public ActionResult Delete(int id, FormCollection collection)
{
try
{
// TODO: Add delete logic here
serobj.DeleteDetails(id);
return RedirectToAction("Index");
}
catch
{
return View(id);
}
}
}
}
Data was displaying fine. I can create data.
However, when I click on edit and delete, I'm getting an error:
ERROR Message "Server Error in '/' Application.
The parameters dictionary contains a null entry for parameter 'id' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult Edit(Int32)' in 'ConsumingClient.Controllers.EmpdetailsController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.
Parameter name: parameters
This error is thrown if you attempt to call this controller action and you do not specify the id either in the path portion or as query string parameter. Since your controller action takes an id as parameter you should make sure that you always specify this parameter.
Make sure that when you are requesting this action you have specified a valid id in the url:
http://example.com/somecontroller/Edit/123
If you are generating an anchor, make sure there's an id:
#Html.ActionLink("Edit", "somecontroller", new { id = "123" })
If you are sending an AJAX request, also make sure that the id is present in the url.
If on the other hand the parameter is optional, you could make it a nullable integer:
public ActionResult Edit(int? id)
but in this case you will have to handle the case where the parameter value is not specified.
https://coderedirect.com/questions/197477/mvc-the-parameters-dictionary-contains-a-null-entry-for-parameter-k-of-non-n

Can't convert from int to "classname"

While building a ASP.NET-MVC website I was trying to implement a EDIT page on my website, but I'm having some difficulties, particulary in my Controller. The error is in this class, pointing to the ID:
public IActionResult Edit(int ID = 0)
{
GestaoAlertas _teste = addresses.Contains(ID);
return View(_teste);
}
And the error says:
It is not possible to convert from int to "hdsportal.GestaoAlertas"
Controller:
public class HomeController : Controller
{
SqlCommand com = new SqlCommand();
SqlDataReader dr;
SqlConnection con = new SqlConnection();
List<GestaoAlertas> addresses = new List<GestaoAlertas>();
private readonly ILogger<HomeController> _logger;
public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
con.ConnectionString = "secret";
}
public IActionResult Gestao_Alertas()
{
FetchData();
return View(addresses);
}
[Route("")]
public IActionResult Index()
{
FetchData();
return View(addresses);
}
public IActionResult Edit(int ID = 0)
{
GestaoAlertas _teste = addresses.Contains(ID);
return View(_teste);
}
public IActionResult Privacidade()
{
return View();
}
public IActionResult Gestao_Utilizadores()
{
return View();
}
public IActionResult Contatos()
{
return View();
}
public IActionResult QuemSomos()
{
return View();
}
private void FetchData()
{
if (addresses.Count > 0)
{
addresses.Clear();
}
try
{
con.Open();
com.Connection = con;
com.CommandText = "SELECT [ID], [SYSTEM_NAME], [SYSTEM_STATUS], [SYSTEM_SHORTMSG] FROM [CORE_SYS_STATUS]";
dr = com.ExecuteReader();
while (dr.Read())
{
addresses.Add(new GestaoAlertas()
{
ID = (int)dr["ID"]
,
SYSTEM_NAME = dr["SYSTEM_NAME"].ToString()
,
SYSTEM_STATUS = dr["SYSTEM_STATUS"].ToString()
,
SYSTEM_SHORTMSG = dr["SYSTEM_SHORTMSG"].ToString()
});
}
con.Close();
}
catch (Exception ex)
{
throw ex;
}
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
}
Model:
public class GestaoAlertas
{
public int ID { get; set; }
public string SYSTEM_NAME { get; set; }
public string SYSTEM_STATUS { get; set; }
public string SYSTEM_SHORTMSG { get; set; }
}
Issue & Concern
According to List<T>.Contains(T), you need parse T object which is GestaoAlertas object to your addresses (List<GestaoAlertas> type).
Hence, you get the error below as it is an unmatched type with int
It is not possible to convert from int to "hdsportal.GestaoAlertas"
for this line:
GestaoAlertas _teste = addresses.Contains(ID);
And List<T>.Contains(T) returns the boolean result.
public bool Contains (T item);
Determines whether an element is in the List.
Solution(s)
Assumptions:
addresses contain GestaoAlertas records
You can get GestaoAlertas element from addresses by ID with either of these LINQ methods:
Pre-requisite:
Import System.Linq namespace.
using System.Linq;
Solution 1: Enumerable.SingleOrDefault
Returns a single, specific element of a sequence, or a default value if that element is not found.
Note: It will throw InvalidOperationException if input sequence contains more than one element. Good to be use for unique identifier such as ID.
GestaoAlertas _teste = addresses.SingleOrDefault(x => x.ID == ID);
Solution 2: Enumerable.Single
Returns a single, specific element of a sequence.
Note: It will throw ArgumentNullException if it returns null.
GestaoAlertas _teste = addresses.Single(x => x.ID == ID);
Solution 3: Enumerable.FirstOrDefault
Returns the first element of a sequence, or a default value if no element is found.
GestaoAlertas _teste = addresses.FirstOrDefault(x => x.ID == ID);
Solution 4: Enumerable.First
Returns the first element of a sequence.
Note: It will throw ArgumentNullException if it returns null.
GestaoAlertas _teste = addresses.First(x => x.ID == ID);

Cannot implicitly convert type 'Note6MVCApplication5.Models.SPGetEmpDetailsByEmpIdJoinResult' to 'Note6MVCApplication5.Models.Emp'

public ActionResult Edit(int? id)
{
Emp emp = db.SPGetEmpDetailsByEmpIdJoin(id).SingleOrDefault();
ViewData["DeptId"] = new SelectList(db.SPGetAllDeptDetails().ToList(), "DeptId", "DeptName", emp.DeptId);
return View(emp);
}
Error : Cannot implicitly convert type 'Note6MVCApplication5.Models.SPGetEmpDetailsByEmpIdJoinResult' to 'Note6MVCApplication5.Models.Emp'
Why this error is coming?
I am posting definition of SPGetEmpDetailsByEmpIdJoinResult() which is present in MVCDemoDB.Designer.cs
public partial class SPGetEmpDetailsByEmpIdJoinResult
{
private int _EmpId;
private string _EmpName;
private string _EmpJob;
private decimal _EmpSalary;
private int _DeptId;
private string _DeptName;
public SPGetEmpDetailsByEmpIdJoinResult()
{
}
[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_EmpId", DbType="Int NOT NULL")]
public int EmpId
{
get
{
return this._EmpId;
}
set
{
if ((this._EmpId != value))
{
this._EmpId = value;
}
}
}
[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_EmpName", DbType="VarChar(50) NOT NULL", CanBeNull=false)]
public string EmpName
{
get
{
return this._EmpName;
}
set
{
if ((this._EmpName != value))
{
this._EmpName = value;
}
}
}
[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_EmpJob", DbType="VarChar(50) NOT NULL", CanBeNull=false)]
public string EmpJob
{
get
{
return this._EmpJob;
}
set
{
if ((this._EmpJob != value))
{
this._EmpJob = value;
}
}
}
[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_EmpSalary", DbType="Money NOT NULL")]
public decimal EmpSalary
{
get
{
return this._EmpSalary;
}
set
{
if ((this._EmpSalary != value))
{
this._EmpSalary = value;
}
}
}
[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_DeptId", DbType="Int NOT NULL")]
public int DeptId
{
get
{
return this._DeptId;
}
set
{
if ((this._DeptId != value))
{
this._DeptId = value;
}
}
}
[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_DeptName", DbType="VarChar(50) NOT NULL", CanBeNull=false)]
public string DeptName
{
get
{
return this._DeptName;
}
set
{
if ((this._DeptName != value))
{
this._DeptName = value;
}
}
}
}
It seems to be Type Cast Error. i would suggest declare variable of type 'var' instead of Emp in below statement
Emp emp = db.SPGetEmpDetailsByEmpIdJoin(id).SingleOrDefault();
to something like this
var emp = db.SPGetEmpDetailsByEmpIdJoin(id).SingleOrDefault();
second approach
Define extension method to cast SPGetEmpDetailsByEmpIdJoinResult to Emp some thing like below
sample Emp class
public class Emp
{
public int DeptId { get; set; }
public int EmpId { get; set; }
/*
* define other properties
*/
}
public static Emp ToEmp(this SPGetEmpDetailsByEmpIdJoinResult empResult)
{
return new Emp() {EmpId = empResult.EmpId, DeptId = empResult.DeptId};
}
and call the extension method
Emp emp = db.SPGetEmpDetailsByEmpIdJoin(id).SingleOrDefault().ToEmp();
that would fix your issue. hope this helps :)

Get custom attribute for parameter when model binding

I've seen a lot of similar posts on this, but haven't found the answer specific to controller parameters.
I've written a custom attribute called AliasAttribute that allows me to define aliases for parameters during model binding. So for example if I have: public JsonResult EmailCheck(string email) on the server and I want the email parameter to be bound to fields named PrimaryEmail or SomeCrazyEmail I can "map" this using the aliasattribute like this: public JsonResult EmailCheck([Alias(Suffix = "Email")]string email).
The problem: In my custom model binder I can't get a hold of the AliasAttribute class applied to the email parameter. It always returns null.
I've seen what the DefaultModelBinder class is doing to get the BindAttribute in reflector and its the same but doesn't work for me.
Question: How do I get this attribute during binding?
AliasModelBinder:
public class AliasModelBinder : DefaultModelBinder
{
public static ICustomTypeDescriptor GetTypeDescriptor(Type type)
{
return new AssociatedMetadataTypeTypeDescriptionProvider(type).GetTypeDescriptor(type);
}
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var value = base.BindModel(controllerContext, bindingContext);
var descriptor = GetTypeDescriptor(bindingContext.ModelType);
/*************************/
// this next statement returns null!
/*************************/
AliasAttribute attr = (AliasAttribute)descriptor.GetAttributes()[typeof(AliasAttribute)];
if (attr == null)
return null;
HttpRequestBase request = controllerContext.HttpContext.Request;
foreach (var key in request.Form.AllKeys)
{
if (string.IsNullOrEmpty(attr.Prefix) == false)
{
if (key.StartsWith(attr.Prefix, StringComparison.InvariantCultureIgnoreCase))
{
if (string.IsNullOrEmpty(attr.Suffix) == false)
{
if (key.EndsWith(attr.Suffix, StringComparison.InvariantCultureIgnoreCase))
{
return request.Form.Get(key);
}
}
return request.Form.Get(key);
}
}
else if (string.IsNullOrEmpty(attr.Suffix) == false)
{
if (key.EndsWith(attr.Suffix, StringComparison.InvariantCultureIgnoreCase))
{
return request.Form.Get(key);
}
}
if (attr.HasIncludes)
{
foreach (var include in attr.InlcludeSplit)
{
if (key.Equals(include, StringComparison.InvariantCultureIgnoreCase))
{
return request.Form.Get(include);
}
}
}
}
return null;
}
}
AliasAttribute:
[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
public class AliasAttribute : Attribute
{
private string _include;
private string[] _inlcludeSplit = new string[0];
public string Prefix { get; set; }
public string Suffix { get; set; }
public string Include
{
get
{
return _include;
}
set
{
_include = value;
_inlcludeSplit = SplitString(_include);
}
}
public string[] InlcludeSplit
{
get
{
return _inlcludeSplit;
}
}
public bool HasIncludes { get { return InlcludeSplit.Length > 0; } }
internal static string[] SplitString(string original)
{
if (string.IsNullOrEmpty(original))
{
return new string[0];
}
return (from piece in original.Split(new char[] { ',' })
let trimmed = piece.Trim()
where !string.IsNullOrEmpty(trimmed)
select trimmed).ToArray<string>();
}
}
Usage:
public JsonResult EmailCheck([ModelBinder(typeof(AliasModelBinder)), Alias(Suffix = "Email")]string email)
{
// email will be assigned to any field suffixed with "Email". e.g. PrimaryEmail, SecondaryEmail and so on
}
Gave up on this and then stumbled across the Action Parameter Alias code base that will probably allow me to do this. It's not as flexible as what I started out to write but probably can be modified to allow wild cards.
what I did was make my attribute subclass System.Web.Mvc.CustomModelBinderAttribute which then allows you to return a version of your custom model binder modified with the aliases.
example:
public class AliasAttribute : System.Web.Mvc.CustomModelBinderAttribute
{
public AliasAttribute()
{
}
public AliasAttribute( string alias )
{
Alias = alias;
}
public string Alias { get; set; }
public override IModelBinder GetBinder()
{
var binder = new AliasModelBinder();
if ( !string.IsNullOrEmpty( Alias ) )
binder.Alias = Alias;
return binder;
}
}
which then allows this usage:
public ActionResult Edit( [Alias( "somethingElse" )] string email )
{
// ...
}

Resources