Error message position in mvc razor - asp.net-mvc

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).

Related

Doing db.find with non primary key

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 ...

Multiple views modifying one object MVC

I am building a service which requires a somewhat lengthy setup process. I have it broken into 4 models and 4 corresponding views. They are Setup, Setup2, Setup3, and Setup4. Each of these views gathers information from the user which is stored in a User object. I have been passing the user along like this:
[HttpPost]
public ActionResult Setup(FormCollection values)
{
User registeringUser = new User();
registeringUser.email = User.Identity.Name;
registeringUser.fName = values["fName"];
registeringUser.lName = values["lName"];
registeringUser.phone = values["phone"];
return RedirectToAction("/Setup2", registeringUser);
}
For some reason, this seems to work just fine for the first jump (from Setup to Setup2) but after that I'm getting weird behavior, such as User. getting set to null when the User is passed to another View.
In a related, but slightly different issue, I need the last screen (Setup4) to be recursive. This screen adds a course in which the user is enrolled, and if they don't check the "This was my last class" button, it needs to basically clear the form so they can enter another course.
The entire Controller looks like this:
[HttpPost]
public ActionResult Setup4(FormCollection values, User registeringUser)
{
// values["allClassesAdded"] returns "false" as a string if box is unchecked, returns "true,false" if checked.
// Solution: parse string for "true"
if (utils.parseForTrue(values["allClassesAdded"]))
{
// TODO Redirect to "congratulations you're done" page.
database.CreateUserInDB(registeringUser);
return Redirect("/Home");
}
else
{
// Build course and add it to the list in the User
course c = new course(values);
if (Request.IsAuthenticated)
{
//registeringUser.currentCourses.Add(c);
registeringUser.AddCourse(c);
return RedirectToAction("/Setup4", registeringUser); // <---- This doesn't really work right
//return View();
}
else
{
return Redirect("/Account/Login");
}
}
}
This is my first project with MVC, so if you find that I'm doing the entire thing completely incorrectly, feel free to not answer the question I asked and offer the proper solution to this need. I'm moving an existing (pure) C# project to MVC and I'm mainly just stuck on how to work within MVC's interesting structure. I'm very grateful for any help you can give!
Thanks!
You can store user related data in session without passing it between requests
Smth like this
[HttpPost]
public ActionResult Step1(Step1Model model)
{
Session["UserRegistration"] = new UserRegistration
{
FirstName = model.fName,
....
}
....
}
[HttpPost]
public ActionResult Step2(Step2Model model)
{
var userRegistration = Session["UserRegistration"] as UserRegistration;
if (userRegistration == null) { return Redirrect("Step1"); }
userRegistration.SomeField = model.someField;
...
Session["UserRegistration"] = userRegistration;
....
}

error from the controller not coming to view in MVC

if (user.UserName == DbData.UserName && DbData.Password.Equals(user.Password, tringComparison.CurrentCultureIgnoreCase))
{
//redirect to main page //this is working fine
}
else {
ModelState.AddModelError("Error", "Username/Password not matching");
ViewBag.Message = ModelState["Error"].Errors[0].ErrorMessage;
return View();
}
and in View i wrote
#if(ViewBag.Message != null){
ViewBag.Message
}
but the error in the viewbag is not coming on the view
That's normal, if you check the TempData["Error"] in the immediate window, you'll see that it's null.
You need to give something to the view bag to get something in the view side.
UPDATE:
This will give you your message (
"Username/Password not matching") that you can set it to the ViewBag.
ModelState["Error"].Errors[0].ErrorMessage
Hope this solves your problem.
For your Info:
ModelStateDictionary.AddModelError Method (String, Exception):
Adds the specified model error to the errors collection for the model-state dictionary that is associated with the specified key.
from ModelState.AddModelError
UPDATE:
To display the message in the View use the # sign before the ViewBag.Message
#if (!string.IsNullOrWhiteSpace(ViewBag.Message))
{
#ViewBag.Message
}

Password reset in MVC

