Set MVC3 parameters to default if empty or null in controller - c#

I am struggling to default CId and SId to 1 if the parameters are empty,
public ViewResult Index(int? CId,int?SId,string name,int? p)
{
if (CId == 0 || SId == 0)
{
CId = 1;
SId = 1;
}
Then I will use the values for a normal query. Thanks for any help

Cid and Sid is Nullable, so you can use HasValue property to check if the variable has value or not (null)
public ViewResult Index(int? CId,int?SId,string name,int? p)
{
if (!CId.HasValue || !SId.HasValue)
{
CId = 1;
SId = 1;
}
}

Just curious but have you tried:
public ViewResult Index(string name,int? p,int? CId = 1,int? SId = 1)
{
}
You have to rearrange them, because the default valued parameters have to come last. Also, being that they're nullable, I'm not actually sure if this will work.

Related

Accept a list (of unknown length) of query string parameters to MVC action

I am building a page which will have a query string sent to it containing any number of productId_{index} and productQuantity_{index}.
E.g:
http://www.website.com/action?productId_1=65&productQuantity_1=1&productId_2=34&productQuantity_2=1
So this URL would map a ProductId of 65 to a quantity of 1 and a ProductId of 34 to a quantity of 1.
I cannot change how this is sent to the page which I why I have not used a solution like this.
I would like to be able to somehow map the query in this format to a strongly typed list of objects.
This question is meant to be mainly asking about the MVC way to do this, as I already have a solution using the Request object, but being able to do this the MVC way would be preferable.
you need to format the query string to something simpler and easy to read like this: p=id-quantity, then you can use params,
e.g.: http://www.website.com/action?p=65-1&p34-4&p=32-23&p=....
public ActionResult Products(params string[] p)
{
foreach(var product in p)
{
var productId = product.Split('-')[0];
var quantity = product.Split('-')[1];
}
}
[Notice]
I don't recommend sending such parameters via url "GET", it is better and safer if you use "POST" form method.
As was suggested to me, I ended up using a custom model binder to give me a list of objects in my Action.
Custom Model Binder
public class ProductIdAndQuantityListModelBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var request = controllerContext.HttpContext.Request;
var products = new List<ProductIdAndQuantity>();
for (int i = 0; i < 25; i++)
{
string productIdKey = string.Format("productid_{0}", i);
string quantityKey = string.Format("productqty_{0}", i);
string productIdVal = request[productIdKey];
string quantityVal = request[quantityKey];
if (productIdVal == null || quantityVal == null)
break;
int productId = Convert.ToInt32(productIdVal);
int quantity = Convert.ToInt32(quantityVal);
var productIdAndQuantity = products.FirstOrDefault(x => productId == x.ProductId);
if (productIdAndQuantity != null)
{
productIdAndQuantity.Quantity += quantity;
}
else
{
products.Add(new ProductIdAndQuantity()
{
ProductId = productId,
Quantity = quantity
});
}
}
return products;
}
}
Global.asax.cs
protected void Application_Start()
{
ModelBinders.Binders.Add(typeof(ICollection<Models.Basket.ProductIdAndQuantity>), new ProductIdAndQuantityListModelBinder());
}
Action
public ActionResult Index(ICollection<ProductIdAndQuantity> products)
{
foreach (var product in products)
{
// Do stuff...
}
}
Thank you you all for your help! As you can see it's an unknown but not unlimited number of parameters it could take which is just down to how I'm using it I think.

Session sets the value successfully but gets null in MVC 5

I am developing an MVC 5 application and I have a specific Controller for Session variables in my application which has 6 sessions, and all are working fine. Now I wanted to use another session, so I have declared it in my Session controller as follows:
public int tempResult
{
get { return Convert.ToInt32(Session["tempResult"]); }
set { Session["tempResult"] = value; }
}
Now I have a Controller A which inherits from Session Controller and it is setting the session variable tempResult in method as:
[HttPPost]
public JsonResult COAcodelength(MST m)
{
var s = (from sets in db.ABCs where sets.name == "Name" && sets.pre.ToString() == m.house select sets.Id).Single().ToString();
tempResult = Convert.ToInt32(s);
}
Now Controller B which also inherits from Session Controller is calling a method of Controller A and in that method I am trying to access the session value of tempResult as:
[HttpPost]
public ActionResult New([Bind(Include = "Id,Name,House,Number")] MST tr)
{
tr.Name = r.Ccode(tr); // r is the instance of Controller A
db.MSTs.Add(tr);
db.SaveChanges();
return Json(tr);
}
And the Ccode method in Controller A is as:
public string Ccode (MST tr)
{
int q = tempResult;
tr.Name = q.ToString() + tr.House;
return tr.Name;
}
So, when Ccode method in Controller A tries to get the value of tempResult it returns null with Object reference error.
What could be the possible problem?
You cannot convert null to int 32, which meant that if your tempResult can be null, you should use it like this:
public int? tempResult
{
get { return Convert.ToInt32(Session["tempResult"]); }
set { Session["tempResult"] = value; }
}
Which will then allow the integer variable to accept null.
int? meaning the integer variable can be nullable.

Pass a string value as parameter in Url.action

