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"
}
Related
This is my public method(APIUtility)
public static string GetRequestData(string key, string defaultVal)
{
if (HttpContext.Current != null && HttpContext.Current.Request != null)
{
return HttpContext.Current.Request[key] == null || HttpContext.Current.Request[key].Trim() == "" ? defaultVal : HttpContext.Current.Request[key].Trim();
}
else
{
return defaultVal;
}
}
Have the html used javascript location.href(aa.json?key=value&key1=value1....) go to url my class funtion
In the Function aa used string getUrlValue = APIUtility.GetRequestData(key name) get Querystring.
The user uses the phone browser (OppoBrowser or safari..) to jump to the server function through my html page
Unable to get querystring is empty, but if using a computer is normal.
Hope you can understand what I want to express.
Try System.Web.HttpContext.Current.Request.QueryString
public static string GetRequestData( string key, string defaultVal ) {
try {
var ctx = System.Web.HttpContext.Current;
var value = ctx.Request.QueryString[key];
return string.IsNullOrEmpty(value) ? defaultVal : value;
} catch {
return defaultVal;
}
}
Learn more
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");
}
}
How can i identify which condition failed in a if statement with multiple OR conditions.example as following.
if ((null == emailNotificationData || string.IsNullOrEmpty(emailNotificationData.Sender))
|| null == emailNotificationData.ToRecipients)
{
LogProvider.Log(typeof(Notification), LogLevel.Error, "Error sending the email notification 'Here i want to log failed argument'");
return;
}
You can't, without rechecking each condition. I'd just write that as:
if (emailNotificationData == null)
{
// This is a helper method calling LogProvider.Log(...)
LogEmailNotificationError("No email notification data");
return;
}
if (string.IsNullOrEmpty(emailNotificationData.Sender))
{
LogEmailNotificationError("No sender");
return;
}
if (emailNotificationData.ToRecipients == null)
{
LogEmailNotificationError("No recipients");
return;
}
You could extract this into a ValidateAndLog extension method on your notification data type though - making it an extension method means you can handle it being null, too:
// ValidateAndLog returns true if everything is okay, false otherwise.
if (!emailNotificationData.ValidateAndLog())
{
return;
}
That way it doesn't need to clutter up other code.
Note that there's almost never any benefit in C# to writing:
if (null == x)
... unless you're actually comparing Boolean values, the "normal" reason for preferring the constant-first comparison (catching a typo of = for ==) doesn't apply, as if (x = null) wouldn't compile anyway.
Either use multiple ifs or meaningful bool variables:
bool noEmailData = emailNotificationData == null;
bool noEmailSender = string.IsNullOrEmpty(emailNotificationData.Sender);
if(noEmailData || noEmailSender)
{
string msg = string.Format("Error sending the email notification: {0} {1}."
, noEmailData ? "No email-data available" : ""
, noEmailSender ? "No email-sender available" : "");
LogProvider.Log(typeof(Notification), LogLevel.Error, msg);
}
That increases readability in general.
You can create a validation rule to check the emailNotificationData.
public class Rule<T>
{
public Func<T, bool> Test { get; set; }
public string Message { get; set; }
}
Then you create a class where you define the rules for your emailNotificationData.
public class EmailNotificationValidationRules
{
public static IEnumerable<Rule<EmailNotificationData>> Rules
{
get
{
return new List<Rule<EmailNotificationData>>
{
new Rule<EmailNotificationData> { Test = data => data != null, Message = "No email notifacation data" },
new Rule<EmailNotificationData> { Test = data => !string.IsNullOrEmpty(data.Sender), Message = "No sender" },
new Rule<EmailNotificationData> { Test = data => data.ToRecipients != null, Message = "No recipients" }
};
}
}
}
Now you can check the your object with this code
bool isValid = EmailNotificationValidationRules.Rules.All(rule => rule.Test(emailNotificationData));
if (isValid == false)
{
var failedRules = EmailNotificationValidationRules.Rules.Where(rule => rule.Test(emailNotificationData) == false);
var text2Log = failedRules.Aggregate(new StringBuilder(), (builder, rule) => builder.AppendLine(rule.Message), builder => builder.ToString());
}
The field text2log contains only the messages of the failed rules.
I have a list of objects. An object has the following properties:
public string mCardColor { get; set; }
public string mCardType { get; set; }
public string mCardRarity { get; set; }
In my view I have the possibility to filter directly the list obtained via a search engine using dropdownlists.
I then pass the values of the filters to the controller method and check if the request is an actual Ajax request like this:
public ActionResult DisplayCardsResults(string _rarity = "", string _type = "", string _color = "")
{
ViewBag._rarity = _rarity;
ViewBag._color = _color;
ViewBag._type = _type;
if (Request.IsAjaxRequest())
{
mListCardColors = null;
mListCardType = null;
mListCardRarity = null;
if (_rarity != "All")
{
mListCardRarity = mListCards.Where(_item => _item.mMasterCard.mCardRarity == _rarity).ToList();
}
if (_type != "All")
{
mListCardType =
mListCards.Where(_item => _item.mMasterCard.mCardType.ToLower().Contains(_type.ToLower())).ToList();
}
if (_color != "All")
{
mListCardColors = mListCards.Where(_item => _item.mMasterCard.mCardColor == _color).ToList();
}
if (mListCardType == null && mListCardColors == null && mListCardRarity == null)
{
return PartialView("_ResultsTable", mListCards.ToPagedList(pageNumber, ValueDomain.PAGE_SIZE));
}
mListCardsToShow = new List<CardDisplay>();
if (mListCardType != null)
{
mListCardsToShow.AddRange(mListCardType);
}
if (mListCardRarity != null)
{
mListCardsToShow.AddRange(mListCardRarity);
}
if(mListCardColors != null)
{
mListCardsToShow.AddRange(mListCardColors);
}
return PartialView("_ResultsTable", mListCardsToShow.ToPagedList(pageNumber, ValueDomain.PAGE_SIZE));
}
if (mListCardsToShow.Count > 0)
{
mListCardsToShow = SortListOrder(_sortOrder, mListCardsToShow);
return View(mListCardsToShow.ToPagedList(pageNumber, ValueDomain.PAGE_SIZE));
}
if (mListCards.Count > 0)
{
mListCards = SortListOrder(_sortOrder, mListCards);
}
return View(mListCards.ToPagedList(pageNumber, ValueDomain.PAGE_SIZE));
}
You have 2 list: the mListCards is the list of cards obtained from the search engine. This does not need to change. The mListCardsToShow is used only if the request is an Ajax request.
I want to retain only the values wanted based on the filters passed to the controller method. The principle is the following: if the three dropdownlist are on all, show all cards. But if there's a value in any or all the dropdownlist, the actual list needs to be filtered.
Is there an efficient way to filter the list based on the three param using Linq other than to write 9 differents scenarios?
If you don't have a strong reason not to, it probably makes sense to filtering on the three fields simultaneously:
var filteredCards =
from card in mListCards
where _color == "ALL" || card.mCardColor == _color
where _type == "ALL" || card.mCardType == _type
where _rarity == "ALL" || card.mCardRarity == _rarity
select card;
I am trying to set an arbitrary path in a JSON structure and I am having difficulty figuring out how to do a simple set value...
What I would like is some method like, SetValue(path,value) which operates like SelectToken, but creates the path if it does not exist and sets the value.
public void SetPreference(string username, string path, string value)
{
var prefs = GetPreferences(username);
var jprefs = JObject.Parse(prefs ?? #"{}");
var token = jprefs.SelectToken(path);
if (token != null)
{
// how to set the value of the path?
}
else
// how to add the path and value, example {"global.defaults.sort": { "true" }}
}
what I mean by global.defaults.sort path is actually { global: { defaults: { sort: { true } } } }
public string SetPreference(string username, string path, string value)
{
if (!value.StartsWith("[") && !value.StartsWith("{"))
value = string.Format("\"{0}\"", value);
var val = JObject.Parse(string.Format("{{\"x\":{0}}}", value)).SelectToken("x");
var prefs = GetPreferences(username);
var jprefs = JObject.Parse(prefs ?? #"{}");
var token = jprefs.SelectToken(path) as JValue;
if (token == null)
{
dynamic jpart = jprefs;
foreach (var part in path.Split('.'))
{
if (jpart[part] == null)
jpart.Add(new JProperty(part, new JObject()));
jpart = jpart[part];
}
jpart.Replace(val);
}
else
token.Replace(val);
SetPreferences(username, jprefs.ToString());
return jprefs.SelectToken(path).ToString();
}