I have a view at /Account/ResetPassword where the user will provide an email address for the account who's password they want to reset.
The email sent for the password reset will contain a link that looks something like this:
/Account/ResetPassword/{reset key}
I'm not sure how or where to design the view for the creation of the new password though.
It occurred to me to use a partial view that has its master set to the ResetPassword view, but having to name the view confuses me...
The url suggests a dynamic name, so how do I create the View?
I wouldn't bother with the inheritance of the ResetPassword view, you aren't gaining much given it's only a single field. I would create a distinct view for CreatePassword, you can determine which view you want to return based on whether the reset key parameter is provided or not e.g.
public ActionResult ResetPassword(string resetKey)
{
if (String.IsNullOrEmpty(resetKey)) {
return View(); // will return "ResetPassword" view
} else {
// check validity of key then redirect if necessary
return RedirectToAction("CreatePassword");
}
}
I would create /Account/ConfirmResetPassword/{reset key} as the link in the email. If the reset key is correct, then redirect user to another view, let's say /Account/ChangePassword where user can change the password. If the reset key is incorrect, then stay on /Account/ConfirmResetPassword/{reset key} and display a message that the reset key is invalid.
This would be the controller action method for /Account/ConfirmResetPassword/{reset key}
public ActionResult ConfirmResetPassword(string resetKey)
{
bool isResetKeyCorrect = ...; // check if resetKey is correct here.
if (isResetKeyCorrect)
{
// redirect to /Account/ChangePassword
return RedirectToAction("ChangePassword", "Account");
}
else
{
// Display a message saying that the reset key is invalid
.......
return View();
}
}

Pass Value from View To Controller in Asp.net MVC

I am trying to pass a message to another view (actually same controller) I can do it well but there is a problem for me..
I am new on web and it doesnt seem good ..
and here my c# code
if (createStatus == MembershipCreateStatus.Success)
{
string registrationMessage = "You have registered successfully";
return RedirectToAction("KurumsalGiris", new { message = registrationMessage });
}
[AllowAnonymous] //sonradan eklendi
public ActionResult KurumsalGiris(string message="")
{
if (User.Identity.IsAuthenticated)
return Content("Zaten giriş yapmışsınız");
ViewBag.RegistrationMessage = message;
return View();
}
and here html side
#model E_Cv.Models.LogOnModel
#{
ViewBag.Title = "Kurumsal Giriş";
}
<h2>Kurumsal Giriş</h2>
<h2>#ViewBag.RegistrationMessage</h2>
<p>
Please enter your user name and password.
#Html.ActionLink("Yeni Kurum Kaydı", "KurumsalKayit")
if you don't have an account.
</p>
so I dont know how to pass value to another view with different way.. I dont want to show this kind of message on address bar and user musnt change it.
Secondly Could I do it with "Get" Method?
Why don't you just return a different view rather than redirecting? In fact, the code the posted in the first place should be posting to a controller that returns a view for a successful login.
In fact, why are you redirecting to a page that asks the user to login if they've just logged in?
Other possible options include encrypting the string in the URL, or just passing a flag in the URL that the controller translates into the corresponding string.
What you would do is instead of returning a RedirectToAction
you could return the View directly: (second parameter is a model, where you can use the same model class E_Cv.Models.LogOnModel adding a RegistrationMessage property to it)
return View("<name of the view>",
new E_Cv.Models.LogOnModel {
RegistrationMessage = "You have registered successfully"
});
or keep the data in the ViewBag like you have done:
ViewBag.RegistrationMessage = "You have registered successfully";
return View("<name of the view>");
regarding your last question, give the message is showing in your URL, you are using the GET method, if you return a View instead of a redirect, it'll avoid showing anything in the URL
You should use TempData in this scenario
if (createStatus == MembershipCreateStatus.Success)
{
TempData["Message"] = "You have registered successfully";
return RedirectToAction("KurumsalGiris");
}
And then in your view
#if (TempData["Message"] != null)
{
<h2>#TempData["Message"]</h2>
}
Or if you want to do it in the controller, just keep your view the same as it is at the moment and set ViewBag.RegistrationMessage in the controller
ViewBag.RegistrationMessage = TempData["Message"];
If the question is how to pass data between controllers without using the querystring, then one option is the Session object.
if (createStatus == MembershipCreateStatus.Success)
{
Session["Message"] = "You have registered successfully";
return RedirectToAction("KurumsalGiris");
}
[AllowAnonymous] //sonradan eklendi
public ActionResult KurumsalGiris(string message="")
{
if (User.Identity.IsAuthenticated)
return Content("Zaten giriş yapmışsınız");
ViewBag.RegistrationMessage = (string) Session["Message"];
return View();
}
However, I agree with #Jonathan Wood below that this is not necessarily the best approach to the particular problem you are attempting to solve. Still, as a general technique, it is worth knowing about.

Resources