Convert simple ASP.NET WebForm to MVC - asp.net-mvc

I have simple asp.net page:
using System;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
rptTable.DataSource = GetDataFromDB();
rptTable.DataBind();
}
}
private DataTable GetDataFromDB()
{
DataTable table = new DataTable();
table.Columns.Add("Id", typeof(int));
table.Columns.Add("Name", typeof(string));
table.Rows.Add(1, "HDD");
table.Rows.Add(2, "Video");
table.Rows.Add(3, "RAM");
return table;
}
protected void rptTable_ItemCommand(object source, RepeaterCommandEventArgs e)
{
TextBox tbName = (TextBox)e.Item.FindControl("tbName");
int id = Convert.ToInt32(e.CommandArgument);
string name = tbName.Text;
//Category.Save(int id, string name)
//Rebuild Repeater
}
}
and aspx code:
<%# Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" EnableEventValidation="false" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<table>
<asp:Repeater ID="rptTable" runat="server" OnItemCommand="rptTable_ItemCommand">
<ItemTemplate>
<tr>
<td>
<%#Eval("id")%>
</td>
<td>
<asp:TextBox ID="tbName" runat="server" Text='<%#Eval("Name")%>'></asp:TextBox>
</td>
<td>
<asp:Button ID="btnSave" runat="server" Text="Save" CommandArgument='<%#Eval("id")%>' />
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
</table>
</div>
</form>
</body>
</html>
It works like simple grid and you are able to edit data directly in the grid.
How can I implement same logic in MVC ?
Thanks!

To replicate the asp:Repeater functionality in an MVC application you would normally use a foreach loop with textboxes within bound to model properties.
You can however if you really want, include an asp:repeater control in an MVC app, but it's not going to work as you'd expect if it relies on postbacks.
If it's a simple read only control, you can put something like the following in your view:
<scipt runat="server">
protected void Page_Load(object sender, EventArgs e) {
rptTable.DataSource = ViewData["yourViewDataList"];
rptTable.DataBind();
}
</script>
This assumes you've got something in the ViewData which can be databound, so to do that you'd likley need to create a controller method to build your DataTable as you've done in 'GetDataFromDB()'
I'm not going to go into the full implementation but at a high level, that's how you could use the control in MVC.

Related

Nothing happens and no errors binding data from sql server to textbox

