Search Select not returning NotFound method - c#

I wrote a simple select to find searched data in a database. Thing is, in my case when there is no item in the database, method is returning an empty json.
[Route("api/Atributes/{value}")]
public IHttpActionResult GetAtributeByValue(string value)
{
var atribute = ( from a in db.Atributes
join p in db.Cards on a.Atr_Nr equals p.Card_Nr
where a.Atr_Value == value
select new Employee
{
Name = p.Name,
Surname = p.Surname,
Number = a.Atr_Value
});
//this is statement id not working
if (atribute == null)
{
return NotFound();
}
return Ok(atribute);
}
Question is: Is this method of searching correct? If not how should I make it in another way?

Convert your result set to List and use its length property to check. LINQ has deferred execution. Fetch the actual result set with .ToList().
[Route("api/Atributes/{value}")]
public IHttpActionResult GetAtributeByValue(string value)
{
var atribute = ( from a in db.Atributes
join p in db.Cards on a.Atr_Nr equals p.Card_Nr
where a.Atr_Value == value
select new Employee
{
Name = p.Name,
Surname = p.Surname,
Number = a.Atr_Value
}).ToList();
//use count, if that does not work, length here
if (atribute.Count() == 0)
{
return NotFound();
}
return Ok(atribute);
}

Seem like that the method is trying to a list of Atribute. So you just return atribute directly
[Route("api/Atributes/{value}")]
public IHttpActionResult GetAtributeByValue(string value)
{
var atribute = ( from a in db.Atributes
join p in db.Cards on a.Atr_Nr equals p.Card_Nr
where a.Atr_Value == value
select new Employee
{
Name = p.Name,
Surname = p.Surname,
Number = a.Atr_Value
});
return Ok(atribute);
}
EDIT:
Why not 404 (Not Found) ?
The 404 status code should be reserved for situations, in which a resource is not found. In this case, your resource is a collection of Atribute. This collection exists but it's currently empty. It is very confused as an author of a client for your application if I got a 200 one day and a 404 the next day just because someone happened to remove a couple of Atributes. What am I supposed to do? Is my URL wrong? Did someone change the API and neglect to leave a redirection.

Related

C# .Net where condition

