4

How can you have a form that doesn't require the user to be logged in until they click submit, and at that point submits the form if the user is logged in, and otherwise redirects to the login page. Then after the user logs in successfully, submits the original form? The original form has an <input type="file"> element also, and the file shouldn't be uploaded unless the user successfully logs in.

3 Answers 3

3

I know this is an old post, hopefully, my experience will help someone:

I have two submit buttons and a common method that gets called for handling form submission from both of them - conditional statements inspect which button is submitting the form.

On the button that requires the user to be authenticated, it was returning HttpUnauthorizedResult() to force the user back to the login page. After login, the user will just be sent back to the form with field values filled in because they were being stored in a TempData entry, but the user still needed to click the button again to submit the data.

So, I added a boolean TempData variable called AutoSave that will be set right before returning the HttpUnauthorizedResult(). I check it before loading the form again and if AutoSave == true I just redirect to the method that handles the submission. Works like a charm.

Here's the sample code:

private ActionResult ProcessOnlineApplication(OnlineApplicationViewModel application){

        //if not submit make sure it's save.
        if (application.SubmitAction == "Save")))
        {
             if(!User.Identity.IsAuthenticated)
             {
                    //Keep a copy of the application until logged in
                    TempData["PendingOnlineApplication"] = application;
                    TempData["AutoSave"] = true;
                    return new HttpUnauthorizedResult();
             }
             else{
                   //Everything goes here
             }
        }
}
public ActionResult OnlineApplicationForm(){
        var viewModel = TempData["PendingOnlineApplication"] as OnlineApplicationViewModel;
        if (TempData.ContainsKey("AutoSave") && Convert.ToBoolean(TempData["AutoSave"]) && viewModel != null)
        {
            TempData["AutoSave"] = false;
            return ProcessOnlineApplication(viewModel);
        }
        if (viewModel == null)
        {
            viewModel = CreateModel();
        }
        return GetOnlineApplicationAction(viewModel);
}
Sign up to request clarification or add additional context in comments.

Comments

2

MVC handles this scenario. Just put the "[Authorize]" attribute only on the form post action the one which has the [HttpPost]. On posting the form as the user is not logged in, he will be redirected to Account controller login action(/Account/Login) and login view will be rendered; this is because it is set so in web.config. Along with this redirection a query string parameter "ReturnUrl=/orginalform" is also added. The MVC login action then does the login and redirects the user again to the original form.

Update: Here is the code that should go in the custom attribute that will capture the form data if you need to retain the form data(this is not tested, only compiled)

    public class CustomAuthorizeAttribute : AuthorizeAttribute
    {
       public override void OnAuthorization(
                            AuthorizationContext filterContext)
      {           
          if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
          {

              string loginUrl = "/Account/Login"; //Get this from web.config instead of hardcode
              if (filterContext.HttpContext.Request != null)
              {
                  loginUrl += "?ReturnUrl=" + filterContext.HttpContext
                                                           .Request
                                                           .Url
                                                           .AbsoluteUri;
                  foreach(var formData in filterContext.HttpContext.Request.Form)
                  {
                      loginUrl += "&"+formData.ToString();
                  }
              }              
              filterContext.Result = new RedirectResult( loginUrl );
          }
      }
    }

You may need some modifications into the login post action. Also the return form get action should fetch the form data from the uri string [FromUri] and render the form again.

3 Comments

They will have to fill out the form again with this method
If you need that then you need to modify the ReturnUrl default mechanism to include the form data. You need you own Authorize attribute that can add the form data along with return url. Then the login action will redirect to the original url with this data. In the get action of your form you need to handle fetching form paramaters from uri and rendering the form again as it was. To start with I suggest create a CustomAuthorize attribute that derives from AuthorizeAttribute and override the OnAuthorization method.
Updated the above post check it.
1

It turns out I cannot do what I wanted because it is a security risk to programmatically populate the <input type=file> field and it is not allowed.

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.