Getting Null value in parameter of Action method - asp.net

I am getting null value in the parameter of my action method.
this is my action method
[HttpGet]
public ActionResult ProjectData(int? formId)
{
if (formId == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
return View();
}
}
and this is my view of actionlink
#foreach (var projects in Model)
{
int formId = Convert.ToInt32(#projects.FormId);
<tr>
<td>#projects.Serial</td>
<td>#projects.ProjectName</td>
#*<td>#projects.SurveyName</td>*#
#*<td>#Html.ActionLink(#projects.SurveyName, "ActionName", new { id = #projects.FormId })</td>*#
<td>#Html.ActionLink(#projects.SurveyName, "ProjectData" , "Home", new {id = formId}, null)</td>
<td>#projects.TotalSubmission</td>
<td>#projects.LastSubmissionTime</td>
<td>#projects.SubmissionToday</td>
</tr>
}
I am using list of user defined type model:
#model IEnumerable<MVC.ProjectInformation>
When I click on actionlink under the loop it should send id to the controller actionmethod but I get the parameter null always.
Specific Actionlink:
#Html.ActionLink(#projects.SurveyName, "ProjectData" , "Home", new
{id = formId}, null)
I can see the id by debugging on the View but on controller actionmethod I cannot get that id value.

The ActionLink's routeValues object properties need to match the parameters of the controller action.
Currently it is
new { id = formId }
which would not match the parameter of the ProjectData
public ActionResult ProjectData(int? formId)
Update to match
#Html.ActionLink(#projects.SurveyName, "ProjectData" , "Home", new {formId = formId}, null)

Related

ERROR: Unable to cast object of type 'System.Collections.Generic.List' to type 'X.PagedList.IPagedList'

I use List instead of IEnumerable model
My Controller
public ActionResult Index(int? page)
{
var pageNumber = page ?? 1;
var itemCount = employees.ToPagedList(pageNumber, 5);
return View(employees.ToList());
}
My View
#Html.Partial("EmployeeList", Model.AsEnumerable())
#Html.PagedListPager((IPagedList)Model.AsEnumerable(), page => Url.Action("Index", new { page }))
IEnumerable<EmployeeViewModel> can't be directly cast to IPagedList with (IPagedList)Model.AsEnumerable() since they're different instances. You should return a PagedList instance using ToPagedList method as View argument (assumed employees is an List<EmployeeViewModel> or array of viewmodels):
public ActionResult Index(int? page)
{
var pageNumber = page ?? 1;
return View(employees.ToPagedList(pageNumber, 5));
}
And use the bound model inside PagedListPager like this:
#model PagedList.IPagedList<EmployeeViewModel>
#using PagedList.Mvc;
#Html.PagedListPager(Model, page => Url.Action("Index", new { page }))
And pass the IPagedList through Model in HtmlHelper.Partial:
#Html.Partial("EmployeeList", Model)
Similar issue:
How to load first x items and give user the option to load more in MVC.NET
**Controller Action **
public ActionResult Index(int? page)
{
var pageNumber = page ?? 1;
return View(employees.ToList().ToPagedList(pageNumber, 5));
}
View page
#using PagedList
#using PagedList.Mvc
#model IEnumerable <Employee>
#Html.Partial("EmployeeList", Model)
#Html.PagedListPager((IPagedList)Model, page => Url.Action("Index", new { page }))

asp.net passing an id between views in different controllers

So I have two models with a one to many relationship. Callout, and shift offer. Callout can have many shift offers.
I want to pass my callout_id to the shift-offer controller. I've done this by modifying the Index() method as follows:
public async Task<ActionResult> Index(long? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
Debug.WriteLine("Callout ID cannot be null");
}
var shift_Offers = db.Shift_Offers.Where(s => s.callout_id_fk == id);
return View(await shift_Offers.ToListAsync());
}
I've also modified one of my HTML action links to call a different page:
#Html.ActionLink("View Callout",
"Index",
"ShiftOffer",
new { area = ""},
new { id=item.callout_id_pk }) |
But here's the kicker, when I try to call Index(long id), it's throwing that bad request error. Why isn't my ID being passed like it is with the default scaffolded links?
Try below
#Html.ActionLink("View Callout",
"Index",
"ShiftOffer",
new { id=item.callout_id_pk },
new { area = ""})

