提交按钮映射到没有相关视图的Controller操作。根据情况返回不同的视图

时间:2022-12-01 22:53:14

In MVC4, a controller named UserController contains an action ForgotPassword and a respective view is also created. This view contains one textbox and one submit button. On the submit of this button the email id should be verified, if not found in record, it should show a error message on the same view, else navigate to different view. I have used Begin Form for mapping the submit button to a new action VerifyEmailId in UserController. However I am stuck on passing the view based on the validity of the email id. Note that this action VerifyEmailId does not have any related view.

在MVC4中,名为UserController的控制器包含一个动作ForgotPassword,并且还创建了相应的视图。此视图包含一个文本框和一个提交按钮。在提交此按钮时,应验证电子邮件ID,如果未在记录中找到,则应在同一视图上显示错误消息,否则导航到不同视图。我使用Begin Form将提交按钮映射到UserController中的新操作VerifyEmailId。但是我坚持根据电子邮件ID的有效性传递视图。请注意,此操作VerifyEmailId没有任何相关视图。

Please suggest the best way to do it.

请建议最好的方法。

View Code:

@model UIKendoLearning.Models.UserDetails
<h2>Forgot Retrieval</h2>
@using (Html.BeginForm("ForgotPassword", "User"))
{
 <div id="PasswordRetrieval">
 @Html.Label("Please enter your registered email address: ")
 <input type="email" id="Email" value="@Model.Email" name="Email" placeholder="e.g.      myname@example.net" />
 @Html.ValidationMessageFor(m => m.Email)
 <br />
 <input type="submit" name="Submit" value="Generate New Password" />
 </div>
}

Controller Code:

public class UserController : Controller
{
    //
    // GET: /User/

    public ActionResult ForgotPassword()
    {
        return View(new UserDetails());
    }

    [HttpPost]
    public ActionResult SendNewPassword(UserDetails userInfo)
    {
        try
        {
            if (userInfo != null)
            {
                HttpClient server = new HttpClient();
                server.DefaultRequestHeaders.Add("EmailId", userInfo.Email);
                HttpResponseMessage response = server.GetAsync("http://localhost/BankService/api/Account/ValidateUser").Result;
                if (response.StatusCode != HttpStatusCode.Found)
                {                        
                    return RedirectToAction("ForgotPassword", "User");
                }
            }
        }
        catch (Exception ee)
        {

        }
        return RedirectToAction("Index", "Home");
    }

3 个解决方案

#1


0  

I have a similar implementation, I suggest you don't need a new Action ValidateEmailID, but only a bool function that you can call from the ForgotPassword Post Action.

我有一个类似的实现,我建议你不需要一个新的Action ValidateEmailID,但只需要一个你可以从ForgotPassword Post Action调用的bool函数。

This could be the Controller code:

这可能是Controller代码:

//
// GET: /User/ForgotPassword

[AllowAnonymous]
public ActionResult ForgotPassword()
{
  return View();
}

//
// POST: /User/ForgotPassword

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult ForgotPassword(String email)
{
  if (ModelState.IsValid)
  {
    if (verifyEmailId(email))
    {
      // Do something, i.e. send email with proper instruction
      // Display a view to say action is done!
      return View("ConfirmReset");
      // Or redirect to another action:
      return RedirectToAction("ActionName", "ControllerName");
    }
    else
    {
      // Add an error message
      ModelState.AddModelError("", "The email ID you submitted is unknown");
    }
  }
  // Redisplay the ForgotPassword View with error message, preserving the submitted email value
  ViewBag.email = email;
  return View();
}

private bool verifyEmailId(email) {
   // Your own code
   // return true if email is valid
}

And this could be the ForgotPassword View code:

这可能是ForgotPassword View代码:

<p>Please submit the email address to reset the password</p>

@using (Html.BeginForm()) {

  @Html.AntiForgeryToken()
  @Html.ValidationSummary()

  @Html.Label("email")
  @Html.Editor("email")

  <input type="submit" value="Reset Password" />
}

I hope this could be usefull for you.

我希望这对你有用。

#2


0  

Modify your method

修改你的方法

@model UIKendoLearning.Models.UserDetails
<h2>Forgot Retrieval</h2>
@using (Html.BeginForm("ForgotPassword", "User"))
{
 <div id="PasswordRetrieval">
 @ViewBag.Error **// Your Error comes here**
 @Html.Label("Please enter your registered email address: ")
 <input type="email" id="Email" value="@Model.Email" name="Email" placeholder="e.g.      myname@example.net" />
 @Html.ValidationMessageFor(m => m.Email)
 <br />
 <input type="submit" name="Submit" value="Generate New Password" />
 </div>
}

Controller