Im trying tot start with a easy setup. I try to get de data into textboxes and start with the first step. For some reason I can't bind the data to the textbox and don't received any errors. Programming is running fine, but nothing is happening when I press the button.
I tested with gridview to check the connection and that seems to be working.
I'm using MS SQL Server 2016 Express version, visual studio 2017, ASP and C#
What do I wrong? Wrong code? Connection blocked by the server?
.........................
ASPX code:
<%# Page Language="C#" AutoEventWireup="true" CodeFile="test3.aspx.cs" Inherits="test3" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:TextBox ID="TextBox1" runat="server" Width="281px"></asp:TextBox>
<asp:Button ID="Button1" runat="server" Text="Start" />
</div>
</form>
</body>
</html>
.............................
The CS code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data.SqlClient;
using System.Configuration;
public partial class test3 : System.Web.UI.Page
{
public SqlConnection conn = new SqlConnection(#"Data Source=.\WDVEXPRESS;Initial Catalog=user;User ID=testaccount;Password=123test");
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button1_Click(object sender, EventArgs e)
{
SqlCommand com;
string str;
conn.Open();
str = "select * from Company$ where Name = 'testuser'";
com = new SqlCommand(str, conn);
SqlDataReader reader = com.ExecuteReader();
if (reader.Read())
{
TextBox1.Text = reader["Name"].ToString();
reader.Close();
conn.Close();
}
}
}
.......................
Many thanks for the help!
Your button on aspx page is not bound to button click event on aspx.cs page. Check below code it will tell you how they got bounded -
HTML ( ASPX PAGE ) CODE
<asp:Button ID="Button1" runat="server" Text="Start" OnClick="Button1_Click" />
CS CODE
protected void Button1_Click(object sender, EventArgs e)
{
//Your Click Event Here
}

Why won't the ASP.NET Webform LinkButton in my MVC project invoke its code-behind OnClick event handler?

I have a previously operational webforms project I had to include in a preexistent MVC-based solution and in it there's a LinkButton control inside a form that is now only partially working; its JavaScript event handler works perfectly fine (referenced below by OnClientClick) but the C# code-behind (lnkSubmit_Click) isn't being invoked! Why not?
My LinkButton's inside Pay.aspx:
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="Pay.aspx.cs" Inherits="PayUp.Pay" MasterPageFile="~/Views/Shared/Site.Master" %>
<form id="form1" runat="server" onsubmit="return validateForm();" defaultbutton="lnkSubmit" action="~/Views/Home/Pay.aspx" method="post" >
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<div align="center">
<script type="text/javascript">
window.onload = function () {
hideFields();
};
</script>
<asp:UpdatePanel runat="server" id="PendingPayments1">
<ContentTemplate>
<!-- Valid form controls, blah blah.... -->
</ContentTemplate>
</asp:UpdatePanel>
<asp:Label ID="labelPayPlan" runat="server" Text="Pay Plan">
</asp:Label>
<asp:HiddenField ID="hiddenPDFForm" Value="false" runat="server" ClientIDMode="Static" />
<asp:UpdatePanel runat="server" id="PaymentInformation1">
<ContentTemplate>
<asp:LinkButton ID="lnkSubmit" runat="server" EnableViewState="false" OnClientClick="javascript: document.getElementById('hiddenPDFForm').value = 'false';"
CssClass="button" onclick="lnkSubmit_Click" onserverclick="lnkSubmit_Click" ClientIDMode="Static">Pay Up!<img alt='Pay Up!' src='images/pay.gif' style='border:0px; margin-left:6px;' />
</asp:LinkButton>
</ContentTemplate>
</asp:UpdatePanel>
</form >
The code-behind does exist inside Pay.aspx.cs:
using System;
using System.Web;
using System.Web.UI.WebControls;
using System.Configuration;
using SupportingMVCProject;
using System.Web.Mvc;
namespace PayUp
{
public partial class Pay : System.Web.Mvc.ViewPage<SupportingMVCProject.Account>
{
protected void Page_Load(object sender, EventArgs e)
{
// The code in this event handler runs just fine when I start the project!
// This code successfully receives and correctly parses my URL parameters (QN, PN, AC).
}
protected void lnkSubmit_Click(object sender, EventArgs e)
{
// The code in this event handler never gets to run!
}
}
}
My RouteConfig.cs looks like:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web.Http;
namespace MainMVCProject
{
public static class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.IgnoreRoute("{WebForm}.aspx/{*pathInfo}");
routes.MapRoute("PayUpIndex", "SupportingMVCProject/PayUp",
new { controller = "PayUp", action = "Index" }
);
// Other valid preexisting MVC routes...
// blah, blah
}
}
}
The PayUpController.cs PayUpIndex route identified above looks like the following, and it does run:
public ActionResult Index(string QN, string PN, string AC)
{
string result = "";
if (!AccessValidation(PN, out result))
{
return RedirectToAction(result);
}
// blah blah
ViewData["message"] = "QN=" + QN + "PN=" + PN + "AC=" + AC;
return this.View("~/Views/PayUp/Pay.aspx");
}
My start URL is http://localhost:3835/SupportingMVCProject/PayUp?QN=ABC-1234567&PN=ABC1234567&AC=123456789. It launches the page just fine and all controls are interactive, all except my "Pay Up!" button (lnkSubmit). Why is lnkSubmit_Click inside Pay.aspx.cs not being invoked?
Your insight is greatly appreciated!
I am pretty sure I have read somewhere that if you use OnClientClick then server side code will not run unless you make some changes
Check out the below link
OnclientClick and OnClick is not working at the same time?

What is the MVC equivalent of Find Control?