I am developing a website using asp.net mvc 4 & EF6. I want to pass a string value as a parameter in a Url.action link. However, whenever I click on the link I get this error:
The argument types 'Edm.Int32' and 'Edm.String' are incompatible for this operation. Near WHERE predicate, line 1, column 76.
This is the code that creates it:
Controller
public ActionResult Edit(string EditId)
{
if (Session["username"] != null)
{
UserInfo uinfo = db.UserInfoes.Find(EditId);
return View(uinfo);
}
else
{
return RedirectToAction("HomeIndex");
}
}
View
<a class="btn btn-info"
href="#Url.Action("Edit", "Home", new { EditId = item.regno.ToString() })"><b>Edit</b></a>
How can I use a string value as a parameter?
public ActionResult Edit(string EditId)
{
if (Session["username"] != null)
{
int id;
//Check try to parse the string into an int if it fails it will return false if it was parsed it will return true
bool result = Int32.TryParse(EditId, out id);
if (result)
{
//I wouldn't use find unless you're 100% sure that record will always be there.
//This will return null if it cannot find your userinfo with that ID
UserInfo uinfo = db.UserInfoes.FirstOrDefault(x=>x.ID == id);
//Check for null userInfo
return View(uinfo);
}
else
{
return RedirectToAction("HomeIndex");
}
}

C# Enum - How to Compare Value

How can I compare the value of this enum
public enum AccountType
{
Retailer = 1,
Customer = 2,
Manager = 3,
Employee = 4
}
I am trying to compare the value of this enum in an MVC4 controller like so:
if (userProfile.AccountType.ToString() == "Retailer")
{
return RedirectToAction("Create", "Retailer");
}
return RedirectToAction("Index", "Home");
I also tried this
if (userProfile.AccountType.Equals(1))
{
return RedirectToAction("Create", "Retailer");
}
return RedirectToAction("Index", "Home");
In each case I get an Object reference not set to an instance of an object.
use this
if (userProfile.AccountType == AccountType.Retailer)
{
...
}
If you want to get int from your AccountType enum and compare it (don't know why) do this:
if((int)userProfile.AccountType == 1)
{
...
}
Objet reference not set to an instance of an object exception is because your userProfile is null and you are getting property of null. Check in debug why it's not set.
EDIT (thanks to #Rik and #KonradMorawski) :
Maybe you can do some check before:
if(userProfile!=null)
{
}
or
if(userProfile==null)
{
throw new ArgumentNullException(nameof(userProfile)); // or any other exception
}
You can use Enum.Parse like, if it is string
AccountType account = (AccountType)Enum.Parse(typeof(AccountType), "Retailer")
Comparision:
if (userProfile.AccountType == AccountType.Retailer)
{
//your code
}
In case to prevent the NullPointerException you could add the following condition before comparing the AccountType:
if(userProfile != null)
{
if (userProfile.AccountType == AccountType.Retailer)
{
//your code
}
}
or shorter version:
if (userProfile !=null && userProfile.AccountType == AccountType.Retailer)
{
//your code
}
You can use extension methods to do the same thing with less code.
public enum AccountType
{
Retailer = 1,
Customer = 2,
Manager = 3,
Employee = 4
}
static class AccountTypeMethods
{
public static bool IsRetailer(this AccountType ac)
{
return ac == AccountType.Retailer;
}
}
And to use:
if (userProfile.AccountType.isRetailer())
{
//your code
}
I would recommend to rename the AccountType to Account. It's not a name convention.
You should convert the string to an enumeration value before comparing.
Enum.TryParse("Retailer", out AccountType accountType);
Then
if (userProfile?.AccountType == accountType)
{
//your code
}

How to work with specific parameter of a Controller

The goal
Treat an offer as a category in controller.
The problem
I have a controller whose name is ProductsController. Inside it, I have an action called Category. When this method is requested, it responds with a view of products list that corresponds to the category passed as parameter. Follow the code:
[HttpGet]
public ActionResult Category(string categoryName = null)
{
if (Regex.Match(categoryName, #"\d+").Success)
{
int categoryId = Convert.ToInt32(Regex.Match(categoryName, #"\d+").Value);
string sluggedCategoryName = CommodityHelpers.UppercaseFirst(CommodityHelpers.GenerateSlug(Categories.GetDetails((sbyte)categoryId).Category_Name));
if (String.Format("{0}-{1}", categoryId, sluggedCategoryName) == categoryName)
{
ViewBag.Title = Categories.GetDetails((sbyte)categoryId).Category_Name;
ViewBag.CategoryProductsQuantity = Categories.GetDetails((sbyte)categoryId).Category_Products_Quantity;
ViewBag.CurrentCategory = sluggedCategoryName;
return View(Products.BuildListForHome(categoryId, null));
}
else
{
return View("404");
}
}
else
{
return View("404");
}
}
But I want to return other a specific view when "Offers" is passed as parameter.
How can I do this?
if (categoryName == "Offers")
return View("SomeView", Products.BuildListForHome(categoryId, null));
You can specify what view to return as a parameter like so:
return View("Offers", data);
Put an "if" "then" in the beginning of the method checking for Offers, and return your offers View if the conditions meet.

Categories

Resources