I have repository class in asp.net mvc which has this,
public Material GetMaterial(int id)
{
return db.Materials.SingleOrDefault(m => m.Mat_id == id);
}
And my controller has this for details action result,
ConstructionRepository consRepository = new ConstructionRepository();
public ActionResult Details(int id)
{
Material material = consRepository.GetMaterial(id);
return View();
}
But why i get this error,
The parameters dictionary contains a null entry for parameter 'id' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult Details(Int32)' in 'CrMVC.Controllers.MaterialsController'. To make a parameter optional its type should be either a reference type or a Nullable type.
Parameter name: parameters
Any suggestion...
You're getting the error because you're not passing an id to the controller method.
You basically have two options:
Always pass a valid id to the controller method, or
Use an int? parameter, and coalesce the null before calling GetMaterial(id).
Regardless, you should check for a null value for material. So:
public ActionResult Details(int? id)
{
Material material = consRepository.GetMaterial((int)(id ?? 0));
if (id == null)
return View("NotFound");
return View();
}
Or (assuming you always pass a proper id):
public ActionResult Details(int id)
{
Material material = consRepository.GetMaterial(id);
if (id == null)
return View("NotFound");
return View();
}
To pass a valid id to the controller method, you need a route that looks something like this:
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id="" }
);
And an URL that looks like this:
http://MySite.com/MyController/GetMaterial/6 <-- id
It means the param (int id) was passed a null, use (int? id)
(in the controller)
Related
I set the E_id as a primary key.My Edit function is not working.It continuously throws the error.But my create and index functions working good.What will be the problem in my code?This is the ERROR
[ArgumentException: 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 'BusinessObjects.Controllers.EmployeeController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.
Parameter name: parameters]
public ActionResult Index()
{
EmployeeBusinessLayer employeebusinesslayer = new EmployeeBusinessLayer();
List<Employee> employees = employeebusinesslayer.Employees.ToList();
return View(employees);
}
[HttpGet] //Create after this Get
[ActionName("Create")] //old name of function
public ActionResult Create_get()
{
return View();
}
[HttpGet]
public ActionResult Edit(int id)
{
EmployeeBusinessLayer employeebusinesslayer = new EmployeeBusinessLayer();
Employee employee = employeebusinesslayer.Employees.Single(emp => emp.E_id == id);
return View(employee);
}
[HttpPost] //Create after this Get
[ActionName("Create")]//old name of function
public ActionResult Create_post()
{
if (ModelState.IsValid)
{
Employee employee = new Employee();
UpdateModel(employee); //Updatemodel for employee - Call for new entries
EmployeeBusinessLayer employeebusinesslayer = new EmployeeBusinessLayer();
employeebusinesslayer.AddEmployee(employee);
return RedirectToAction("Index");
}
return View();
}
}
}
You should change Edit(int id) to Edit(int? id) to prevent case input id empty in URL or not number.
And update this line of code
Employee employee = id != null ? employeebusinesslayer.Employees.Single(emp => emp.E_id == id.Value) : null;
I've two action method in the following controller-
public class VisitMasterController
{
public ActionResult StartBrVisit()
{
string id=(Request.QueryString["id"].ToString(); //value=null here
}
public ActionResult BrNotPresent()
{
return RedirectToAction("StartBrVisit","VisitMaster" , new { id = "id", name = "name" });
}
{
After Redirect, Request.QueryString["id"] returns null.
My default route config is-
context.MapRoute(
"BR_default",
"BR/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional },
new[] { "OpinionLeader.Areas.BR.Controllers" } //add this line
);
Any help?
You have defined a route with a parameter named id so when you use new { id = "id" }, the RedirectToAction() method finds a match and adds the value as a route value, not a query string value (in the case of name, there is no match, so its value is added as a query string value). You could access it using
string id = (string)Request.RequestContext.RouteData.Values["id"]
However, it would be far easier to add a parameter to your method
public ActionResult StartBrVisit(string id)
I want to send a parameter to a view from an action that resolves and sends that value. The issue is that when the parameter "arrives" to the view, it arrives null giving me an error when I try to manage it.
The code I have in the action is (it creates the parameter and send it):
public ActionResult CreateAccount(Account model)
{
try
{
if (ModelState.IsValid)
{
_repository = new Repository();
model.PublicadorId = GetPublicadorId();
model.CreatedDate = DateTime.Now;
model.ModifiedDate = DateTime.Now;
model.IsActive = true;
Int32 id = _repository.Store(model);
return RedirectToAction("SubirImagenes/" + id, "Account");
}
}catch{}
}
So, the action that manage the parameter sent is (note that I pass the parameter as a nullable to avoid errors, and the name of the parameter is the same as the name I use to call the RedirectToAction before):
[HttpPost]
[AuthorizeUser]
[ValidateAntiForgeryToken]
public ActionResult UploadImage(CompraVenta.Models.UploadFileModel fileModel, Int32? id)
{
string directory = #"C:\Folder\";
if (ModelState.IsValid)
{
if (fileModel != null && fileModel.File != null && fileModel.File.ContentLength > 0)
{
var fileName = Path.GetFileName(fileModel.File.FileName);
fileModel.File.SaveAs(Path.Combine(directory, fileName));
}
return RedirectToAction("Index");
}
return View();
}
[AuthorizeUser]
public ActionResult SubirImagenes()
{
return View();
}
Any help would be appreciated. The routing roules of my application is:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
You are using it wrong way, you have to pass parameter using this overload of RedirectToAction() which takes object of RouteValueDictionary as parameter.
Do like this:
return RedirectToAction("UploadImage", "Account", new {id = id});
UPDATE:
you cannot pass parameters the way told above if action is HttpPost, the workaround is to directly call action without using RedirectToAction like:
return UploadImage(null,id);
Call the method directly instead of using RedirectToAction like:
return UploadImage(null,id);
instead of
return RedirectToAction("UploadImage/" + id, "Account");
Note:- address in the browser would be of old method
You can add an anonymous object to the RedirectToAction for the action parameters:
return RedirectToAction("Index", "Home", new {id = id});
Finally I've found the solution. In the "get" action "SubirImagenes" I get the parameter and then, with a strong typed model, using a hidden field, I pass the parameter in the "post" action receiving it inside the model I pass as a parameter in that post action.
I want to have links http://localhost:2409/Account/Confirmation/16 and that link http://localhost:2409/Account/Confirmation/ (without parametr). But with this action methods, it isn't working. Why?
public ActionResult Confirmation(int id, string hash)
{
Some code..
return View();
}
second, I just want to return View, if parametr is empty.
public ActionResult Confirmation()
{
return View();
}
Error (translated):
The current request for action on a controller Confirmation
AccountController is ambiguous between the following methods of
action: System.Web.Mvc.ActionResult Confirmation (Int32,
System.String) for type TC.Controllers.AccountController
System.Web.Mvc.ActionResult Confirmation () for type
TC.Controllers.AccountController
You cannot have multiple actions with the same name using the same HTTP verb (in your case GET.) You can name your actions differently but this means the link will change or you can use different VERB but this can also leads to other problems like you cannot just enter the link in your browser.
What you should do is to change your id to be optional with int? and merge your two actions into one:
public ActionResult Confirmation(int? id, string hash)
{
if(id.HasValue)
{
//Some code.. using id.Value
return View();
}
//There was no Id given
return View();
}
You may also need to allow in your route that the id is optional. If you are using the default routes this should be the default setting:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
There is no need to make 2-methods for it. Your HTTP request get confused that which ActionMethod should be called on both cases;
http://localhost:2409/Account/Confirmation/16
http://localhost:2409/Account/Confirmation/
Instead of all this, just create a single method. Make its parameter optional or assign some default value to the parameters. Here are 2-examples to understand it.
// 1. Default value to paramter
public ActionResult Confirmation(int id = 0, string hash = null)
{
//Some code..
return View();
}
// 2. Make id optional
public ActionResult Confirmation(int? id, string hash)
{
//Some code..
return View();
}
You can adopt any one approach from them.
Is it possible to pass data from one controller to another? When my second controller is called the int id is showing the WRONG value:
I have one controller:
public ActionResult Index(int id)
{
return RedirectToAction("New", "NewProducts", id);
}
NewProductsController:
public string New(int id)// <--------id never has correct number when called
{
return "value: " + id;
}
You need to use either a RouteValueDictionary or an anonymous type with an id property for the route values otherwise it will use the properties on the Int32 object id to fill the route values dictionary.
public ActionResult Index(int id)
{
return RedirectToAction("New", "NewProducts", new { id = id } );
}
Hope it will work
public ActionResult Index(int id)
{
return RedirectToAction("New?id=" + id, "NewProducts");
}