    public ActionResult ForgotPassword()
    {
        if (Request.QueryString["error"] != null) 
           ViewBag.Error = "Email Not Found";
        else
           ViewBag.Error = "";
        return View(new UserDetails());
    }
    [HttpPost]
    public ActionResult SendNewPassword(UserDetails userInfo)
    {
        try
        {
            if (userInfo != null)
            {
                HttpClient server = new HttpClient();
                server.DefaultRequestHeaders.Add("EmailId", userInfo.Email);
                HttpResponseMessage response = server.GetAsync("http://localhost/BankService/api/Account/ValidateUser").Result;
                if (response.StatusCode != HttpStatusCode.Found)
                {                        
                    return RedirectToAction("ForgotPassword", "User",new{error="notFound"});
                }
            }
        }
        catch (Exception ee)
        {

        }
        return RedirectToAction("Index", "Home");
    }

#3


0  

As @Doan Cuong wrote it is good solution to use content validity. For example, you have model for your view like this:

正如@Doan Cuong所写,使用内容有效性是一个很好的解决方案。例如,您的视图模型如下:


    class UserDetails
    {
        [DataType(DataType.EmailAddress)]
        [Required(ErrorMessage = "Please enter a proper email address")]
        public string Email { get; set; }

        // property for displaying custom error message if validation failed
        public string ErrorMessage { get; set; }

        ...
    }

You have a form which calls action ForgetPassword. SendNewPassword should be renamed to ForgetPassword. And if you using try/catch it will be good if you display something if error occures. So, the controller code may look like this:

你有一个调用动作ForgetPassword的表单。 SendNewPassword应重命名为ForgetPassword。如果你使用try / catch,如果你发现错误就会很好。因此,控制器代码可能如下所示:


    class UserController
    {
        [NonAction]
        private bool VerifyEmail(string email)
        {
            // ... verify logic
        }

        public ActionResult ForgotPassword()
        {
            return View(new UserDetails());
        }

        [HttpPost]
        public ActionResult ForgotPassword(UserDetails userInfo)
        {
            if (ModelState.IsValid)
            {
                // Here is userInfo.Email is a proper email address
                if(VerifyEmail(userInfo.Email)
                {
                    HttpClient server = new HttpClient();
                    server.DefaultRequestHeaders.Add("EmailId", userInfo.Email);
                    HttpResponseMessage response = server.GetAsync("http://localhost/BankService/api/Account/ValidateUser").Result;
                    if (response.StatusCode != HttpStatusCode.Found)
                    {
                        // Here is error action ForgotPassword with param with field "error"                        
                        // return RedirectToAction("ForgotPassword", "User",new{error="notFound"});
                        return View("ForgotPassword", "User", new UserDetails { ErrorMessage = "Email not found" } );
                    }
                    // Here is all ok - go home
                    return RedirectToAction("Index", "Home");
                }
            }
            // Redisplay form with error messages
            return View(model);
        }
    }
    

And modify the View code:

并修改View代码:

@model UIKendoLearning.Models.UserDetails

<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>

<h2>Forgot Retrieval</h2>
@using (Html.BeginForm("ForgotPassword", "User"))
{
    <div id="PasswordRetrieval">
    @Html.Label("Please enter your registered email address: ")
    <input type="email" id="Email" value="@Model.Email" name="Email" placeholder="..." />
    @Html.ValidationMessageFor(m => m.Email)
    @if(Model.ErrorMessage != null)
    {
        @* you can insert some good html *@
        <span>@Model.ErrorMessage</span>
    }
    <br/>
    <input type="submit" name="Submit" value="Generate New Password" />
    </div>
}

#1


0  

I have a similar implementation, I suggest you don't need a new Action ValidateEmailID, but only a bool function that you can call from the ForgotPassword Post Action.

我有一个类似的实现,我建议你不需要一个新的Action ValidateEmailID,但只需要一个你可以从ForgotPassword Post Action调用的bool函数。

This could be the Controller code:

这可能是Controller代码:

//
// GET: /User/ForgotPassword

[AllowAnonymous]
public ActionResult ForgotPassword()
{
  return View();
}

//
// POST: /User/ForgotPassword

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult ForgotPassword(String email)
{
  if (ModelState.IsValid)
  {
    if (verifyEmailId(email))
    {
      // Do something, i.e. send email with proper instruction
      // Display a view to say action is done!
      return View("ConfirmReset");
      // Or redirect to another action:
      return RedirectToAction("ActionName", "ControllerName");
    }
    else
    {
      // Add an error message
      ModelState.AddModelError("", "The email ID you submitted is unknown");
    }
  }
  // Redisplay the ForgotPassword View with error message, preserving the submitted email value
  ViewBag.email = email;
  return View();
}

private bool verifyEmailId(email) {
   // Your own code
   // return true if email is valid
}

And this could be the ForgotPassword View code:

这可能是ForgotPassword View代码:

<p>Please submit the email address to reset the password</p>

@using (Html.BeginForm()) {

  @Html.AntiForgeryToken()
  @Html.ValidationSummary()

  @Html.Label("email")
  @Html.Editor("email")

  <input type="submit" value="Reset Password" />
}

I hope this could be usefull for you.

我希望这对你有用。

#2


0  

Modify your method

修改你的方法

@model UIKendoLearning.Models.UserDetails
<h2>Forgot Retrieval</h2>
@using (Html.BeginForm("ForgotPassword", "User"))
{
 <div id="PasswordRetrieval">
 @ViewBag.Error **// Your Error comes here**
 @Html.Label("Please enter your registered email address: ")
 <input type="email" id="Email" value="@Model.Email" name="Email" placeholder="e.g.      myname@example.net" />
 @Html.ValidationMessageFor(m => m.Email)
 <br />
 <input type="submit" name="Submit" value="Generate New Password" />
 </div>
}

Controller

