razor mvc4 and c# codebehind - c#

Alright, so I have just started with razor mvc4 and I have a little experience with c#. I am currently making a website on which there is a button. my html follows:
<button onclick ="vote1_click" id="VoteButton" value="Vote">Vote</button>
this is in a .cshtml view
I then have a class to handle the vote1_click event. It is in c# and follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace MvcApplication1
{
public class voting
{
public void vote1_click(object sender, EventArgs e)
{
}
}
}
I believe that my issue is a fundamental understanding of the razor structure, but could not figure it out on my own.
Any help at all is appreciated, and I will try to not feel too stupid when the answer is simple.
Thanks!
EDIT:
I have been getting an issue where the Add(string name) gives me an error of "not all code paths return a value"
here is the rest of my code as requested:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Data.SqlClient;
namespace WAgermanClub.Controllers
{
public class HomeController : Controller
{
[HttpPost]
public ActionResult Add(string vote)
{
SqlConnection vote1connection = new SqlConnection("user id=userid;" +
"password=validpassword;server=o5z5dpwpzi.database.windows.net;" +
"Trusted_Connection=yes;" +
"database=wagermanclub_votes; " +
"connection timeout=30");
try
{
vote1connection.Open();
}
catch (Exception g)
{
Console.WriteLine(g.ToString());
}
try
{
SqlDataReader myReader = null;
SqlCommand myCommand = new SqlCommand("select * from table", vote1connection);
myReader = myCommand.ExecuteReader();
while (myReader.Read())
{
Console.WriteLine(myReader["Vote1"].ToString());
}
}
catch (Exception i)
{
Console.WriteLine(i.ToString());
}
SqlCommand vote1command = new SqlCommand("INSERT INTO table (Column1, Vote1) " +
"Values (1, 'Vote1' + 1)", vote1connection);
vote1command.ExecuteNonQuery();
try
{
vote1connection.Close();
}
catch (Exception h)
{
Console.WriteLine(h.ToString());
}
}
}
}
And here is my HTML:
#{
ViewBag.Title = "Ideas";
}
#section featured {
<section class="featured">
<div class="content-wrapper">
<hgroup class="title">
<h1>#ViewBag.Title.</h1>
<h2>#ViewBag.Message</h2>
</hgroup>
<p>
</p>
</div>
</section>
}
<body>
<div style="border: solid; max-width: 300px; margin-left: auto; margin-right: auto">
#using(Html.BeginForm())
{
<input type="submit" value="Vote"/>
}
</div>
</body>
Thanks!

You are confused with ASP.NET webforms and MVC. MVC works more in the classic Web (GET-POST form) style. You post a form with values. There is no such click events and event handler in codebehind like what you have in web forms.
So to render your page, you may have an action method like this in your HomeController
public class HomeController : Controller
{
public ActionResult Add()
{
return View();
}
}
So in your Add view(razor file), you need to have some code to render a form tag with input elements. Let's use the Html.Begin form helper method to render the form tag for us.
#using(Html.Beginform())
{
<input type="text" name="name" />
<input type="submit" />
}
This will render a form tag in your markup with action property set as "Home/Add", assuming your GET action method is in HomeController. (Check the view source of the page)
So when user clicks on the submit button it will post the form to the Add action. so make sure you have an action method like this in HomeController to handle the form posting.(The one decorated with HttpPost attribute
[HttpPost]
public ActionResult Add(string name)
{
//do something with the posted values
return RedirectToAction("Success"); // redirecting to another view
}

You may be confusing the webforms model with the asp.net mvc model.
razor is only available for you when using webpages or asp.net mvc.
For asp.net mvc there's not concept of a server method/event as you've defined here.
You'll typically need to define action methods in your controllers which will be responsible for processing whatever forms your are posting.
You may want to check out more on ASP.NET MVC

MVC does not implement the web forms style viewstate and event handlers. So there is no vote1_click. What you would want to do is either
1) Create a JavaScript Post/Get back to the server
or
2) have a form and post back all the form variables back to the server
Here is a pretty good example of beginning MVC: http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-mvc4/intro-to-aspnet-mvc-4

Related

ASP.NET MVC5 Html.Beginform not calling action method

