How to bind part of form values to model in asp.net webform - asp.net

I inherited an asp.net webform application. Now when I try to add new feature to it. I hit the following stop:
I created a form to get data from end user, and the data goes into two tables in the database.
I used Entity Framework to deal with communication with database.
My question is, because the form data need to go into two models(two tables), can I bind one model to part of the form data?
Or there is no way to do that, I have to go through each and every form data and assign them to the model properties?
for example
data model would be
class ModelA{
public int ModelAID {get;set;}
public string ModelAName {get;set;}
}
class ModelB{
public int ModelBID {get;set;}
public string ModelBName{get;set;}
}
front end page would be
<form>
<input name="Aid"/>
<input name="AName"/>
<input name="Bid"/>
<input name="BName"/>
</form>
code behide would be

What kind of version are you using?
I'm developing in web forms 4.5, and I have suffered with the similar problem.
The short answer is.. kinda difficult but you can do it with some restrictions.
For data binding, I'm not sure what you mean..
if you want to just bring the data, or you want to update and delete the data as well.
For me, I am using gridview everywhere to show the data and also to update, delete it, and in my experience, updating and delete is possible for one table.
But you could show other table's data by showing it in ItemTemplate.
Here is a short example of what i did :
<asp:GridView runat="server" ItemType="model"
ID="someGrid" SelectMethod="someGrid_GetData" CellPadding ="10"
autoGenerateColumns="false" deleteMethod="someGrid_DeleteItem"
updateMethod="someGrid_UpdateItem" DataKeyNames="id"
AutoGenerateDeleteButton="true" AutoGenerateEditButton="true">
<Columns>
<asp:DynamicField DataField="col1" />
<asp:BoundField DataField="col2" HeaderText="col2" />
<asp:TemplateField HeaderText="details">
<ItemTemplate>
<asp:HyperLink ID="detailLink" runat="server" Text="details" NavigateUrl='<%# "~/someDetails?some=" + Eval("someDetails") %>'></asp:HyperLink>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="vendor">
<ItemTemplate>
<asp:Label ID="vendorLbl" runat="server"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
as you can see, you could update, delete the data from model table, but you can also put data inside vendor as a label from the code behind.
I've spent many time figuring about this.
And hope this helps!

Related

Asp.net gridview edit without editbutton

I have regular asp.net gridview,and i want to enable editmode in each row,and also without editbutton (like excel grid).
Edited data i want to save to my database by clicking "Post" button outside the grid(one button for whole grid).
How can i reach it?
To achieve this, you are going to have to use ItemTemplates for each column with textboxes in them as the control..
ASP
<asp:TemplateField HeaderText="Heading Title" SortExpression="Heading Title">
<ItemTemplate>
<asp:TextBox ID="tbTextbox" runat="server" Width="65px" Text='<%# Bind("ColumnNameYouWantToView") %>'></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
After this is set up properly, you will want the post button. You can either put it in the grid or outside the grid. I use both, but here is the one inside the grid as a footer.
ASP
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="btnView" runat="server" Text="View" OnClick="btnView_Click" Width="40px" />
</ItemTemplate>
<FooterTemplate>
<asp:Button ValidationGroup="UPDATE" ID="btnUpdate" OnClick="btnUpdate_Click" runat="server" Text="Update" Width="50px"></asp:Button>
</FooterTemplate>
<FooterStyle HorizontalAlign="Center" VerticalAlign="Middle" Width="50px" />
</asp:TemplateField>
So far, what I have found that works best is using a foreach statement in your button click. The biggest flaw with this idea is that it will update every single row. It works, but if you only change a single row at a time, it will update all of them. I have my pager set to 10, so 10 rows are always updated (unless you are just searching for a single record and update it, the only that single record is updated).
Code Behind C#
protected void btnUpdate_Click(object sender, EventArgs e)
{
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["databaseConnection"].ConnectionString);
conn.Open();
//finds the controls within the gridview and updates them
foreach (GridViewRow gvr in gvGridViewName.Rows)
{
string ID = (gvr.FindControl("lblId") as Label).Text.Trim();//finds the control in the gridview
string anotherControl = ((TextBox)gvr.FindControl("tbTextBox")).Text.Trim();//finds the textbox in the gridview
//Your update or insert statements
}
This is how I do it. You can also look into Real World Grids but I haven't had much luck with this as I would always get an error if a textbox was empty. This however, is suppose to be "smart" enough to just update the rows that have been changed, but again, I didn't have much luck of doing it this way. Hope this helps!