In ASP.NET web forms it is possible to modify page controls from the master page. For example, on a page "/Sample" I could set TextBox1 as readonly by doing the following.
//Site.master.cs
protected void Page_Load(object sender, EventArgs e)
{
if (Request.Path.ToUpper().Contains("/SAMPLE"))
{
TextBox TB = MainContent.FindControl("TextBox1") as TextBox;
TB.ReadOnly = true;
}
}
The question is... Is there an equivalent way to do this in an MVC application that uses a SiteLayout?
Background: We have purchased an MVC application and have access to modify the
source code. We need to customize the behaviors on some of the pages. It
will only be used by a few dozen people so a performance hit won't really be noticeable. If this was a Web Forms
application we would use the above method. However this application
is written with MVC and it is making our web form programmer (me) confused on how best to proceed. Customizing numerous pages is going to be a headache when
we have to patch the software. Having all the changes in one central location
would be easier to manage going forward. How can you have one place where you can customize other pages programmatically in MVC?
There is no MVC equivalent for FindControl, since views are built in a single operation, where ASP.NET controls are built up and modified over several different events. You don't need to find the control, you specify all of its attributes as it is built.
The rough equivalent to an ASP.NET control (at least in this context) is an HTML helper. HTML helpers are implemented as static extension methods, which allows them to be shared between views and perform some actions as the view is loaded.
using System.Web.Mvc;
using System.Web.Mvc.Html;
public static class MyExtensions
{
public static MvcHtmlString TextBox1(this HtmlHelper helper, string name)
{
if (helper.ViewContext.HttpContext.Request.Path.ToUpper().Contains("/SAMPLE"))
{
return InputExtensions.TextBox(helper, name, null, new { #readonly = "readonly" });
}
return InputExtensions.TextBox(helper, name);
}
}
Usage
~/Views/Shared/_Layout.cshtml
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>#ViewBag.Title - My ASP.NET MVC Application</title>
<link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
<meta name="viewport" content="width=device-width" />
#Styles.Render("~/Content/css")
#Scripts.Render("~/bundles/modernizr")
</head>
<body>
<header>
<div class="content-wrapper">
<div class="float-left">
<p class="site-title">#Html.ActionLink("your logo here", "Index", "Home")</p>
</div>
<div class="float-right">
<section id="login">
#Html.Partial("_LoginPartial")
</section>
<nav>
<ul id="menu">
<li>#Html.ActionLink("Home", "Index", "Home")</li>
<li>#Html.ActionLink("About", "About", "Home")</li>
<li>#Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>
</nav>
</div>
</div>
</header>
<div id="body">
#RenderSection("featured", required: false)
<section class="content-wrapper main-content clear-fix">
#* Render custom HTML Helper *#
#Html.TextBox1("test")
#RenderBody()
</section>
</div>
<footer>
<div class="content-wrapper">
<div class="float-left">
<p>© #DateTime.Now.Year - My ASP.NET MVC Application</p>
</div>
</div>
</footer>
#Scripts.Render("~/bundles/jquery")
#RenderSection("scripts", required: false)
</body>
</html>
Note that it is also possible to put the logic directly in the view, but then you cannot reuse logic in other views and it makes your view look cluttered.
As for reading the data back out of a textbox, you need to put it within a <form> tag so it can be posted to a controller action method, which is the rough equivalent of a submit button click event. Unlike ASP.NET, MVC supports multiple <form> tags so you don't have to mix your logic for different actions on the page.
Your question is very broad. But generally, if you want to provide read only rendering for your controls in your razor views based on some conditions, you can try the below approach.
You should add a IsReadOnly property to your view model and use that to render the control the way you wanted.
public class CreateCustomerVM
{
public bool IsReadOnly {set;get;}
//Other properties goes here
public string Email { set; get; }
public string Name { set; get; }
}
In your Action method set the IsReadOnly propery value based on your condition.
public ActionResult Index()
{
var vm=new CreateCustomerVM();
//Set the value based on your condition
vm.IsReadOnly=true;
return View(vm);
}
And in your view , you use the IsReadOnly property to determine whether you want to display a readonly control or not.
#model YourNameSpaceGoesHere.CreateCustomerVM
#using (Html.BeginForm())
{
#Html.TextBoxFor(m => m.Email)
if(Model.IsReadOnly)
{
#Html.TextBoxFor(m => m.Name, new { #readonly = "readonly" })
}
else
{
#Html.TextBoxFor(m => m.Name)
}
<input type="submit"/>
}

how we can add one by one row in table by using struts

I want to show data in tabular format when we click add button one by one keep adding in table . only use struts 2 not Ajax and Jquery.
home.jsp
<%# page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%# taglib prefix="s" uri="/struts-tags"%>
<%# taglib prefix="sx" uri="/struts-dojo-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
</head>
<body>
<table>
<tr>
<td><s:textfield label="Sainumber"
name="stockcreationbean.sainumber" /></td>
<td><table><tr><td><sx:datetimepicker
name="stockcreationbean.saidate" displayFormat="MM-dd-yy"
label="SaiDate" /></td></tr></table></td>
<td><s:textfield label="Challan"
name="stockcreationbean.challan"></s:textfield></td>
<td><table><tr><td><sx:datetimepicker name="stockcreationbean.challandate"
displayFormat="MM-dd-yy" label="ChallanDate"></sx:datetimepicker></td></tr></table></td>
</tr>
<tr>
<td><s:textfield label="BillNumber"
name="stockcreationbean.billnumber"></s:textfield></td>
<td><table><tr><td><sx:datetimepicker name="stockcreationbean.billdate"
displayFormat="MM-dd-yy" label="BillDate"></sx:datetimepicker></td></tr></table></td>
<td><s:textfield name="stockcreationbean.ponumber"
label="PoNumber"></s:textfield></td>
<td><table><tr><td><sx:datetimepicker name="stockcreationbean.podate"
displayFormat="MM-dd-yy" label="PoDate"></sx:datetimepicker></td></tr></table></td>
</tr><tr><td><s:textfield name="stockcreationbean.filenumber"
label="FileNumber"></s:textfield></td>
</tr>
</table>
<table>
<s:iterator value="toparraylist">
<tr>
<s:iterator value="tablelist">
<td><s:property value="saidate"/></td>
</s:iterator>
</tr>
</s:iterator>
</table>
<s:submit value="Submit" onclick="formSubmit(this.form)"></s:submit>
</body>
</html>
This is action class that we can use for adding data in array list .One is local array list and other is global array list then call getData() method when we click add button then add local arraylist object to global arraylist object
DisplayAction.java
public class DisplayAction extends ActionSupport {
ArrayList<Object> toparraylist = new ArrayList<Object>();
public String execute() {
return "success";
}
public String getData() throws NamingException, Exception {
ArrayList<Object> tablelist=new ArrayList<Object>();
tablelist.add(stockcreationbean);
toparraylist.add(tablelist);
return "success";
}
public ArrayList<Object> getToparraylist() {
return toparraylist;
}
public void setToparraylist(ArrayList<Object> toparraylist) {
this.toparraylist = toparraylist;
}
}
#Mack Struts 2 is a server-side framework for java. If I decode your requirement it tells me that you want to update something on table(at client) and it gets updated on-by-one by using struts 2(at server).
Ajax was fits your requirement perfectly and is the only solution for your requirement, as updating table is an asynchronous call to server.

Load ASP-MVC View with Ext.Panel loader

I have following layout, related to the one i am describing in this question
<ext:Viewport runat="server">
<Items>
<ext:Panel Region="North" runat="server" ID="TopBar" />
<ext:Panel Region="West" runat="server" ID="Nav" >
<Items>
<ext:Button runat="server" ID="loaderComponentFooBar">
<DirectEvents>
<Click OnEvent="loadFooBar" />
</DirectEvents>
</ext:Button>
//Some more Buttons each with his own loader Function in Code-Behind
</Items>
</ext:Panel>
<ext:Panel runat="server" Region="center" ID="MainPanel" />
</Items>
</ext:Viewport>
on Button-Click i now want to load my View # "/Foo/Bar/" to the MainPanel
How can i achieve this in CodeBehind?
I already tried:
public void loadFooBar(object sender, DirectEventArgs e)
{
MainPanel.Loader.Url = "/Foo/Bar/"; //Throws null reference Exception
MainPanel.Loader.Url = "~/Foo/Bar/"; // same as above
MainPanel.Loader.GetUrlByRoute("Foo/Bar/"); //again the same
MainPanel.Loader.LoadContent("/Foo/Bar/");
//and after each of these attempts except the last went:
MainPanel.Loader.Mode = LoadMode.Frame;
MainPanel.Loader.LoadMask.ShowMask = false;
MainPanel.Loader.LoadContent();
}
Just by the way, i am using aspx-web-application views
I think you should not use a page's code behind for DirectEvents' handlers. It is going out of the MVC concept. You should refer a controller's actions.
Here is an example.
Example View
<%# Page Language="C#" Inherits="System.Web.Mvc.ViewPage" %>
<%# Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>
<!DOCTYPE html>
<html>
<head runat="server">
<title>Ext.Net.MVC v2 Example</title>
</head>
<body>
<ext:ResourceManager runat="server" />
<ext:Viewport runat="server" Layout="BorderLayout">
<Items>
<ext:Panel runat="server" Region="West" Width="100">
<Items>
<ext:Button
runat="server"
Text="Load View 1"
DirectClickUrl=<%# Url.Action("LoadView1") %>
AutoDataBind="true" />
<ext:Button
runat="server"
Text="Load View 2"
DirectClickUrl=<%#Url.Action("LoadView2") %>
AutoDataBind="true" />
</Items>
</ext:Panel>
<ext:Panel ID="MainPanel" runat="server" Region="Center">
<Loader runat="server" Mode="Frame" AutoLoad="false">
<LoadMask ShowMask="true" />
</Loader>
</ext:Panel>
</Items>
</ext:Viewport>
</body>
</html>
Example Controller
using System.Web.Mvc;
using Ext.Net;
using Ext.Net.MVC;
namespace Work2MVC.Controllers
{
public class AspxController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult View1()
{
return View();
}
public ActionResult View2()
{
return View();
}
public ActionResult LoadView1()
{
Panel p = X.GetCmp<Panel>("MainPanel");
p.LoadContent(Url.Action("View1"));
return this.Direct();
}
public ActionResult LoadView2()
{
Panel p = X.GetCmp<Panel>("MainPanel");
p.LoadContent(Url.Action("View2"));
return this.Direct();
}
}
}
Also you can initiate a load request on client side via JavaScript. Then you avoid an additional request.

Resources