I had my submit form working from my razor file to a controller, then from the controller to my remote database. but now i don't even think the controller class is being called.
Here is my view:
#model InputEvent
#using (Html.BeginForm("Save", "Portal/Controllers/MyEvent"))
{
<md-input-container class="md-block" flex-gt-xs="">
<label>Title</label>
#Html.TextBoxFor(m => m.title)
</md-input-container>
<md-input-container class="md-block">
<label>Address</label>
#Html.TextBoxFor(m => m.address)
</md-input-container>
<md-button class="md-raised">
<input type="submit" value="Save" />
</md-button>
}
with my model:
public class InputEvent
{
public string title;
public string address;
}
And my controller with the database connection:
namespace Portal.Controllers
{
public class MyEventController : Controller
{
[HttpPost]
public ActionResult Save(InputEvent y)
{
MySqlConnection conn = new MySqlConnection("mydbstring");
string myTitle = y.title;
string myAddress = y.address;
conn.Open();
MySql.Data.MySqlClient.MySqlCommand comm = conn.CreateCommand();
comm.CommandText = "INSERT INTO event(title, address) VALUES(#title, #address)";
//comm.Parameters.AddWithValue("#title", myTitle);
//comm.Parameters.AddWithValue("#address", myAddress);
comm.Parameters.AddWithValue("#title", "test_title");
comm.Parameters.AddWithValue("#address", "test_address");
comm.ExecuteNonQuery();
conn.Close();
return View();
}
}
}
Am i not calling my controller correctly? or is my sql command invalid?
EDIT: I just checked my database again over an hour later, and i have multiple rows with "test_title" and "test_address" in there. i guess my code works, but it is VERY delayed. This might not be the best place to ask, but does anyone have any idea why it could be so delayed inserting into the DB?
Ensure the server-side code looks like the code below. Note the [HttpPost] attribute. While the default for client-side form is Post, HttpGet is the default for the server-side. So you would have to explicitly say you want a HttpPost on the server-side. Do the following steps. Note Save method has two overloads and also one with HttpGet and the other with HttpPost. When you are done, put a break point on the method with the HttpPost attribute and post the form. You will see that the model will be hydrated.
Step 1
#using (Html.BeginForm("Save", "MyEvent", FormMethod.Post))
{
<md-input-container class="md-block" flex-gt-xs="">
<label>Title</label>
#Html.TextBoxFor(m => m.title)
</md-input-container>
<md-input-container class="md-block">
<label>Address</label>
#Html.TextBoxFor(m => m.address)
</md-input-container>
<md-button class="md-raised">
<input type="submit" value="Save" />
</md-button>
}
Step 2
public class MyEventController : Controller
{
[HttpPost]
public ActionResult Save(InputEvent model)
{
// Consider refining the implementation to use Stored Procedures or an ORM e.g. Entity Framework.
// It helps secure your app. Application security advice.
MySqlConnection conn = new MySqlConnection("mydbstring");
conn.Open();
MySql.Data.MySqlClient.MySqlCommand comm = conn.CreateCommand();
comm.CommandText = "INSERT INTO event(title, address) VALUES(" + model.title + "," + model.address + ")";
comm.ExecuteNonQuery();
conn.Close();
return View();
}
[HttpGet]
public ActionResult Save()
{
return View();
}
}
Add the FormMethod.Post as a third parameter... your action method is specting a Post and not a Get.
#using (Html.BeginForm("Save", "MyEvent", FormMethod.Post)){
....
}
I see that your code is working now. However, you should not be returning a view from a POST method the way you are. You should use PRG pattern. Read that link so you are aware of the issues your code can cause. I know that is for MVC 4 but the pattern is the same regardless of the version of MVC.

Get Length of String using Jquery on MVC 4 ASP .NET