Getting the bound type of templated column controls in gridView

Hi I have following grid view
<asp:GridView ID="grdSettings" runat="server" Height="400px" Width="100%"
AutoGenerateColumns="false" >
<Columns>
<asp:TemplateField HeaderText="XYZ" BoundFieldName="XYZTypeName">
<ItemTemplate>
<asp:Label ID="lblCustomerName" runat="server" Text='<%# Bind("CustomerName") %>'>
</asp:Label>
<asp:Label ID="lblCostumerId" runat="server" Text='<%#Bind("CustomerId") %>'></asp:Label>
</asp:TemplateField>
</Columns>
</asp:GridView>
Which is bound by List of Customer ,class is as follows
Class Customer
{
public string CustomerName { get; set; }
public int CustomerId { get; set; }
}
Now on a method named GetGridStuff() , i need to iterate in every column and get the type that was bound to controls in template field. For example in case of the first control in the template field
<asp:Label ID="lblCustomerName" runat="server" Text='<%# Bind("CustomerName") %>' >
</asp:Label>
I need to know what type of property data it contains , in this case its CustomerName. I need to get this dynamically at run time as to write code in part of program which is not aware if this grid structure. I have the grid object with me and i can access all properties.
Let me try this, being away from coding for more than 5 years now and if I understand the problem correctly as you may want to handle it through server side code.
Look for an event called ItemBound (or similar forgive me for my memory), this gives you values of all the items in current row (Properties). You also need to declare temp control types (label,textbox etc) and assign corresponding value to these controls using e.FindControl with appropriate type casting, e.g. Label l = (Label)e.Findcontrol("Name")
downside of the approach you should avoid too much of process as it is going to execute on every row creating of the grid.
Let me know if you still want a precise code to handle the problem but otherwise this description should at least help you to look for Row Level Event to crack the prob and also encourage you to stick to tech forums :)

Dynamic Data - Selecting a table from a DropDownList to scaffold in a GridView