How to add ViewBag property as html class attribute properly?

I have this line:
#Html.ActionLink("Discounts", "ListDiscounts", "Product", null, new { #class = ViewBag.Discount })
The ListDiscounts is:
public ViewResult ListDiscounts(int nrProducts = 5)
{
ViewBag.Discount = "selected";
ProductsListViewModel model = new ProductsListViewModel
{
Products = repository.Products
.Where(p => p.Discount != false)
.Take(nrProducts)
};
return View(model);
}
The View that renders the Menu (where my separate Discounts will also be)
#model IEnumerable<string>
#Html.ActionLink("Home", "List", "Product")
#foreach (var link in Model) {
#Html.RouteLink(link, new
{
controller = "Product",
action = "List",
category = link,
page = 1
},
new
{
#class = link == ViewBag.SelectedCategory ? "selected" : null,
})
}
ListDiscounts.cshtml
#model Sportsstore.WebUI.Models.ProductsListViewModel
#{
ViewBag.Title = "ListDiscounts";
}
<h2>Discounts available</h2>
#foreach (var p in Model.Products)
{
Html.RenderPartial("ProductSummary", p);
}
I'm trying to add the selected class to my 'a' element in a view but this doesn't work. The ViewBag property remains empty when I click on that Discounts link.
The View associated with ListDiscounts is not the one where that ActionLink line is from (they're separate with the one that has it being a Partial View) but from what I understand ViewBag features have some sort of a global state so this should work?
Any ideas on what is wrong here?
EDIT: Using MVC 4
I believe there is something you are not showing us that is the problem. Perhaps you only populated the ViewBag in your post method but not your get method. I created a test application that mocks your app very closely and it works fine.
Controller
namespace MvcApplication1.Controllers
{
public class HomeController : Controller
{
public ViewResult Index()
{
ViewBag.Discount = "selected";
return View();
}
[HttpPost]
public ViewResult Index(int nrProducts = 5)
{
var model = new ProductsListViewModel{Products = "stuff"};
ViewBag.Discount = "selected";
return View(model);
}
}
}
View
#model MvcApplication1.Models.ProductsListViewModel
#Html.ActionLink("Discounts", "Index", "Home", null, new { #class = ViewBag.Discount })
#{ Html.RenderPartial("ViewPage1");}
#using (Html.BeginForm())
{
<input type="submit" />
}
Partial
#Html.ActionLink("Discounts", "Index", "Home", null, new { #class = ViewBag.Discount })
When I view the source both links have the class I expected. Also after I click on the link they have the class expected. Thus I believe you are not populating the view bag either on the Get and/or the Post controller method
If you're sure that you have value in the viewbag property instead of
#class = ViewBag.Discount try
#class = #ViewBag.Discount and see if it works
You just try the below code. Change the Viewbag name and try.
#Html.ActionLink("Discounts", "ListDiscounts", "Product", null, new { #class = ViewBag.CssDiscount })
public ViewResult ListDiscounts(int nrProducts = 5)
{
ViewBag.CssDiscount = "selected";
ProductsListViewModel model = new ProductsListViewModel
{
Products = repository.Products
.Where(p => p.Discount != false)
.Take(nrProducts)
};
return View(model);
}

Why Is The Selected Value Different Between Using Route ID and Action Parameter in SelectList

I have a SelectList in my action method. The selected value for SelectList is coming from the action method parameter. The action and view are simple like below:
// Recipe Action
public ActionResult Recipe(int? recipeId)
{
ViewBag.RecipeID = new SelectList(_recipsRecipes, "RecipeID", "RecipeName", recipeId);
return View(new Recipe());
}
//Recipe View
#model RecipeDemo.Models.Recipe
#Html.DropDownList("RecipeID", (SelectList)ViewBag.RecipeID, string.Empty)
I'm using ActionLink below to call the Recipe action.
#Html.ActionLink("Recipe", "Recipe", "Home", new { recipeId = 2 }, null)
It works like I expect, the DropDownList is showing the selected value as the No. 2 (recipeId = 2) item.
Problem
When I change the Recipe action parameter by using route id, like below:
//Recipe View
public ActionResult Recipe(int? id)
{
ViewBag.RecipeID = new SelectList(_recipsRecipes, "RecipeID", "RecipeName", id);
return View(new Recipe());
}
//Recipe View (Same View as above)
#model RecipeDemo.Models.Recipe
#Html.DropDownList("RecipeID", (SelectList)ViewBag.RecipeID, string.Empty)
And I'm using ActionLink below to call the Recipe action.
#Html.ActionLink("Recipe", "Recipe", "Home", new { id = 2 }, null)
The DropDownList is NOT showing the selected value, (id = 2) item. The selection is instead empty.
But I have the correct id value in the SelectList. see below:
Why is this, does anyone know the explanation?
Update:
The model is below:
public class Recipe
{
public int RecipeID { get; set; }
public string RecipeName { get; set; }
}
Well that was certainly interesting. After first confirming the issue with the code you provided, I experimented around and believe I have the root cause. Basically, you are using the same variable name way to often and the model binder appears to be getting confused. You have RecipeId in your route, RecipeId in your View Model and RecipeId as the name of your view bag variable. By altering my variable names, the SelectList works as expected.
The primary issue is naming your SelectList RecipeId which matches a property in your model. When you send the new Recipe(), the model binder is attempting to use that value. In your first example, since you have RecipeId defined in the URL, it is getting it from there. In the second example, there is no RecipeId to pull from the URL and it is null in the model.
Controller
namespace MvcApplication1.Controllers
{
public class HomeController : Controller
{
private List<Recipe> Recipes;
public HomeController()
{
Recipes = new List<Recipe>
{
new Recipe {RecipeId = 1, RecipeName = "Test - 1"},
new Recipe {RecipeId = 2, RecipeName = "Test - 2"},
new Recipe {RecipeId = 3, RecipeName = "Test - 3"},
};
}
public ActionResult Index(int? id)
{
ViewBag.MyList = new SelectList(Recipes, "RecipeID", "RecipeName", id);
return View(new Recipe());
}
}
}
Index View
#model MvcApplication1.Models.Recipe
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
#Html.DropDownList("MyRecipeId", (SelectList)ViewBag.MyList)
Basically, vary your parameter names a little bit more to help prevent the model binder from getting confused and/or pulling information from the wrong place.
You can verify this in your second example by sending this in your return statement:
Return View(New Recipe{RecipeId = 3});
The option value with 3 will be selected regardless of what the actual Id sent was.
EDIT
An even better option would be to do what I said to do as an example above. By changing your Action to this:
public ActionResult Index(int? id)
{
ViewBag.MyList = new SelectList(Recipes, "RecipeID", "RecipeName");
return View(new Recipe(RecipeId = id));
}
You can leave your view unchanged. Now, the SelectList will pull from the model that you are sending.

ASP .net Dropdown list not saving the selected value to database

In the following code i want to save the value selected by user from drop downlist into database. but whatever value is selected by user, first value of dropdown lsit is saved to database
View
<% =Html.DropDownList("lstUsertype", (SelectList)ViewData["UserTypeID"])%>
Controller
public ActionResult CreateUser()
{
UmUser _UmUser = new UmUser();
UMRepository _UMRepository = new UMRepository();
EvoLetDataContext db = new EvoLetDataContext();
ViewData["UserTypeID"] = new SelectList(_UMRepository.FillUserTypes(), "UserTypeID", "UserType",2);
return View(_UmUser);
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult CreateUser(UmUser _umUser)
{
//try
//{
if (ModelState.IsValid)
{
//try
//{
UserRepository _UserRepository = new UserRepository();
_UserRepository.Add(_umUser);
_UserRepository.Save();
return RedirectToAction("Details", new { id = _umUser.UserID });
/*}
catch
{
ModelState.AddModelErrors(_umUser.GetRuleViolations());
}*/
}
return View();
//}
/*catch
{
return View();
}*/
}
This is how I'm doing it successfully:
<%= Html.DropDownListFor(model => model.Value, new SelectList(Values, "Key", "Value", Model.Value), "[select]")%>
Where Values is of type IDictionary and Value is of type Guid
Hope this helps!

Resources