I made a simple form where you write a string, and then print it on another view, but now i have to check the length of the string(using jquery) and print it on a Jquery UI dialog, already looked for some tutorials but im new to this MVC4 ASP .Net so its a little bit confusing to use jquery(which I have to) on this framework.
Here is the view of the form:
#{
ViewBag.Title = "Página principal";
}
<h3>Formulario</h3>
#using (Html.BeginForm())
{
#Html.Label("Escribe lo que quieras")<br />
#Html.TextArea("text")<br />
<button type="submit">Enviar</button>
}
Here is the view where i print the string i got from the first view:
#{
ViewBag.Title = "Hola, Escribiste: ";
}
<hgroup class="title">
<h1>#ViewBag.Title</h1>
<h2>#ViewBag.Message</h2>
</hgroup>
<script type="text/javascript">
var myLength = $("#text").val().length;
</script>
And here is the controller:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MvcApplication10.Controllers
{
public class HomeController : Controller
{
[HttpGet]
public ActionResult Index()
{
ViewBag.Message = "Modifique esta plantilla para poner en marcha su aplicación ASP.NET MVC.";
return View();
}
[HttpPost]
public ActionResult Index(string text)
{
TempData["Text"] = text;
return RedirectToAction("About", "Home");
}
public ActionResult About()
{
ViewBag.Message = TempData["Text"];
return View();
}
public ActionResult Contact()
{
ViewBag.Message = "Página de contacto.";
return View();
}
}
}
Please help me!
It's important to bear in mind that jQuery (and jQuery UI) are client-side technologies. That code runs in the user's browser. ASP.Net MVC is a server-side technology. That code runs on your server, and creates the HTML and JavaScript that is delivered to the browser.
You seem to be off to a reasonable start. You are outputting JavaScript code that will run in the browser and set the length of the string in a JavaScript variable
var myLength = $("#text").val().length;
Now, you need to add some additional code to create your jQuery UI dialog. You put that JavaScript code in your view as well. ASP.Net will then send that code to the browser as well, where it will run.
Have a look at the examples for jQuery UI dialogs and try to incorporate that into your view
http://jqueryui.com/dialog/
Fundamentally you will have a block of HTML that describes what will appear in the dialog, e.g.:
<div id="dialog" title="Basic dialog">
<p>The length of the string is: <span id='len'>RESULT HERE</span></p>
</div>
and will "convert" that block into the dialog using a call like:
<script>
$(function() {
$( "#dialog" ).dialog();
});
</script>
The only trick now is to update the text in that dialog to show the length of the string. There are many ways to accomplish that. One way is to have an HTML element as a placeholder for that value, and set the text of that element using jQuery:
$('#len').text(myLength);

redirect to different view after loading partial view in Main view

I dint find answers to this and tried several ways. any help would be appreciated thanks !!
I have view which updates the page without reloading on each click using ajax scripts. Below is the code. but after entire partial views are generated, I want user to redirect complete different view on clicking a link which is not associated to controller user is in now.
my View
#model IMONLP.Models.Search
#{
ViewBag.Title = "Search";
}
<script src="~/Scripts/jquery-1.8.2.min.js"></script>
<script src="~/Scripts/jquery.unobtrusive-ajax.js"></script>
#using (Ajax.BeginForm("Search", new AjaxOptions() { UpdateTargetId = "results"
}))
{
<br />
#Html.TextBoxFor(m => m.search_text, new { style = "width: 200px;" })
<input type="submit" value="search" />
}
#Ajax.ActionLink("Try Demo", "PLNHK", "PLNHK", new AjaxOptions { })
// this ajax link should redirect to different view,
<div id="results">
#if (!String.IsNullOrEmpty(#Model.search_text))
{
Html.RenderPartial("Searchprocess", Model);
}
</div>
My controller:
public ActionResult Search(Search s)
{
//do something
return PartialView("Searchprocess", s);
}
public ActionResult Selected(Search s)
{
//DO something
return PartialView("Selected", s);
}
The above "TryDEMO" "PLNHK" ajax action link will have to be redirected to new controller and new action and return view thats returned by that action. everytime I click on that, I found it moving to that controller and then to corresponding view but again its getting back to old page. I used #html.actionlink instead of Ajax, but now I get this error
The "RenderBody" method has not been called for layout page "~/Views/PLNHK/PLNHK.cshtml".
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
EDIT : I did create PLNHK.cshtml. while I'm trying to debug this, the control goes to PLNHK controller then to PLNHK view(PLNHK.cshtml) parses each and every step in that page, but finally I would get the output to be the older page. I was thinking may be the Ajax scripts on before page is the reason.

New to ASP.NET MVC, having trouble with render action containing a form