I have been struggling with this ASP.NET Dynamic Data problem for days now... I have a DropDownList containing the table names of all the tables in my data context (.dbml) file. When I select the DropDownList, it needs to scaffold the selected table in a GridView. My code works 100% in scaffolding the MetaTable in the GridView (it implements all the rules that I applied in my Meta Classes).
However, filtering only seems to work if I explicitly add the DynamicExpression in the declaration of the QueryExtender:
<asp:QueryExtender ID="GridQueryExtender" TargetControlID="GridDataSource" runat="server">
<asp:DynamicFilterExpression ControlID="FilterRepeater" />
</asp:QueryExtender>
This in turn requires me to specify the MetaTable explicitly in the LinqDataSource (linqdsData), either programmatically in the Page_Load or in the ASP.NET syntax.
Since the GridView gets scaffolded in the Page_Load part of the life-cycle, the above approach does not work for me, since it takes place in the Page_Init part of the life-cycle.
So my requirement is that as soon as I select another table to populate the GridView with from the DropDownList, the FilterRepeater needs to reflect the filters of the newly selected MetaTable.
Is there any way for me to programmatically update the FilterRepeater in the Page_Load so that it will contain the filters of the MetaTable that I selected in the DropDownList.
The following is some of my code:
ASP.NET Page Code-Behind:
protected void Page_Load(object sender, EventArgs e)
{
if (ddlTable.SelectedIndex > 0)
{
string tableName = ddlDataType.SelectedValue;
linqdsData.TableName = tableName;
MetaTable mt = ASP.global_asax.DefaultModel.GetTable(tableName);
GridViewData.SetMetaTable(mt, mt.GetColumnValuesFromRoute(Context));
GridViewData.EnableDynamicData(mt.EntityType);
GridViewData.DataSourceID = linqdsData.ID;
}
}
ASP.NET Page:
<asp:Panel runat="server" ID="pnlFilters" CssClass="gridFilterCon" EnableTheming="True">
<div class="filterGridHeading">
Filter the grid by:</div>
<asp:QueryableFilterRepeater runat="server" ID="FilterRepeater">
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Eval("DisplayName") %>' OnPreRender="Label_PreRender"
CssClass="gridFilterLbl" />
<asp:DynamicFilter runat="server" ID="DynamicFilter" />
<br />
</ItemTemplate>
</asp:QueryableFilterRepeater>
<asp:Button ID="btnFilter" runat="server" Text="OK"
EnableTheming="False" UseSubmitBehavior="False" OnClick="btnFilter_Click" />
</asp:Panel>
<asp:GridView ID="GridViewData" runat="server" OnSelectedIndexChanged="GridViewData_SelectedIndexChanged"
OnPreRender="GridViewData_PreRender" OnRowDataBound="GridViewData_RowDataBound"
OnPageIndexChanged="GridViewData_PageIndexChanged" AllowPaging="True" PageSize="50" OnInit="GridViewData_Init">
<Columns>
...
</Columns>
<PagerTemplate>
<asp:GridViewPager ID="GridViewPager1" runat="server" />
</PagerTemplate>
<PagerSettings Mode="NumericFirstLast" NextPageText="Next" />
</asp:GridView>
<asp:LinqDataSource ID="linqdsData" runat="server" ContextTypeName="pdcDataContext"
OnSelected="linqdsData_Selected" OnSelecting="linqdsData_Selecting" EnableUpdate="True">
</asp:LinqDataSource>
<asp:QueryExtender ID="GridQueryExtender" TargetControlID="linqdsData" runat="server">
</asp:QueryExtender>
Your help will be greatly appreciated.
It sounds like you are trying to do a lot on one web page. This creates complications of the type you are experiencing: each table requires distinct filters and MetaTables. Trying to keep each item straight requires a bunch of switch and/or if...then statements. I recommend an alternate approach. Instead of doing all of this on one page:
Create a web page for each table
Setup the appropriate filters and MetaTables
Copy the DropDownList containing the table names of all the tables to each web page, and use it to redirect to the appropriate web page.
ASP.net Dynamic Data makes it easy to create web pages for each table. That is what scaffolding is all about. With the approach above, each web page will handle its own set of concerns that are focused on the particular table.
Hope this helps.

Eval() in ASP. How to pass values on redirect

<asp:GridView ID="GridView1" runat="server" CssClass="style29">
<Columns>
<asp:TemplateField HeaderText="Send Message to Group">
<ItemTemplate>
<asp:LinkButton ID="LinkButton2" runat="server" PostBackUrl='SendMessage.aspx?GroupName=<%# Eval("GroupName") %>' Text='Send Message'></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
I am redirecting the to SendMessage.ASPX page which has a text box, I have to pass the group name to that text box. Please help me guys I am new to programming. It gets redirected but how to pass that value to this text box below in SendMessage.aspx page.
Sorry I may have misunderstood your question, however the common pattern involves the query string
You can access the query string values as
if (String.IsNullOrEmpty(HttpContext.Current.Request.QueryString["GroupID"]) == false) {
String groupId = HttpContext.Current.Request.QueryString["GroupID"];
}
you would then be able to set this value to the textbox.Text property in your page load event, which will apply the value from the query string to the textbox.
Generally, you want to check for null or empty strings before attempting to access the query string.
Also, always remember that this kind of action is often a target for malicious users to do malicous things with your website, so you must check inputs to ensure 'bad' inputs are ignored.

