Pass Value from View To Controller in Asp.net MVC - 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.

Related

How can I set the ReturnUrl when I am using RedirectToAction?

I have a controller that redirects to another action, e.g.
mysite.com/food/3
This action does a RedirectToAction to an action called Cake and passes in id=3.
If the user is not authenticated at that point, you go back to the loginpage, but the RedirectUrl is /Cake (without any mention of the id) and not /food/3. This causes an error once you log in because firstly it shouldn't be accessed via that url in the browser, and secondly because the parameters have vanished.
Is there a simple way to make sure it redirects to the original URL in the browser, or do I have to write a custom authorize attribute and store a lookup table to get the parent page?
Gonna take a stab at this one.
Food and Cake take id values and redirect parameters and just pass them around freely where they can be used as you see fit.
Food
public ActionResult Food (int id, string returnUrl = string.Empty)
{
// Do work
return RedirectionToAction("Cake", new { id, returnUrl })
}
Cake
[Authorize]
Cake (int id, string returnUrl = string.Empty)
{
// Do work
if (returnUrl != string.Empty)
return Redirect (returnUrl);
return View();
}
A problem arises when a View is finally returned to the client because then you have to somehow get that returnUrl into the form posted when they submit their login info because you want to use it later. So the first step is getting it into the View's form so it's included in the model that gets posted. One way to do that is the ViewBag; another way is pulling it from the query string. I've shown an example of both below.
Option 1:
Login
Login (string returnUrl = string.Empty)
{
ViewBag.ReturnUrl = returnUrl;
return View();
}
Login.cshtml
Model.ReturnUrl = ViewBag.ReturnUrl;
Option 2:
Login
Login ()
{
return View();
}
Login.cshtml
Model.ReturnUrl = Request.QueryString["ReturnUrl"];
If this doesn't suffice, comment and I can try to modify this answer further.
The simplest way to make this work is to put the AuthorizeAttribute onto the action method that calls RedirectToAction to short circuit the nonsense of building the wrong URL. The FormsAuthenticationModule uses the RawUrl of the request when it adds the ReturnUrl parameter, so it not possible to modify without building your own custom FormsAuthenticationModule (which you could consider option B). But if you check authorization before you redirect the RawUrl will be correct.
// This ensures it builds the correct ReturnUrl.
[Authorize]
public ActionResult Food (int id)
{
// Do work
return RedirectionToAction("Cake", new { id = id })
}
// This ensures the final destination cannot be accessed
// without authorization.
[Authorize]
public ActionResult Cake (int id)
{
// Do work
return View();
}

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();
}
}

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

MVC Url not pathing correctly

I have a link going to
<a class="k-link" href="/UserView/EditByName?UserName=MVCTest6">Profile</a>
When the link it is clicked it goes to this
URL: http://localhost:3256/MVCTest6/Create
which works when i am logged in as an admin user. (The folder has no security in a web.config setting it apart). This link actually works on another part of the page.
The user also already exist and has been authenticated.
Can this please be explained?
I get it ! This is where the problem is,
return RedirectToAction("Create", User.Identity.Name);
you are using this overload RedirectToAction("Action", "Contoller");
So the later part is taken as the controller. Try other overloads that matches your requirement, if you are trying to pass values to another action, which must be like
return RedirectToAction("Create", new {UserName = User.Identity.Name});
I forgot I had logic in place to redirect if user profile was not created. This was causing the problem. My test user didnt have profile already setup so it was redirecting to the create page
public ActionResult EditByName(string userName)//EditByName
{
if (User.Identity.IsAuthenticated)
{
UserModel usermodel = repository.Get(User.Identity.Name);// db.UserModels.Find(id);
if (usermodel == null)
{
return RedirectToAction("Create", User.Identity.Name);
}
return View(usermodel);
}
else { return RedirectToAction("Login", controllerName: "AccountView"); }
}

Resources