I am used to ASP.NET web forms, and am slowly learning ASP.NET MVC.
My website has a little login form on the homepage. My natural thought is that this login form may be useful in other places, and it is not the primary action of the homepage, so I want to separate it off into a partial view. And because it is related to accounts, I want the login in my AccountController not my HomepageController.
Login form is a pretty basic strongly typed partial view:
#model Models.Account.AccountLogin
<h2>Login Form</h2>
#using (Html.BeginForm("_Login", "Account")) {
#Html.ValidationSummary()
<div>
<span>Email address:</span>
#Html.TextBoxFor(x => x.EmailAddress)
</div>
<div>
<span>Password:</span>
#Html.PasswordFor(x => x.Password)
</div>
<div>
<span>Remember me?</span>
#Html.CheckBoxFor(x => x.RememberMe)
</div>
<input type="submit" value="Log In" />
}
</div>
On the homepage, I have this:
#Html.Action("_Login", "Account")
Finally, in the account controller, this:
[HttpGet]
public PartialViewResult _Login()
{
return PartialView();
}
[HttpPost]
public PartialViewResult _Login(AccountLogin loginDetails)
{
// Do something with this
return PartialView();
}
Now when I load my homepage, it looks OK and contains the form. When I click the Log In button, it takes me to myurl/Account/_Login, which contains the form, but not within the _Layout master page, just basic plain HTML and it doesn't do anything at all when I click Log In.
I am pretty sure that I have just missed some fundamental aspect of what I am supposed to be doing here, can someone please point me in the right direction?
It's because you're returning a partial view, which strips away the master page and just returns the main content. Often actions starting with an underscore are used for partials (e.g. ajaxing in a bit of a page, but not the full page). It sounds like you want a full action, and not a partial, so
[HttpPost]
public ActionResult Login(AccountLogin loginDetails)
{
// Do something with this
return View();
}
The issue here is that you are doing a fullpage postback.
You have two options, really.
Firstly, you can use a full page postback, and then call Html.Partial to display your Partial.
Something like
[HttpGet]
public ActionResult Login()
{
return View();//this typically returns the view found at Account/Index.cshtml
}
And then create a View along the lines of
#{
ViewBag.Title = "Index";
}
<h2>Title</h2>
#Html.Partial("PartialNameGoesHere")
Your partial is then rendered where indicated, but this is done when the page loads (if you look at the generated HTML, it appears exactly as though you had written it inline).
Or you can use jQuery/AJAX to load the partial on demand. Let's say you have a homepage of some description
public ActionResult Home()
{
return View();
}
public ActionResult Login()
{
return PartialView("_Login");
}
Create the view
#{
ViewBag.Title = "Index";
}
<h2>Home</h2>
<div>
<p>Hey welcome to my pretty awesome page!</p>
</div>
Show me the login!
<div id="container">
</div>
You can then load the PartialView into the container div whenever you need it, using some JS.
$(function() {
$('.my-login-link').click(function() {
$.ajax({
url: 'account/login',
success: function(data) {
$('#container').html(data);
}
});
return false;//cancel default action
});
});
In that instance, the page loads as normal without the login part. When the user clicks the link, the Login on the controller Account is called using AJAX/jQuery. This returns the HTML of the PartialView, which you can then add to the page using jQuery in the Success handler.

How to fix Child actions are not allowed to perform redirect actions, other answers does not fix

ASP.NET MVC2 view:
<%# Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MvcMusicStore.ViewModels.PaymentViewModel>" %>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
...
<form action="<%= Html.Action("PaymentByBankTransfer", "Checkout") %>" >
<input type="submit" value="Payment by bank transfer" />
</form>
CheckoutController:
public ActionResult PaymentByBankTransfer()
{
var order = Session["Order"] as Order;
ExecCommand(#"update dok set confirmed=true where order={0}", order.OrderId);
return CheckoutCompleteOK();
var cart = ShoppingCart.GetCart(HttpContext);
cart.EmptyCart();
// https://stackoverflow.com/questions/1538523/how-to-get-an-asp-net-mvc-ajax-response-to-redirect-to-new-page-instead-of-inser?lq=1
return JavaScript("window.location = '/Checkout/CompleteOK'");
}
// common method called from other controller methods also
public ActionResult CheckoutCompleteOK()
{
var cart = ShoppingCart.GetCart(HttpContext);
cart.EmptyCart();
// prevent duplicate submit if user presses F5
return RedirectToAction("Complete");
}
public ActionResult Complete()
{
var order = Session["Order"] as Order;
SendConfirmation(order);
return View("PaymentComplete", order);
}
pressing form submit button causes exception
Child actions are not allowed to perform redirect actions
As code shows most upvoted answer from
How to get an ASP.NET MVC Ajax response to redirect to new page instead of inserting view into UpdateTargetId?
is tried to fix it, but this causes other error: browser tries to open url window.location = '/Checkout/CompleteOK'
How to fix this exception? Everything looks OK, there is no partial views as described in other answers.
I tried als o to use method='post' attribute in form but problem persists.
Instead of Calling public ActionResult CheckoutCompleteOK() on post, remove that action and Create a HTTP Post Action for public ActionResult PaymentByBankTransfer().
Then return RedirectToAction("Complete"); in PaymentByBankTransfer post method.
I think this would solve your problem.
Without using javascript for redirect:
If you put forms inside your child view,Sometimes if you specify action name and controller name in Beginform helper(inside child view), this problem doesn't happen. for example I changed my child action view like this :
Before :
#using (Html.BeginForm())
{
...
}
After :
#using (Html.BeginForm("InsertComment", "Comments", FormMethod.Post, new { id = "commentform" }))
{
...
}
Now, You can put RedirectAction command inside "InsertComment" action and everything will work.

Categories