0

I am completely stuck and confused why it works with one View to Controller but not the other one.

The one that works:

public class HomeController : Controller
{
    // GET: Home
    IAuthenticationManager Authentication
    {
        get { return HttpContext.GetOwinContext().Authentication; }
    }

    public ActionResult Index()
    {
        return View();
    }

    [POST("login")]
    [ValidateAntiForgeryToken]
    public ActionResult Login(LoginModel input)
    {
        if (ModelState.IsValid)
        {
            if (input.HasValidUsernameAndPassword())
            {
                var identity = new ClaimsIdentity(new[] {
                        new Claim(ClaimTypes.Name, input.Username),
                    },
                    DefaultAuthenticationTypes.ApplicationCookie,
                    ClaimTypes.Name, ClaimTypes.Role);

                // if you want roles, just add as many as you want here (for loop maybe?)
                if (input.isAdministrator)
                {
                    identity.AddClaim(new Claim(ClaimTypes.Role, "Admin"));
                }
                else
                {
                    identity.AddClaim(new Claim(ClaimTypes.Role, "User"));
                }
                // tell OWIN the identity provider, optional
                // identity.AddClaim(new Claim(IdentityProvider, "Simplest Auth"));

                Authentication.SignIn(new AuthenticationProperties
                {
                    IsPersistent = input.RememberMe
                }, identity);

                return RedirectToAction("password", "authentication");
            }
        }
        return View("show", input);
    }

    [GET("logout")]
    public ActionResult Logout()
    {
        Authentication.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
        return RedirectToAction("login");
    }
}

With this CSHTML code:

@model AgridyneAllIn1MVC.Models.Authentication.LoginModel
@using (Html.BeginForm())
{
 @Html.AntiForgeryToken()

 <div class="form-horizontal">
    <h4>Details</h4>
    <hr />
    @Html.ValidationSummary(true)

    <div class="form-group">
        @Html.LabelFor(model => model.Username, new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Username)
            @Html.ValidationMessageFor(model => model.Username)
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Password, new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Password)
            @Html.ValidationMessageFor(model => model.Password)
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.RememberMe, new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.RememberMe)
            @Html.ValidationMessageFor(model => model.RememberMe)
        </div>
    </div>

    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" value="Login" class="btn btn-default" />
        </div>
    </div>
</div>
}

The CSHTML that doesn't work is:

@using Microsoft.AspNet.Identity
@model AgridyneAllIn1MVC.Models.Authentication.LoginModel
@if(User.Identity.IsAuthenticated)
{
   using (Html.BeginForm("resetpassword", "authentication", FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{
    @Html.AntiForgeryToken()
    <h4>Reset your password.</h4>
    <hr />
    @Html.ValidationSummary("", new { @class = "text-danger" })
    <div class="form-group">
        @Html.LabelFor(m => m.Username, new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.TextBoxFor(m => m.Username, new { @class = "form-control" })
        </div>
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.Password, new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.PasswordFor(m => m.Password, new { @class = "form-control" })
        </div>
    </div>
    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" class="btn btn-default" value="Reset" />
        </div>
    </div>
}
}

The Controller that goes with it is:

public class AuthenticationController : Controller
{
    [Authorize]
    public ActionResult Password()
    {
        return View("ResetPassword");
    }

    [Authorize]
    public ActionResult Register()
    {
        return View("Register");
    }

    [Authorize]
    [POST("resetpassword")]
    public ActionResult ResetPassword(LoginModel input)
    {
        if (ModelState.IsValid)
        {
            if (User.Identity.IsAuthenticated)
            {
                if(input.SuccessfullyUpdatedPassword())
                {
                    return View("Password");
                }
            }
        }
        return View("Password");
    }

    [Authorize]
    [POST("registernewuser")]
    public ActionResult RegisterNewUser(LoginModel input)
    {
        if (ModelState.IsValid)
        {
            if (User.Identity.IsAuthenticated)
            {
                if (input.SuccessfullyUpdatedPassword())
                {
                    return View();
                }
            }
        }
        return View();
    }
}

Every time I try to get to either of those pages I get

The resource cannot be found. HTTP 404. Requested URL: /resetpassword.

Am I missing something that is required in the HTML.BeginForm() that would make it go to the correct ActionEvent to fire off my code and update the view? This is my first MVC that I am building from scratch and designing the views from scratch. Does MVCs have a problem with having multiple views to one controller? What gets me is that the MVC that works doesn't have anything filled in the HTML.BeginForm(), I tried it without having anything in HTML.BeginForm() and I get the same result. I tried with changing the [GET("resetpassword")] to [GET("")] and it doesn't work either. I have another view that is called register and it has the same problem with the AuthenticationController. So can someone please tell me what is wrong and explain why so I can fully understand how MVC wants things to be done so I get it right for the other 50 plus views that I still have to build yet.

7
  • 3
    Your controller method is marker with [HttpGet] but your form is POSTed. I'd suggest to change your controller method: replace HttpGet with HttpPost. Commented Jun 12, 2015 at 15:54
  • 2
    as a side note, you can [Authorize] the class and not have to put it on every method. Commented Jun 12, 2015 at 15:55
  • 2nd side note: you don't actually need to use GetAttribute("your_method_name"), simply HttpGet works (url is case insensitive to resolve to a method) Commented Jun 12, 2015 at 15:57
  • @AdrianoRepetti So if it is something that is taking a input from a form it has to have POST but if its a view getting displayed then you use GET? Commented Jun 12, 2015 at 16:00
  • 2
    @AdrianoRepetti I have one more question about MVC and how I am doing it, if my code is correct or not. Am I properly giving each user a role? I want the users that are Admins to see more stuff then simple users. Also can you submit your answer so I can mark it as the answer since you gave that answer first. Commented Jun 12, 2015 at 16:58

2 Answers 2

1

Your Form use FormMethod.Post but there aren't exist POST resetpassword method in your Controller

Sign up to request clarification or add additional context in comments.

Comments

0

Change the [GET("resetpassword")] to POST because the form from cshtml file use the post method:

using (Html.BeginForm("resetpassword", "authentication", FormMethod.Post,....

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.