I want to send a HTTP POST request in a controller.
This is my code:
[HttpPost]
public IHttpActionResult login([FromBody] ClubAPI.Models.AllRequest.login userid)
{
using (DAL.ClubEntities db = new ClubEntities())
{
DAL.AspNetUser q = db.AspNetUsers.Single(t=>t.Id.Equals(userid.id.ToString()));
if (q == null)
{
return Ok(new ClubAPI.Models.AllResponse.loginResponse
{
msg = "bad",
state = false,
});
}
return Ok(new ClubAPI.Models.AllResponse.loginResponse
{
msg = "good",
state = true,
token = q.UserName,
});
}
}
But now I get the error below:
"Non-static method requires a target in webapi" i cant solve that. the
error is related to this line:
db.AspNetUsers.Single(t=>t.Id.Equals(userid.id.ToString()));
When I change the ID to a real ID, like "t.Id.Equals(2342)", the error is resolved; but I do not want to use the real ID.
Try this code instead of
DAL.AspNetUser q = db.AspNetUsers.SingleOrDefault(t=>t.Id == userid.id.ToString());
into
DAL.AspNetUser q = db.AspNetUsers.SingleOrDefault(t=>t.Id == userid.id);
It seems your problem is in the following line which probably does not find the user:
DAL.AspNetUser q = db.AspNetUsers.Single(t=>t.Id.Equals(userid.id.ToString()));
write it like (depending on the type of id) which will return null when the user is not found:
DAL.AspNetUser q = db.AspNetUsers.SingleOrDefault(t=>t.Id == userid.id.ToString());
If t.Id.Equals(2342) works, then t.Id must not be a string and so you shouldn't be using .ToString()
Try
db.AspNetUsers.Single(t=>t.Id.Equals(userid.id));
or
db.AspNetUsers.Single(t=>t.Id == userid.id);
Make sure this userid not null and userid.id.ToString() is not return null
DAL.AspNetUser q = db.AspNetUsers.Single(t=>t.Id.Equals(userid.id.ToString()));
when any lambda variable return null then this type of error happen.
To prevent this you can do like this
DAL.AspNetUser q = db.AspNetUsers.SingleOrDefault(t=>t.Id == userid.id.ToString());
Related
I'm fairly new with updating databases, and I've constructed the below code to replace a user's role with a new role. I'm getting the error in the subject though.
public void UpdateRole(string id, string newRoleID)
{
var user = Users.FirstOrDefault(u => u.Id == id);
var oldRoleId = user.Roles.FirstOrDefault().RoleId;
if (user != null && oldRoleId != newRoleID)
{
user.Roles.Remove(oldRoleId);
user.Roles.Add(newRoleID);
}
}
Could someone please explain why I am getting this error? I am not trying to convert anything. I am attempting to delete the contents of RoleId for the user id specified, and replace it with the new ID that is sent from my post action.
user.Roles.Add method takes a IdentityUserRole object while you are passing it a string value (i.e. newRoleID). You need the following change in you code:
user.Roles.Add(new IdentityUserRole { RoleId = newRoleID });
Edit
The Remove method, needs an IdentityUserRole object too. But note that it must be attached to the context too. The simplest way you can do it is through the following code:
var user = Users.FirstOrDefault(u => u.Id == id);
var oldRole = user.Roles.FirstOrDefault();
if (user != null && oldRole.RoleId != newRoleID)
{
user.Roles.Remove(oldRole);
user.Roles.Add(new IdentityUserRole { RoleId = newRoleID });
}
I have a table named dbo.EmployeeType with three records:
PK_EmployeetypeID EmployeeTypeName
1 Project Manager
2 Business Analyst
3 Developer
I have this piece of Linq code:
public static string GetTypeByID(int id)
{
using (ProjectTrackingEntities1 db = new ProjectTrackingEntities1())
{
var type = db.EmployeeTypes.Select(o => new LOOKUPEmployeeType
{
PK_EmployeeTypeID = id,
EmployeeTypeName = o.EmployeeTypeName
});
return type.FirstOrDefault().EmployeeTypeName;
}
}
No matter what id I send to it, it returns Project Manager, and I'm confused as to why.
You need to apply a filter, otherwise you're just returning the first record and hard coding the ID. Try this:
public static string GetTypeByID(int id)
{
using (ProjectTrackingEntities1 db = new ProjectTrackingEntities1())
{
//Here we apply a filter, the lambda here is what creates the WHERE clause
var type = db.EmployeeTypes
.FirstOrDefault(et => et.PK_EmployeeTypeID == id);
if(type != null)
{
return type.EmployeeTypeName;
}
else
{
return "";
}
}
}
Note that using FirstOrDefault means if there are no matches, or multiple matches, type will be null and you will get an empty string returned.
Set a breakpoint on type = ... and inspect it. You have no Where in there so you get all - and Select just makes LOOKUPEmployeeTypes out of all of them.
FirstOrDefault then returns the first of those 3 which is always the ProjManager
Fix:
var type = db
.EmployeeTypes
.Where( o => o.Id == id)
.Select(o => new LOOKUPEmployeeType
{
PK_EmployeeTypeID = id,
EmployeeTypeName = o.EmployeeTypeName
});
In your code you only return the first value. You need to tell EF which value you need to return.
Let us assume you need the value with Id=2. Instead of Select(), use Single(x => x.Id == 2) or First(x => x.Id == 2).
I have this in my test scenario:
var dbConnection = new Mock<IDbConnection>();
dbConnection.Setup(x => x.SearchFor<User>("users", y => y.Password =="12345"
&& y.Username == "tester")).Returns(new List<User>{
new User{
Username = "tester",
Password = "12345"
}}.AsQueryable());
var users = new Users.Users(dbConnection.Object);
var user = users.Get("tester", "12345");
When looking at the Get method:
public User Get(string username, string password){
var total = _dbConnection.SearchFor<User>("users", y =>
y.Password == password &&
y.Username == username).Single();
return total;
}
It should work according by most of the samples I found on the internet, but it always gives me:
System.InvalidOperationException: Sequence contains no elements
When I change my Get method to this:
public User Get(string username, string password){
var total = _dbConnection.SearchFor<User>("users", y =>
y.Password == "12345" &&
y.Username == "tester").Single();
return total;
}
It magicaly works, but the get method is in a business layer and like we all know... to set a username and password hardcoded is never good.
The question is: How can I get the setup for moq work properly? What am I doing wrong?
so you're setting up, expecting the paramters "users" and y => y.Password == "12345" && y.UserName == "tester". However, your second parameter is a lambda, which are hard to compare (if not impossible?). So, when Moq is checking to see if you've called that, it's ultimately trying to compare lambdas, which will probably fail.
For example the following code shows two seemingly identical functions, but they are not considered to be equal:
Func<bool> a = () => true;
Func<bool> b = () => true;
(a == b).Dump(); //False
a.Equals(b).Dump(); //False
Therefore Moq doesn't know to use the return value that you setup.
You may need to implement a mock repository that will actually run the lambda instead of trying to find the same one that you provided.
Something like this:
class TestRepo
{
public void Add<T>(T myType)
{
//add to an in-memory "database"
}
public IEnumerable<T> Get<T>(Expression<Func<T, bool>> filter)
{
return inMemoryDataBase.Where(filter);
}
}
Which would make your Get method look something like this:
public User Get(string username, string password){
var total = RealRepo.Get<User>(y =>
y.Password == "12345" &&
y.Username == "tester").Single();
return total;
}
And your test:
var repo = new TestRepo();
repo.Add(new User { Username = "tester", Password = "12345" });
var users = new Users.Users(dbConnection.Object);
var user = users.Get("tester", "12345");
Here is a somewhat related question where a user was trying to find a way to uniquely identify a lambda so that they could be "compared" in the way you're hoping for. I don't know that any perfect solutions were found there. Link
I have a parameter that is passed to a action from a view that when matched only shows those corresponding results.
Everything works as normal when the parameter passed in has a match, but when the id being passed it does not match any id, the corresponding view is showing all the results.
public ActionResult ShowResults(Guid ParameterId)
{
return this.PartialView(this.MyClassVariable.MyGetMStuffMetod().Where(x => x.Id == ParameterId));
}
Is there a way I can tell it if the ids do not match return nothing?
My Method
public IList<MyStuffViewModel> MyGetStuffMethod()
{
IList<MyStuffViewModel> result = (IList<MyStuffViewModel>)HttpContext.Current.Session["MyStuff"];
if (result == null)
{
HttpContext.Current.Session["MyStuff"] = result =
(from mStuff in new dbEntities().TableA
select new MyStuffViewModel
{
Id = mStuff.Id,
Name = mStuff.Name
}).ToList();
}
return result;
}
This worked, but I think it is something else causing the issue, I will track it down and post the results. Thanks for the help.
.Where(x => x.Id == ParameterId).GroupBy(t => t.ParameterId));
I need to convert a sql statement to a linq query.
The code below has my area in question marked -
public class MyObjectController : Controller
{
private EFDbContext db = new EFDbContext();
private IObjectRepository objRepo;
public MyObjectController(IObjectRepository objectRepository)
{
objRepo = objectRepository;
}
//
// GET: /Client/MyObject/
public ActionResult Index()
{
if (User.Identity.IsAuthenticated)
{
MembershipUser currentUser = Membership.GetUser(User.Identity.Name, true);
if (currentUser != null && currentUser.ProviderUserKey != null && currentUser.IsApproved)
{
var currentUserId = (Guid)currentUser.ProviderUserKey;
<========HOW TO EXECUTE IN LINQ==================>
Object result = (from obj in objRepo
where obj.ObjId == currentUserId
select obj).FirstOrDefault();
<========HOW TO EXECUTE IN LINQ==================>
return View(result);
}
}
return View();
}
Just to clarify - I am going for something more like this but I don't know how to get the syntax right:
Object myObj = moveRepo.Objects
.Where(m => m.ObjectId)
.Equals(m => currentUserId)
return View(myObj);
You are using LINQ and I don't see any SQL statement. Probably you want to modify the LINQ statement to work it properly. In your query you need to specify the data context and the table.
var result = (from obj in yourDataContext.yourEntity
where obj.ObjId == currentUserId
select obj).FirstOrDefault();
That query will give you your record if found, null otherwise
Have a look at LINQpad.
I've found it to be really useful and is ideal for checking what if your linq is doing what you are used to with SQL.