    public ActionResult ForgotPassword()
    {
        if (Request.QueryString["error"] != null) 
           ViewBag.Error = "Email Not Found";
        else
           ViewBag.Error = "";
        return View(new UserDetails());
    }
    [HttpPost]
    public ActionResult SendNewPassword(UserDetails userInfo)
    {
        try
        {
            if (userInfo != null)
            {
                HttpClient server = new HttpClient();
                server.DefaultRequestHeaders.Add("EmailId", userInfo.Email);
                HttpResponseMessage response = server.GetAsync("http://localhost/BankService/api/Account/ValidateUser").Result;
                if (response.StatusCode != HttpStatusCode.Found)
                {                        
                    return RedirectToAction("ForgotPassword", "User",new{error="notFound"});
                }
            }
        }
        catch (Exception ee)
        {

        }
        return RedirectToAction("Index", "Home");
    }

#3


0  

As @Doan Cuong wrote it is good solution to use content validity. For example, you have model for your view like this:

正如@Doan Cuong所写,使用内容有效性是一个很好的解决方案。例如,您的视图模型如下:


    class UserDetails
    {
        [DataType(DataType.EmailAddress)]
        [Required(ErrorMessage = "Please enter a proper email address")]
        public string Email { get; set; }

        // property for displaying custom error message if validation failed
        public string ErrorMessage { get; set; }

        ...
    }

You have a form which calls action ForgetPassword. SendNewPassword should be renamed to ForgetPassword. And if you using try/catch it will be good if you display something if error occures. So, the controller code may look like this:

你有一个调用动作ForgetPassword的表单。 SendNewPassword应重命名为ForgetPassword。如果你使用try / catch,如果你发现错误就会很好。因此,控制器代码可能如下所示:


    class UserController
    {
        [NonAction]
        private bool VerifyEmail(string email)
        {
            // ... verify logic
        }

        public ActionResult ForgotPassword()
        {
            return View(new UserDetails());
        }

        [HttpPost]
        public ActionResult ForgotPassword(UserDetails userInfo)
        {
            if (ModelState.IsValid)
            {
                // Here is userInfo.Email is a proper email address
                if(VerifyEmail(userInfo.Email)
                {
                    HttpClient server = new HttpClient();
                    server.DefaultRequestHeaders.Add("EmailId", userInfo.Email);
                    HttpResponseMessage response = server.GetAsync("http://localhost/BankService/api/Account/ValidateUser").Result;
                    if (response.StatusCode != HttpStatusCode.Found)
                    {
                        // Here is error action ForgotPassword with param with field "error"                        
                        // return RedirectToAction("ForgotPassword", "User",new{error="notFound"});
                        return View("ForgotPassword", "User", new UserDetails { ErrorMessage = "Email not found" } );
                    }
                    // Here is all ok - go home
                    return RedirectToAction("Index", "Home");
                }
            }
            // Redisplay form with error messages
            return View(model);
        }
    }
    

And modify the View code:

并修改View代码:

@model UIKendoLearning.Models.UserDetails

<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>

<h2>Forgot Retrieval</h2>
@using (Html.BeginForm("ForgotPassword", "User"))
{
    <div id="PasswordRetrieval">
    @Html.Label("Please enter your registered email address: ")
    <input type="email" id="Email" value="@Model.Email" name="Email" placeholder="..." />
    @Html.ValidationMessageFor(m => m.Email)
    @if(Model.ErrorMessage != null)
    {
        @* you can insert some good html *@
        <span>@Model.ErrorMessage</span>
    }
    <br/>
    <input type="submit" name="Submit" value="Generate New Password" />
    </div>
}