How do I data bind a drop down list in a gridview from a database table using VB?

So in this gridview, there is a column for status and I want to have a drop down list with Pass, Pending, Fail appear when the edit button is clicked. These values are already in a table, so I need to somehow bind from this table to each ddl for every row.
Here is the column from the gridview. As you can see, I would like to just have a label showing when not in edit mode, and a ddl when the edit button is pressed
<asp:TemplateField HeaderText="During Production Status" SortExpression="DuringProductionStatus">
<EditItemTemplate>
<asp:DropDownList ID="ddlStatus" runat="server" datavaluefield="Name"
datatextfield="Name" DataSource="*What goes here?*"> />
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="lblStatus" runat="server"
Text='I don't understand how to get this from the ddl' />
</ItemTemplate>
</asp:TemplateField>
For clarity's sake, my table is named Status, and the database is named DirectImport
There's a few steps to go through here - none of them are particularly difficult, but they can be a bit fiddly (IMHO). The good news is once you've got this working once, it gets easier to do it again!
I'm assuming you've got a <asp:*DataSource> control on your page - my preference is for an ObjectDataSource but I don't think it matters, I think a SqlDataSource works equally well. I've never tried doing this with GridView.DataSource = MyDataSet in code-behind, so I don't know whether that would work or not, but my assumption is that it wouldn't as you wouldn't get the proper two-way binding that you want. This data source feeds your grid with your main data. The key point here is that your database query must return both the Status text field and the Status id.
So your gridview will now look something like:
<asp:objectdatasource runat="server" id="MainDataSource" ... />
<asp:gridview runat="server" id="MyGridView" DataSourceID="MainDataSource">
<Columns>
<asp:TemplateField HeaderText="During Production Status" SortExpression="DuringProductionStatus">
<ItemTemplate>
<asp:Label ID="lblStatus" runat="server"
Text="<%# Bind('Status') %>" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:gridview>
The Text="<%# Bind('Status') %>" is the bit you're missing to get the status text into the grid.
Now add a second data source into your markup that reads in the set of values from the Status table.
<asp:objectdatasource runat="server" id="StatusObjectDataSource" ... />
And add the EditItemTemplate into the GridView, which is bound to the Status DataSource.
<EditItemTemplate>
<asp:DropDownList ID="ddlStatus" runat="server" datavaluefield="StatusID"
datatextfield="Status" DataSourceID="StatusObjectDataSource"
SelectedValue="<%# Bind('StatusId') %>" />
</EditItemTemplate>
The SelectedValue="<%# Bind('StatusId') %>" is what connects up the two datasets so that when you flip a row into Edit mode, the dropdownlist has the correct item already selected, and when you then save it you've got the Status ID to put into your database.
And you're done.
I have used the RowDataBound event. Here is a small code snippet. HTH
you would have an ItemTemplate in your aspx/ascx
<asp:TemplateField HeaderText="Column Headings">
<ItemTemplate>
<asp:DropDownList ID="ddlName" runat="server" Width="150"></asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
and in your code behind, you will have
protected void grdDataMap_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DropDownList ddl = (DropDownList)e.Row.FindControl("ddlName");
ddl.DataSource = someList;//the source of your dropdown
ddl.DataBind();
}
}
so when you bind your grid with grdDataMap.Databind (assuming your grid id is grdDataMap), row databound event will be called for each row (including header/footer, and thats the reason you check RowType)
so you can probably decide what controls/columns to hide/show/bind inside this row databound event
In the winforms world I pull my objects from the DB into a List(Of Whatever) and use the list as the datasource.
This also lets me add extra "convenience" fields in the object so that I can populate it with stuff from other tables.
I don't know asp.net at all so if you can do something similar, it might help.
A really quick solution is to create a custom web control for the status dropdown. The control will always contain the same data. When it renders you populate the datasource. When it gets added to the gridview, the data will be in the drop down. Hope that helps!

Resources