I have this code to select the city for each person whose Id matches from the list of cities:
public List<PersonelDto> MapPersonelDto(List<Personel> personels,List<City> cities)
{
var result = new List<PersonelDto>();
foreach (var item in personels)
{
var personel = new PersonelDto
{
Id = item.Id,
Maaş = item.Salary,
MedeniHal = item.MartialStatus,
Meslek = item.Job,
Soyisim = item.LastName,
Şehir = (from s in cities where s.Id == item.CityId select s.name).ToString()
};
result.Add(personel);
}
return result;
}
But City's value come out like this:
System.Linq.Enumerable+WhereSelectListIterator`2[Personnel_Registration.City,System.String]
How can I fix this?
The error is because there's nothing in the type system metadata to guarantee you won't have more than one city match, and so the result of the expression is a potential collection of 0, 1, or more cities. What you see is the result of calling .ToString() on that collection.
To fix it, you can do this:
public IEnumerable<PersonelDto> MapPersonelDto(IEnumerable<Personel> personels, IEnumerable<City> cities)
{
return personels.Select( p => {
new PersonelDto() {
Id = item.Id,
Maaş = item.Salary,
MedeniHal = item.MartialStatus,
Meslek = item.Job,
Soyisim = item.LastName,
Şehir = string.Join(",", cities.Where(c => c.Id == p.CityId).Select(c=> c.name));
}
});
}
Or, if you're confident you only want one city, you could do this:
public IEnumerable<PersonelDto> MapPersonelDto(IEnumerable<Personel> personels, IEnumerable<City> cities)
{
return personels.Select( p => {
new PersonelDto() {
Id = item.Id,
Maaş = item.Salary,
MedeniHal = item.MartialStatus,
Meslek = item.Job,
Soyisim = item.LastName,
Şehir = cities.FirstOrDefault(c => c.Id == p.CityId)?.name;
}
});
}
Note the complete lack of Lists. You really ought to get out of the habit of using List<T> everywhere, and instead let things remain as an IEnumerable<T> as much as possible. This can make your code faster and MUCH more efficient with RAM use.
Another benefit is it makes your code more flexible. For example, you can still pass the existing Lists to this new method. And if for some reason you need the result to be a List<> for the next method call (hint: you probably don't really need this at all) you can always add a .ToList() after calling the method. But, again, don't do that unless you really have to!
from s in cities where s.Id == item.CityId select s.name
return an IEnumerable - there might be more than one city
do instead
Şehir = (from s in cities where s.Id == item.CityId select s.name).FirstOrDefault().ToString()
which selects the first element
Note that this assumes that there is always a matching city. If not then you should supply a default value
Şehir = (from s in cities where s.Id == item.CityId select s.name).FirstOrDefault("unknow city").ToString()

Linq check value in SQL table always is false

I tried to check if the cost or benefit value exists for the selected Id, then I will get the cost or benefit value from the table.
In the code below my if statement doesn't work and seems to always be false but the return benefit value works fine. Where is the problem?
public string GetCostBenefitAmount(int id)
{
if (db.CostBenefits.Any(c => c.ID == id && !c.Cost.Equals(0)))
{
return db.CostBenefits.Select(c => c.Cost).First().ToString();
}
return db.CostBenefits.Where(c=> c.ID == id).Select(c => c.Benefit).First().ToString();
}
This is my code in windows form for fill txtAmount textBox by GetCostBenefitAmount(int id) method:
var stockIdList = db.CostBenefitRepository.GetAllID();
int id = stockIdList[listBox.SelectedIndex];
CostBenefit costBenefit = db.GenericCostBenefitRepository.GetById(id);
txtStockName.Text = listBox.SelectedItem.ToString();
txtSoldAmount.Text = costBenefit.SoldAmount.ToString();
ComboCostBenefit.SelectedItem = db.CostBenefitRepository.GetCostBenefitOperation(id);
txtAmount.Text = db.CostBenefitRepository.GetCostBenefitAmount(id);
The Object.Equals method determines whether two object instances are equal. Try if (db.CostBenefits.Any(c => c.ID == id && c.Cost != 0)). For more info on the Object.Equals function see this post.
Edit:
As #Gert Arnold commented, the issue was in the return db.CostBenefits.Select(c => c.Cost).First().ToString(); where there was no filtering done before returning.
I think equals is only when you are using in a join. So just use
c.Cost != 0
instead.

How to update a table row, given the RowID and the Value to update. MVC C# Linq

Here is my code. PayPal sends the ActionResult the RowID which is item_number and the transaction id which is pp_txn_id. I simple want to reference the row in my transaction table, tblPayPalTransactions, and update it with the pp_txn_id which I see is sent back to me after purchase in PayPal. Then photo links are sent to DownloadPicture.cshtml view.
I simply can't figure the syntax out to update the transaction table. Everything else I can do. Stuck here trying to finish a project.
//ROW IN PHOTOS IS item_number, PAYPAL PAID TRANSACTION IS pp_txn_id
public ActionResult thankyou(string item_number, string pp_txn_id)
{
var photo = db.PayPalTransactions.Where(x => x.RowID == Convert.ToInt32(item_number));
photo.pp_txn_id = pp_txn_id;
db.SubmitChanges();
var thisPaidPhoto = (from p in db.Photos
where p.PhotoId == Convert.ToInt32(item_number)
select p).FirstOrDefault();
return View(thisPaidPhoto);
}
Your current code will have compilation errors because the Where method returns a collection. So basically photo variable will be a collection type and it will not have a pp_txn_id property.
Assuming rowid is a unique identifier of the record in that table, you need to get a single record.
You may use FirstOrDefault method.
var rowId=Convert.ToInt32(item_number)
var photo = db.PayPalTransactions.FirstOrDefault(x => x.RowID ==rowId);
if(photo!=null)
{
// update now
photo.pp_txn_id = pp_txn_id;
db.SubmitChanges();
}
else
{
// item does not exist in table. Handle as needed.
}
Also keep in mind that, the Convert.ToInt32 method will throw an exception if the input is not a valid numeric value. I would use Int32.TryParse to be safe. but If you are sure the values are always going to be numeric type, i would recommend you to use a numeric type as param (int or long).
public ActionResult thankyou(string item_number, string pp_txn_id)
{
var photo = db.PayPalTransactions.SingleOrDefault(x => x.RowID == Convert.ToInt32(item_number));
if(photo != null){
photo.pp_txn_id = pp_txn_id;
db.SubmitChanges();
var thisPaidPhoto = (from p in db.Photos
where p.PhotoId == Convert.ToInt32(item_number)
select p).FirstOrDefault();
return View(thisPaidPhoto);
}
else
{
return View();
}
}

How to return list linq in json in MVC Controller?

public List<Detail> GetOrderDetails()
{
var orderDetails = (from user in db.Users
join detail in db.OrderDetails
on user.Id equals detail.UserId
where (detail.DateAdded != null)
select new Detail
{
FirstName = user.FirstName,
LastName = user.LastName,
Origin = detail.OriginCode,
Destination = detail.DestinationCode,
CarrierCode = detail.CarrierCode,
IsReturn = detail.IsReturn,
IsCancel = detail.IsCancel,
OrderId = detail.OrderId
}).FirstOrDefault();
return Json(orderDetails);
}
This code gives me the following error.
Cannot implicitly convert type 'System.Web.Mvc.JsonResult' to
'System.Collections.Generic.List<TravelingAdmin.Controllers.Detail>
Problems:
(your query).FirstOrDefault(); returns an element not a list.
Json(x) converts x to string which contains json representation of x.
Here are your options:
You can remove FirstOrDefault() and use return (your query).ToList() if you want to return list of objects.
You can change the return type of method to Detail instead of List<Detail> and then use return orderDetails; instead of return Json(orderDetails);
UPDATE:
As inferred from title of the question you want to "return list in json in MVC Controller"
You should change the method to this
public ActionResult GetOrderDetails()
{
var orderDetails = (from user in db.Users
join detail in db.OrderDetails
on user.Id equals detail.UserId
where (detail.DateAdded != null)
select new Detail
{
FirstName = user.FirstName,
LastName = user.LastName,
Origin = detail.OriginCode,
Destination = detail.DestinationCode,
CarrierCode = detail.CarrierCode,
IsReturn = detail.IsReturn,
IsCancel = detail.IsCancel,
OrderId = detail.OrderId
}).ToList();
return Json(orderDetails, JsonRequestBehavior.AllowGet);
}
Just change your return type to JsonResult And use .tolist() method to convert in to list return Json(orderdetails.tolist(),jsonrequestbehaviour.allowget) it's depend on your request if you send request Through "Post" method then use [httppost] attribute on the top of method name and remove "jsonrequestbehaviour.allowget" from your code, it will work for you.

ASP.Net MVC 5 Entity Framework Select Where In?

I have 3 tables Project, Province, ProjProvRel
In my project page when I add data I select multiple provinces for each project
means my Province is multi select dropdown list.
I insert data it is working I get the inserted Id and added to ProjProvRel with selected Ids of Province
Now In details view I want to display my data but I could not solve it.
here is my code:
// GET: Project/Details/5
public ActionResult Details(int? id)
{
if (id == null)
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
var mydata = db.Projects.Find(id);
if (mydata == null)
{
return HttpNotFound();
}
var prov_id = from o in db.ProRel where o.ProjectId.Equals(id) select o.ProvinceIds;
foreach (var p_id in prov_id)
{
int[] PIds = new int[] {p_id};
}
var Prov= from c in db.Provinces where c.ID in pIds;
ViewBag.Province = Prov;
return View(mydata);
}
one problem is how can I select data from table based on where condition
var prov_id = from o in db.ProRel where o.ProjectId.Equals(id) select o.ProvinceIds;
is the above query correct ? I am new to ASP.Net MVC
also blow query is correct ?
var Prov= from c in db.Provinces where c.ID in pIds;
how can I select data from Table Province where province.ID in PIds
Get the rows from ProRel where the ProjectId matches with id:
var prov_ids = db.ProRel.Where(r => r.ProjectId == id).Select(r => r.ProvinceId);
Get the provinces that can be found from prov_id:
var provs = db.Provinces.Where(p => prov_id.Any(i => p.ID == i));
I hope you don't mind the lambda-style LINQ.
Also, I think you should consider your variable naming. For example, prov_id gives the idea of a single id and since you declared the type implicitly it is difficult to tell otherwise.

Categories