18

I working on my first ASP.net MVC project and and i got some problems using multi forms in same page. First i have created 2 partial Class : (*Register will allow user to register, *Login it allow user to login.)

Then i used HTML.render to integrate them in my "Logpage". So i have To uses 2 different Action. Like this one:

    [HttpPost]
    public ActionResult Login(LogModel.Login Model)
    {
        if (ModelState.IsValid)
        {

            if (LogModel.Login.Verifuser(Model.IDUser, Model.Password))
            {
                FormsAuthentication.SetAuthCookie(Model.IDUser, false);
                if (LogModel.Login.IsAdmin(Model.IDUser, Model.Password))
                {
                    return View("Admin/Index");
                }
                else
                {
                    return View("Agence/Index");
                }
            }
            else
            {
                ModelState.AddModelError("", "Invalide username or Password");
                return View(Model);
            }
        }
        return View(Model);
    }

The problem that on error case i'm redirect to new Page(White page contain validation summary). So i'm wondring how to show this error message in my default page Logpage.

2
  • 2
    Post your code. Follow the formatting guides for instructions on how to make it legible. Commented Apr 3, 2012 at 16:56
  • What exactly is the problem? If you're concerned about the form POST action, you can certainly have both forms POST to different controller actions. Commented Apr 3, 2012 at 17:06

3 Answers 3

32

You can solve this with three actions and a complex model.

 public class LoginOrRegisterViewModel
 {
      public Models.RegisterViewModel Register { get; set; }
      public Models.LoginViewModel Login { get; set; }
 }


 [HttpGet]
 public ActionResult Login()
 {
      return View("Login", new LoginOrRegisterViewModel());
 }

 [HttpPost]
 public ActionResult Register(Models.LoginViewModel model)
 {
      if(!ModelState.IsValid)
           return View("Login", new LoginOrRegisterViewModel(){ Register = model });
      else
      {
           //TODO: Validate the user
           //TODO: Write a FormsAuth ticket
           //TODO: Redirect to somewhere
     }
 }

 [HttpPost]
 public ActionResult Login(Models.RegistrationViewModel model)
 {
      if(!ModelState.IsValid)
           return View("Login", new LoginOrRegisterViewModel(){ Login = model});
      else
      {
           //TODO: CRUD for registering user
           //TODO: Write forms auth ticket
           //TODO: Redirect
     }
 }

In your code, make sure that you set the action of the Form:

 @model Models.LoginOrRegisterViewModel

 @using(Html.BeginForm("Login", "Controller", FormMethod.Post, new { id = "loginForm"}))
 {
       @Html.EditorFor(m => Model.Login)
 }

 @using(Html.BeginForm("Register", "Controller", FormMethod.Post, new { id = "registerForm"}))
 {
       @Html.EditorFor(m => Model.Register)
 }
Sign up to request clarification or add additional context in comments.

12 Comments

FYI, your second POST method should be called Register.
This part """ public class LoginOrRegisterViewModel { public Models.RegisterViewModel Register {get;set;} public Models.LoginViewModel Login {get;set;} """ where i put it in My Model Class ??? }
Also What's ""LoginOrRegister"
I updated the second POST method to Register, Tuan was correct, it was a typo. LoginOrRegisterViewModel is a Class which is a Model or ViewModel. These usualy go in your Models folder. "LoginOrRegister" should have been "LoginOrRegisterViewModel", I refactored my code before I submitted it and didn't double check all names before submitting. There is also a way to share one controller action for two seperate forms but it's dirty and involves looping through the ModelState and removing errors unrelated to the form that did the submission. I would stick with splitting the actions
For me, I had to have as input parameter LoginOrRegisterViewModel on both POST methods. Just having one of the underlying ones (register/login viewModel) as parameter gave null values inside the model.
|
0

It looks like you also need to call IsAdmin in the !Verifyuser branch, to have it return the correct view:

        if (ModelState.IsValid)
        {

            if (LogModel.Login.Verifuser(Model.IDUser, Model.Password))
            {
                FormsAuthentication.SetAuthCookie(Model.IDUser, false);
                if (LogModel.Login.IsAdmin(Model.IDUser, Model.Password))
                {
                    return View("Admin/Index");
                }
                else
                {
                    return View("Agence/Index");
                }
            }
            else
            {
                ModelState.AddModelError("", "Invalide username or Password");

                if (LogModel.Login.IsAdmin(Model.IDUser, Model.Password))
                    return View("Admin/Index", Model);
                else
                    return View("Agence/Index", Model);

            }
        }

Currently, you're calling return View(Model); when you have a ModelState error, which returns the default view for the action, called "Login".

3 Comments

this didn't Work there is confision beetwen Model
Then you need to cast Model to the type expected by the Index views, or construct it, and pass it instead Model to View("Admin/Index") and View("Agence/Index").
I'm beginer i ASP.net MVC can u explain me more ?? i did'nt get the point :'(
0

If you want multiple forms posted to a controller action simultaneously, create a JSON object with client JS that has a separate property for each form and give each of those properties a camel-case name that corresponds to a respective ProperCase parameter of your controller action. Then, send in a serialization of that JSON object to your controller:

let form1 = $('#my-form1-id');
let form2 = $('#my-form2-id');
let url = 'myArea/myController/myAction'
let viewData = {
    controllerParameter1: form1,
    controllerParameter2: form2
};

$.ajax({

    url: url,
    type: 'POST',
    data: JSON.stringify(viewData),
    dataType: "json",
    beforeSend: function () {
        $('#my-submit-button-id').html('<i class="fa fa-2x fa-cog fa-spin"></i>');
        $('#my-submit-button-id').attr("disabled", "disabled");
    },
    success: function (res) {
        alert("Submitted!");
    },
    error: function (status, err) {
        alert("Failed!");
    },
    complete: function (status, err) {

        $('#my-submit-button-id').html('Submit My 2 Forms');
    }
});

That should work for a controller action w/ a signature similar to:

[HttpPost]
public virtual async Task<ActionResult> MyAction(ViewModel1 controllerParameter1, ViewModel2 controllerParameter2)
{
    // do amazing things
}

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.