Pass a string value as parameter in Url.action - c#

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");
}
}

Related

RedirectToAction to multiple HttpPost Action

I created a button that directs to another page with 3 tabs.
These 3 subtabs has different input text and only using 1 Action [HttpGet].
These are my cases.
I want to save only first tab data, the 2 tabs value will be null
I want to save only second data, the 1st tab and 3rd tab will be null
I want to save all the text input that I've typed under 1st tab, 2nd tab, and 3rd tab.
Here is my code:
[HttpGet]
public ActionResult Create_Data(int productId)
{
var model = BigViewModel();
///rest of code
return View(model)
}
[HttpPost]
public ActionResult Create_Data(BigViewModel model, int productId)
{
int experimentForOverloading = 0;
string experimentAgain = ""
// validates if first tab and doesn't have data inputted, will redirect to Create_SecondTab. Below is just for testing
if (model.FirstTabName == null && model.ThirdTabDirectory == null)
{
// this is where I want to go to route the new Action. But I don't know what to do..
return RedirectToAction("CreateData", new
{
model = BigViewModel,
Id = productId,
experimentForOverloading
}
}
else if (model.SecondTabSalary == null && model.ThirdTabDirectory == null)
{
return RedirectToAction("CreateData", new
{
model = BigViewModel,
Id = productid
experimentAgain
}
}
else
{
return RandomView(); //Testing purposes
}
}
// This is the second case, save only when first tab is empty
[HttpPost]
public ActionResult CreateData(BigViewModel, int bigId, int experimentForOverloading)
{
if(ModelState.IsValid)
{
//.. code here
_context.SaveChanges()
}
else
{
return RandomView(); //Testing purpose
}
}
// This is the first case, save only when second and third tab is empty
[HttpPost]
public ActionResult CreateData(BigViewModel, int bigId, string experimentAgain)
{
if(ModelState.IsValid)
{
//.. code here
_context.SaveChanges()
}
else
{
return RandomView(); //Testing purpose
}
}

Object not passed into method from JSON body

I'm attempting to run a method I've created in an MVC API which requires an object to be passed into it via the body in JSON format. As far as I'm aware there's no errors with the method or the object, but the JSON that I'm sending is not actually passed into the method and the object parameter remains null.
This is the method:
// Consignment Search
[HttpPost]
[ResponseType(typeof(Legacy.JobTracking))]
[Route("api/search/")]
public IHttpActionResult SearchConsignment(ConsignmentSearch search)
{
// Get the ID
var UserId = 0;
using (_PortalDb)
{
var User = _PortalDb.PortalUsers.FirstOrDefault(u => u.ServerUser == search.User);
if (User != null) UserId = User.UserId;
}
List<Legacy.JobTracking> Consignments;
if (!ModelState.IsValid) return BadRequest("Invalid Search");
if (search.JobNo == null && search.CustRef == null && search.ConRef == null && search.DateFrom == null && search.DateTo == null) return BadRequest("No search filters");
if (search.JobNo != null)
{
// Run Job number search and continue
Consignments = Legacy.Exporter.GetJobByNo(search.JobNo, search.User, search.Account, UserId);
}
else if (search.ConRef != null)
{
// Run Con Ref Search and continue
Consignments = Legacy.Exporter.GetJobByCon(search.ConRef, search.User, search.Account, UserId);
}
else if (search.CustRef != null)
{
// Run Customer Ref Search and continue
Consignments = Legacy.Exporter.GetJobByRef(search.CustRef, search.User, search.Account, UserId);
}
else if (search.DateFrom != null && search.DateTo != null)
{
// Run Date Range Search and continue
Consignments = Legacy.Exporter.GetJobsInDateRange(search.DateTo, search.DateFrom, search.User, search.Account, UserId);
}
else
{
return BadRequest("Invalid Date Search");
}
return Ok(Consignments);
}
The class:
public class ConsignmentSearch
{
public string JobNo;
public string CustRef;
public string ConRef;
public string DateFrom;
public string DateTo;
public string User;
public string Account;
}
And the JSON in the body:
["consignmentSearch": {
"dateFrom": "20150101",
"dateTo": 20160101,
"user": "LianeS",
"account": "PORTAL"
}]
Text that you pass in body of your request is not valid JSON (and of course does not represent your model also). Valid JSON for your case will be something like:
{
"dateFrom": "20150101",
"dateTo": 20160101,
"user": "LianeS",
"account": "PORTAL"
}

Complex Remote validation based on 2 properties

I'm trying to use custom remote validation to validate 2 properties based on one another with no success.
Action
Edit only, no insert
Properties
Both properties are free text (no dropdownlist)
FolderName
FileName
Validation conditions
FileName can be empty even if folder name is present
FileName can only be filled in if folder name is present
Filename is unique for each unique folder
When edit page is loaded and in case if there are already data present then no check should be done unless the user modifies theses values.
Code
1- Json function in the controller
public JsonResult IsFileValid(string folderName, string fileName)
{
if (!folderName.IsNullOrEmpty() && fileName.IsNullOrEmpty())
{
// FileName can be empty even if Folder name is present
return Json(true, JsonRequestBehavior.AllowGet);
}
if (folderName.IsNullOrEmpty() && fileName.IsNullOrEmpty())
{
//FileName can be empty even if Folder name is present
return Json(true, JsonRequestBehavior.AllowGet);
}
if (folderName.IsNullOrEmpty() && !fileName.IsNullOrEmpty())
{
//FileName can only be filled in if Folder name is present
return Json(false, JsonRequestBehavior.AllowGet);
}
var Folder =
Uow.Folders.GetAll()
.FirstOrDefault(x => x.Name.ToLower().Trim() == folderName.Trim().ToLower());
if (Folder != null)
{
// the Folder already exists, FileName name should be unique.
return Uow.Files.GetAll()
.Any(
x =>
x.FolderId == Folder.Id &&
x.fileName.Trim().ToLower() == fileName.Trim().ToLower()) ? Json(false, JsonRequestBehavior.AllowGet) : Json(false, JsonRequestBehavior.AllowGet);
}
// Folder name is new, in this case we can add new Folder and basked name
return Json(true, JsonRequestBehavior.AllowGet);
}
2- Create Custome remote attribute class
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
// When using remote attribute, we specify the controller, action and the error message. The aim of the following is to retrieve the controller, action and error message
//using reflection.
// first get the controller
Type controller =
Assembly.GetExecutingAssembly()
.GetTypes()
.FirstOrDefault(
type =>
type.Name.ToLower() ==
string.Format("{0}Controller", this.RouteData["controller"].ToString()).ToLower());
if (controller != null)
{
// Get the method in the controller with
MethodInfo action =
controller.GetMethods()
.FirstOrDefault(method => method.Name.ToLower() == this.RouteData["action"].ToString().ToLower());
if (action != null)
{
// create instance of the controller
object instance = Activator.CreateInstance(controller);
//invoke the action method of the controller, and pass the value which is the parameter of the action
object response = action.Invoke(instance, new object[] {value});
// because the remote validation action returns JsonResult
var returnType = response as JsonResult;
if (returnType != null)
{
object jsonData = returnType.Data;
//because the jsonDate is bool
if (jsonData is bool)
{
// return success or the error message
return (bool) jsonData ? ValidationResult.Success : new ValidationResult(this.ErrorMessage);
}
}
}
}
return new ValidationResult(ErrorMessage);
}
3- My viewModel class
public class FileInViewModel
{
public string FolderName { get; set; }
[RemoteValidation("IsFileValid","Home",ErrorMessage="Please select different file name")]
public string FileName { get; set; }
// .....
}
What am i missing to make it work? If also possible to have different
error message for each error?
How can i ignore the validation for data already present when the edit page is loaded?
See the code below:
[Remote("CheckExist", "securitylevels", AdditionalFields = "Id", ErrorMessage = "the number is Zero!")]
public int Number { get; set; }

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