Doing db.find with non primary key - asp.net-mvc

So what im trying to do is im trying to get an user from my database where the email im trying to find matches an email in my database. If i had the id instead of the email i could just do an db.user.find(id) but i only have the email so im trying to use where but without success.
this is my code
// POST: api/User_Agendapunt1
[ResponseType(typeof(User))]
public IHttpActionResult PostUser_Agendapunt(User user1)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
User user = db.User.Where(o => o.Email== user1.Email);
var user_dagpunten = from s in db.User_agendapunt
where s.UserId == user.IdUser
select s;
return Ok(user_dagpunten.ToList());
}
EDIT1:

User user= db.User.Where(x=> x.Email==user1.Email).FirstOrDefault();
if(user !=null)
{
// do your stuff
}
else{
//return no user exist with given email
}
Hope this solves your issue ...

Related

Error checking in controller in ASP.NET Core MVC

I'm discovering ASP.NET Core MVC and I'm on my first project. Creating a cool web shop.
I'm currently wondering how to implement faulty information checking for example in the controller
Let's say there a product page, whenever users clicks on a product they will hit the function below.
As you can see the function accepts an int parameter named id, it will search in the database for the id that fits the productId, but I'm wondering how do I add error checking here? Like for example if the id does not exist in database return to page XX?
Also feel free to give suggestions to the function if you don't like it.
I've already tried to do a simple if and else statement
if(productvm == null)
{
then
return RedirectToPage("Index")
}
else
return View("ProductPage", productVm);
but it didn't seem to hit the if statement
[Route("ProductPage/{id}")]
public IActionResult ProductPage(int id)
{
Product product = _uow.Products.SelectProduct(id);
var stockViewModels = new List<StockViewModel>();
foreach (Stock stock in product.Stock)
{
stockViewModels.Add(new StockViewModel()
{
Id = stock.Id,
Description = stock.Description,
IsAvailable = stock.IsAvailable,
Quantity = stock.Quantity,
});
}
ProductViewModel productVm = new ProductViewModel
{
Name = product.Name,
Id = product.Id,
Description = product.Description,
Price = product.Price,
Stocks = stockViewModels,
};
if (productVm == null)
{
return RedirectToPage("Productslist");
}
else
{
return View("ProductPage", productVm);
}
}
I basically want an error handling the controller if the id is not found in the database then execute XX
The way how I test the function is to change the ID when browsing the page with an ID that does not exist in the database, then I get this error:
https://i.imgur.com/1amWx43.png
and I want to handle it
I think your problem is that you have new the productVm object before the if, so it will never be null, for your case, you should get check the product object and not the productVm, for example:
Product product = _uow.Products.SelectProduct(id);
if (product == null)
{
return RedirectToPage("Productslist");
}
else
{
return View("ProductPage", productVm);
}

MVC AspNetUser get registered User ID

