How can I implement multiple forms using a single view? - asp.net-mvc-4

I am having a scenario where I need to implement two forms using a single view... There will be a home page having a form each for LogIn and SignUp (similar to Facebook homepage). I created a view for my home page (Index.cshtml) that contains the razor code for both my forms.
[#using (Html.BeginForm("LogIn", "Home", FormMethod.Post))]
[#using (Html.BeginForm("SignUp", "Home", FormMethod.Post))]
However, upon clicking the 'Log In' button for LogIn form or clicking 'Sign Up' button for SignUp form, the runtime throws an error basically saying that I still need to create views for both LogIn and SignUp actions, even though I have already implemented the HTML forms in my index.cshtml
[NOTE: I am not using ASP.NET membership provider. And this question is generally for two forms, can be any two forms.]
So my question is: Do I really need to create two more views named LogIn.cshtml and SignUp.cshtml? Won't this cause code duplication? I'm quite new to MVC 4 and I hope you understand what I'm trying to do here, so all I want to know is whether there is any other way to implement this? (jQuery, AJAX or something)
public class HomeController : Controller
{
[HttpGet]
public ActionResult Index()
{
return View();
}
[HttpGet]
public ActionResult LogIn()
{
return View();
}
[HttpPost]
public ActionResult LogIn(Account acc)
{
// some code
return View();
}
[HttpGet]
public ActionResult SignUp()
{
return View();
}
[HttpPost]
public ActionResult SignUp(Account acc)
{
// some code
return View();
}
}

You could specify the view you want to be returned:
[HttpGet]
public ActionResult SignUp()
{
return View("LogIn");
}

Related

Redirect to login page when click the tab

I'm very new in ASP.Net Core.
Let say I have three tabs such as Home, contact and about.
The user can only access contact and about page if they are login. Otherwise, they cannot access the page. My question is, if the user is not login yet, how to redirect to the login page if they click the Contact or about tab?
Before you go into the answer, it might be to your benefit to read through the great documentation available at the official Microsoft Docs.
As a simple solution, I would suggest you add authorization by using the AuthorizeAttribute.
If your project is using MVC
public class HomeController : Controller
{
public ActionResult Index()
{
}
[Authorize]
public ActionResult About()
{
}
[Authorize]
public ActionResult Contact()
{
}
}
Alternatively, if your project is using RazorPages
[Authorize]
public class AboutModel : PageModel
{
...
}

form submit always hit in mvc index method while enable unobtrusive javascript enabled

MY form element submit is not working while enable unobtrusive javascript mode. it always hits in index method. how to resolve this issue. while enable unobtrusive mode with form submit successfully.
public ActionResult Index()
{
var Data = value;
ViewBag.dataSource = Data;
return View();
}
public ActionResult frmbtn()
{
return View("Index");
}
[HttpPost]
public void Formposting()
{
// it not hit while enable unobtrusive in webconfig
. . .
}
You didn't show view code it's difficult to locate the problem. you can match your code with given below:
#using (Html.BeginForm("Formposting", "ControllerName", FormMethod.Post, new { id = "formid" }))
{
}
Donot forget to replace "ControllerName" with actual controller name.
Or if you have blank in beginform like below
#using (Html.BeginForm())
{
}
You need to add one more "Action" with httppost and model
public ActionResult Index(Your Model Here){ return View();}

MVC5 EF6 How to add confirmation screen with additional authentication before submitting data

Developing a new MVC5 project. I have my scaffolding in place for CRUD functionality but there is a requirement that when data is inserted or updated, an e-signature is required. Before data can be submitted to the database the user must be presented with a page asking them to enter their username and password again to confirm the data. If the username and password entered is valid and the username matches the currently signed in user, then the original data entered can be saved to its table (for example Member) and the e-signature information is saved to a separate table (ESignature). I'd appreciate any help on the best way to go about this - a view model combining Member and ESignature, or a reuse of the LoginViewModel from the Account controller to check the authentication, or an alternative approach? I need something that I can use across half a dozen controllers where e-signatures are required.
Alright maybe my approach is not the best but I will attempt.
My solution would be to create a CustomAttribute: AuthorizeAttribute and decorate all the actions which require Esignature. In your CustomAttribute implementation you will redirect to a controller action exactly similar to Login but with slight modification.
public class CustomAuthorize : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
var url = filterContext.HttpContext.Request.Url;
var query = url.Query;
if (query.Contains("g="))
{
var code = query.Split(new String[] { "g=" }, StringSplitOptions.None);
//You can create time sensistive token and validate it.
}
else
{
//Redirect User to a particular page
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary
{
{ "controller", "Account" },
{ "action", "elogin" },
{ "redirectUrl", url.AbsolutePath}
}
);
}
}
}
Then decorate for example Index() method with it.
[CustomAuthorize]
public ActionResult Index()
{
return View();
}
At first when you hit the Index() method then inside OnAuthorization method of CustomAuthorizeAttribute the else loop gets executed and re-directs you to a elogin method inside AccountController. This method is similar to the Login HttpGet method. While specifying the RedirectToResult I am specifying the redirectUrl path of the current page so when you successfully validate a user inside the elogin method then with the help of redirectUrl we can come back.
[AllowAnonymous]
public ActionResult ELogin(string returnUrl)
{
ViewBag.ReturnUrl = returnUrl;
return View("Login");
}
//
// POST: /Account/Login
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> ELogin(LoginViewModel model, string returnUrl)
{
if (ModelState.IsValid)
{
var user = await UserManager.FindAsync(model.UserName, model.Password);
if (user != null)
{
await SignInAsync(user, model.RememberMe);
var url = String.Format("{0}/?g={1}", returnUrl, "HashCode");
return RedirectToLocal(url);
}
else
{
ModelState.AddModelError("", "Invalid username or password.");
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
The only difference in the HttpPost ELogin method is that before doing RedirectToLocal I append /g=HasCode. Note: Here you can append your own logic to create a time sensitive hash. When we get redirected to our home page then we can inspect inside our OnAuthorization Method if the url contains g=HashCode then don't redirect to Login Page.
This would be very basic idea on how you can approach to force users to re-sign in whenever they hit specific controllers. You will have to do additional security checks and be careful in what you are exposing via url.

How do I add new information to the database?

I am working with the following code. I have set up the form, models, and controllers necessary to add an item. I know the code works because after entering text into the text field I am redirect to the correct page. My question is: How do I add the text entered by the user into the default database?
public ActionResult TruckAdd()
{
ViewBag.DisplayText = "Add A Truck";
return View();
}
[HttpPost]
public ActionResult TruckAdd(RegisterTruckModel model)
{
if (ModelState.IsValid)
{
// Attempt to register the Truck
try
{
return RedirectToAction("Index", "Dashboard");
}
catch
{
}
}
// If we got this far, something failed, redisplay form
return View(model);
}

Routing GET and POST routes in ASP.NET MVC 4

I am trying to setup a Login form in an ASP.NET MVC 4 app. Currently, I have configured my view as shown here:
RouteConfig.cs
routes.MapRoute(
"DesktopLogin",
"{controller}/account/login",
new { controller = "My", action = "Login" }
);
MyController.cs
public ActionResult Login()
{
return View("~/Views/Account/Login.cshtml");
}
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginModel model)
{
return View("~/Views/Account/Login.cshtml");
}
When I attempt to visit /account/login in the browser, I receive an error that says:
The current request for action 'Login' on controller type 'MyController' is ambiguous between the following action methods:
System.Web.Mvc.ActionResult Login() on type MyApp.Web.Controllers.MyController
System.Web.Mvc.ActionResult Login(MyApp.Web.Models.LoginModel) on type MyApp.Web.Controllers.MyController
How do I setup a basic form in ASP.NET MVC 4? I've looked at the sample Internet App template in ASP.NET MVC 4. However, I can't seem to figure out how the routing is wired up. Thank you so much for your help.
I haven't tried this yet but can you try annotating your Login actions with the appropriate Http Verb - I'm assuming that you're using a GET for viewing the login page and a POST for processing the login.
By adding [HttpGet] for the first action and [HttpPost] for the second action the theory is that ASP.Net's routing will then know which Action method to call based upon which method has been used. Your code should then look something like this:
[HttpGet] // for viewing the login page
[ViewSettings(Minify = true)]
public ActionResult Login()
{
return View("~/Views/Account/Login.cshtml");
}
[HttpPost] // For processing the login
[ViewSettings(Minify = true)]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginModel model)
{
return View("~/Views/Account/Login.cshtml");
}
If this doesn't work, consider having two routes and two differently named actions like below:
routes.MapRoute(
"DesktopLogin",
"{controller}/account/login",
new { controller = "My", action = "Login" }
);
routes.MapRoute(
"DesktopLogin",
"{controller}/account/login/do",
new { controller = "My", action = "ProcessLogin" }
);
There are other similar questions and answers on StackOverflow already, take a look at: How to route GET and DELETE for the same url and there is also the ASP.Net documentation which might also help.