I am trying to do the following: I would like to get the registered user ID by receiving the user mail and checking if that mail all ready exists in AspnetUsers table. If it does then get the User ID else create a new user. I have started by doing the following:
if (UserManager.FindByEmail(model.Email) != null)
{
// get user Id
// Update person table
}else
//create a new user
{
but I can not get the user ID.
I resolved my issue by doing the following:
if (UserManager.FindByEmail(model.Email) != null)
{
var registedUserID = context.AspNetUsers.FirstOrDefault(x => x.Email == model.Email);
string id= registedUserID.Id; // Now my id is equal to UserMembership Id
}
I got the AspNetUsers where mail equals the mail I recieved then I could get that User Id.
The FindByEmail() should return an ApplicationUser object to you. Just assign it to a local variable and retrieve the Id.
var user = UserManager.FindByEmail(model.Email);
if (user != null)
{
// get user Id
var userId = user.Id;
// Update person table
}
else
//create a new user
{
}

Error message position in mvc razor

I'm trying to put custom error messages for a login and registration forms.
So far I have the form to check if there's an email already registered, if it is, it will return
Response.Write("There's already someone with that email")
But the problem with this is that the message will only appear on the top of the website.
Is there a way I could display these error messages somewhere else?
I know that in the model I could just put
[Required(ErrorMessage = "Something here")]
And then just put in the view somewhere
#Html.ValidationMessageFor(a =>a.Email)
and it will display the error there.
The code that I have for now is this:
[HttpPost]
public ActionResult Register(Registration signingUp)
{
var db = new ShareRideDBEntities();
if (ModelState.IsValid)
{
//find if email is already signed up
var FindEmail = db.tblProfiles.FirstOrDefault(e => e.PROF_Email == signingUp.Email);
//if email is not found up do this
if (FindEmail == null)
{
var Data = db.tblProfiles.Create();
Data.PROF_Password = signingUp.Password;
Data.PROF_Email = signingUp.Email;
db.tblProfiles.Add(Data);
int Saved = db.SaveChanges();
if (Saved != 0)
{
Response.Write("Registration Successful.");
}
else
{
Response.Write("There was an error.");
}
}
else
{
Response.Write("There's already an user with that email.");
return View();
}
}
else
{
Response.Write("Fill all the fields to continue.");
}
return View();
Now if I do this with an existing email it will return "There's already an user with that email." but it will be display on the top of the website.
How can I make this error message be displayed somewhere else?
I heard something with #Html.Raw() but I'm confused on how to use it.
Using this.ModelState.AddModelError method you can add any custom error message you want. If you specify property name as a key - it will be displayed by corresponding ValidationMessageFor. So in controller instead of writing to response directly do this:
ModelState.AddModelError("Email", "There's already an user with that email.");
return View();
And in view this line which you already have:
#Html.ValidationMessageFor(a =>a.Email)
will display this messagea at whatever part of the page you place it (presumably near the field for email).

Duplicate users added to database

I try to add a new value to my database. UserPassword and RePassword must have the same value and a user with UserName must not already exist in the database.
public User NewUser(int HotelID, string UserName, string UserPassword, string RePassword, string FullName, string Email, bool Active, bool MasterUser)
{
User user = new User();
user.HotelID = HotelID;
user.UserName = UserName;
user.UserPassword = UserPassword;
user.FullName = FullName;
user.Email = Email;
user.IsActiveq = Active;
user.IsMaster = MasterUser;
var cekUser = (from c in _UserRepository.All()
where c.HotelID == HotelID
select c.UserName).ToList();
if (UserPassword == RePassword)
{
foreach (string cek in cekUser)
{
var x = cek;
if (UserName != x)
{
_UserRepository.Add(user);
}
}
}
_UserRepository.CommitChanges();
return user;
}
Every time I run my code a new line is added to the database, although a user with the supplied user name already exists in the database.
Why does this happen? Which part of my code is wrong?
I think your code should be something like this:
if (UserPassword == RePassword)
{
// Also I thinks you should finish whether user existed logic in database
// but for now, let's follow your original logic
var existedUsers = (from c in _UserRepository.All()
where c.HotelID == HotelID
select c.UserName).ToList();
if (!existedUsers.Any(u => u == UserName))
{
_UserRepository.Add(user);
_UserRepository.CommitChanges();
}
}
You have your logic wrong. If there is more than one user in a given hotel, your code will be adding more users for all users with names different from UserName.
bool found = false;
foreach(string cek in cekUser)
{
if ( UserName == cek)
{
found = true;
break;
}
}
if (!found)
_UserRepository.Add(user);
Just offering an alternate idea.
If you have access to the database, the best approach will be to make the Username field UNIQUE. That way, even if you get your code wrong, a duplicate insert will fail. Then you capture that fail gracefully in your Repository, and Bob's your uncle.

How to integrate OpenId with ASP.Net Membership in MVC

I am using the following code from MVC Storefront to test OpenId in MVC. How do I integrate it with my ASP.Net Membership so I can use roles and save a user name for the user in my tables? I believe that SO is also using something similar.
public ActionResult OpenIdLogin()
{
string returnUrl = VirtualPathUtility.ToAbsolute("~/");
var openid = new OpenIdRelyingParty();
var response = openid.GetResponse();
if (response == null)
{
// Stage 2: user submitting Identifier
Identifier id;
if (Identifier.TryParse(Request["openid_identifier"], out id))
{
try
{
IAuthenticationRequest req = openid.CreateRequest(Request["openid_identifier"]);
var fetch = new FetchRequest();
//ask for more info - the email address
var item = new AttributeRequest(WellKnownAttributes.Contact.Email);
item.IsRequired = true;
fetch.Attributes.Add(item);
req.AddExtension(fetch);
return req.RedirectingResponse.AsActionResult();
}
catch (ProtocolException ex)
{
ViewData["Message"] = ex.Message;
return View("Logon");
}
}
else
{
ViewData["Message"] = "Invalid identifier";
return View("Logon");
}
}
else
{
// Stage 3: OpenID Provider sending assertion response
switch (response.Status)
{
case AuthenticationStatus.Authenticated:
var fetch = response.GetExtension<FetchResponse>();
string name = response.FriendlyIdentifierForDisplay;
if (fetch != null)
{
IList<string> emailAddresses = fetch.Attributes[WellKnownAttributes.Contact.Email].Values;
string email = emailAddresses.Count > 0 ? emailAddresses[0] : null;
//don't show the email - it's creepy. Just use the name of the email
name = email.Substring(0, email.IndexOf('#'));
}
else
{
name = name.Substring(0, name.IndexOf('.'));
}
//FormsAuthentication.SetAuthCookie(name, false);
SetCookies(name, name);
AuthAndRedirect(name, name);
if (!string.IsNullOrEmpty(returnUrl))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
case AuthenticationStatus.Canceled:
ViewData["Message"] = "Canceled at provider";
return View("Logon");
case AuthenticationStatus.Failed:
ViewData["Message"] = response.Exception.Message;
return View("Logon");
}
}
return new EmptyResult();
}
ActionResult AuthAndRedirect(string userName, string friendlyName)
{
string returnUrl = Request["ReturnUrl"];
SetCookies(userName, friendlyName);
if (!String.IsNullOrEmpty(returnUrl))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
}
There are several questions like yours already on StackOverflow. This one seems particularly similar.
If you're already using the Membership provider for your site and are just adding OpenID to it, then I guess you're stuck with Membership for now and can use one of the answers to the question I linked to to get a semi-decent membership provider that MAY work for you.
But if you're writing a new site and just want "use roles and save a user name for the user in my tables" as you said, then DON'T use ASP.NET Membership at all. It's SO not worth it! It doesn't fit OpenID's password-less paradigm and just causes more grief than anything else. If you're not afraid of a little bit of database access yourself, do it that way. And you can get Roles behavior very easily by just issuing your own FormsAuthentication.RedirectFromLoginPage or FormsAuthentication.SetAuthCookie call and passing in the roles the user fills.
The open id provider will return data about the user. If you don't request/require specific tokens of information, then all you'll be given is the user's display name and identity URL.
Depending on what open id library you're using, you can request tokens like FirstName LastName, DOB (if you really cared) and if the user provided that information on their chosen identity, then you'd get it returned to you.
You can then use this to create a new user in the membership system. You'll probably have to give them a dummy password to get around the requirements of the Membership API.
To validate a login, provide 1 form that takes username & password and the other that takes an identity URL. After you've validated the user via open id, try to find the user by username (identity url) in the Membership API. If it doesn't exist, create it.

Resources