Solved

Using Required Attribute in ASP.NET

Posted on 2016-07-28
6
63 Views
Last Modified: 2016-08-01
This is some new territory for me but heres what Im trying to figure out.
I have a gridview user control Im using that accepts a Generic List(of myObj). So after I run my Populate, I end up sending my entire object to the gridview. The gridview consumes the object and builds the columns based off the object. Problem is I only want it to use certain fields when I send it. So I put the Required attribute on the fields I want to send.
My question is when I do the Populate of my object and return the object how can I filter only the object properties that have the Required Attribute?

   Public Function PopulateWorkItem() As List(Of WorkItem)
            Dim db As New DBAccess()
            db.AddParameter("@TypeID", ItemTypeID)
            Dim sdr As SqlDataReader = db.ExecuteReader("spGetWorkItemsByWeekId")
            Dim wi As New List(Of WorkItem)
            While sdr.Read
                wi.Add(New WorkItem)
                wi(wi.Count - 1).ItemID = sdr("ItemID").ToString
                wi(wi.Count - 1).WorkDate = FormatDateTime(CDate(sdr("WorkDate")), DateFormat.ShortDate)
                wi(wi.Count - 1).Name = sdr("Name").ToString
                wi(wi.Count - 1).Street = sdr("Street").ToString
            End While
          [b] 'When I return this it sends the entire object and I only want to send the properties that I have just queried[/b]
            Return wi
        End Function

Open in new window


When I set the DataSource of the grid it builds the Columns from the object I send it. So it has "al"l the properties in my object, which it doesnt need, so I am trying to use the Required attribute like this

<Required> _
    <Display(Name:="Street")> _
        Public Property Street() As String
            Get
                Return m_Street
            End Get
            Set(value As String)
                m_Street = value
            End Set
        End Property

Open in new window


So when Im doing my return after the populate how can I filter out just the "Required" fields?

Thanks for any help!!
0
Comment
Question by:jknj72
  • 4
  • 2
6 Comments
 
LVL 33

Expert Comment

by:it_saige
ID: 41733219
Filtered how?  In order to create the columns?  Don't get me wrong I understand what you mean by filtering based on the attribute, we can do this easily by using the GetCustomAttrubute method.

Example -
Imports System.ComponentModel.DataAnnotations

Module Module1
	Sub Main()
		Dim bob = New Person() With {.ID = 0, .Name = "Bob", .Address = "123 E Street", .Birthdate = New DateTime(1975, 1, 28)}
		bob.PrintRequired()
		Console.ReadLine()
	End Sub
End Module

Class Person
	<Required> _
	Public Property ID() As Integer
	<Required> _
	Public Property Name() As String
	Public Property Address() As String
	<Required> _
	Public Property Birthdate() As DateTime
	Public Property Hobbies() As List(Of String)

	Public Sub PrintRequired()
		Dim required = (From [property] In Me.GetType().GetProperties()
					 Where CType([property].GetCustomAttributes(GetType(RequiredAttribute), False), RequiredAttribute()).Count > 0
					 Select New With {.Name = [property].Name, .Value = [property].GetValue(Me, Nothing)})
		Console.WriteLine("[{0}]", String.Join("; ", required))
	End Sub
End Class

Open in new window

Which produces the following output -Capture.JPG
-saige-
0
 

Author Comment

by:jknj72
ID: 41733281
Well what I mean by Filter is when I Populate my object I pass it to a Routine that creates Columns in my GridView and I only want the fields that have the RequiredAttribute to be Columns but it goes through every property in my object instead(values or not). This is the code I am running. I will try and fit what you sent me to get the job done and let you know... Thanks for your help!

Public Shared Sub PrepareColumns(source As Object, ByVal columns As DataControlFieldCollection)
   Dim y As Integer = 0
                If columns.Count = 0 Then
                    ' at this point, the datasource must have been prepared and it must be a list
                    Dim properties = source(0).GetType.GetProperties()

                    For Each prop In properties
                        Dim name = prop.Name
                        Dim field = New BoundField()
                        With field
                            .DataField = name
                            .HeaderText = SeperateNamesWithSpace(name) 
                            .Visible = .HeaderText <> ""
                            .SortExpression = name
                            .HtmlEncode = False
                           
                        End With
                        columns.Add(field)
                    Next
End Sub

Open in new window

0
 
LVL 33

Accepted Solution

by:
it_saige earned 500 total points
ID: 41733359
Nevermind.  I get what you are after now.  I had to reread your question, gotta remember to start drinking my coffee earlier.  :)

Anyhow, here is one way you could use a Required attribute to remove columns and their values from an ASP.NET GridView.

Default.aspx -
<%@ Page Title="Home Page" Language="VB" AutoEventWireup="true" CodeBehind="Default.aspx.vb" Inherits="EE_Q28960135_Web._Default" %>
<form id="form1" runat="server">
	<asp:GridView ID="GridView1" runat="server">
	</asp:GridView>
</form>

Open in new window

Default.aspx.vb -
Imports System.ComponentModel
Imports System.ComponentModel.DataAnnotations

Public Class _Default
	Inherits Page

	ReadOnly people As New List(Of Person)(From i In Enumerable.Range(0, 10) Select New Person() With {.ID = i, .Name = String.Format("Person{0}", i), .Birthdate = New DateTime(1975, 1, 27).AddMonths(i), .Address = String.Format("12{0} E Street", i)})

	Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
		GridView1.DataSource = people
		GridView1.DataBind()
	End Sub

	Protected Sub OnRowDataBound(sender As Object, e As GridViewRowEventArgs) Handles GridView1.RowDataBound
		If e.Row.DataItem IsNot Nothing Then
			Dim grid = DirectCast(sender, GridView)
			Dim notRequired = (From [property] In e.Row.DataItem.GetType().GetProperties()
						    Where CType([property].GetCustomAttributes(GetType(RequiredAttribute), False), RequiredAttribute()).Count <= 0
						    Select e.Row.DataItem.GetType().GetProperties().ToList().IndexOf([property]))

			For Each index In notRequired
				If e.Row.Cells.Count - 1 > index Then
					e.Row.Cells(index).Visible = False
				End If

				If grid.HeaderRow.Cells.Count - 1 > index Then
					grid.HeaderRow.Cells(index).Visible = False
				End If
			Next
		End If
	End Sub
End Class

Class Person
	<Required> _
	Public Property ID() As Integer
	<Required> _
	Public Property Name() As String
	Public Property Address() As String
	<Required> _
	Public Property Birthdate() As DateTime
	Public Property Hobbies() As List(Of String)
End Class

Open in new window

Default.aspx.designer.vb -
'------------------------------------------------------------------------------
' <auto-generated>
'     This code was generated by a tool.
'
'     Changes to this file may cause incorrect behavior and will be lost if
'     the code is regenerated. 
' </auto-generated>
'------------------------------------------------------------------------------

Option Strict On
Option Explicit On


Partial Public Class _Default

	'''<summary>
	'''form1 control.
	'''</summary>
	'''<remarks>
	'''Auto-generated field.
	'''To modify move field declaration from designer file to code-behind file.
	'''</remarks>
	Protected WithEvents form1 As Global.System.Web.UI.HtmlControls.HtmlForm

	'''<summary>
	'''GridView1 control.
	'''</summary>
	'''<remarks>
	'''Auto-generated field.
	'''To modify move field declaration from designer file to code-behind file.
	'''</remarks>
	Protected WithEvents GridView1 As Global.System.Web.UI.WebControls.GridView
End Class

Open in new window

Produces the following output -Capture.JPG
-saige-
0
Master Your Team's Linux and Cloud Stack

Come see why top tech companies like Mailchimp and Media Temple use Linux Academy to build their employee training programs.

 

Author Comment

by:jknj72
ID: 41733372
I literally just pasted what you sent me and its a done deal.
Great job and thanks alot!!
0
 

Author Closing Comment

by:jknj72
ID: 41733374
THANK YOU!!!
0
 

Author Comment

by:jknj72
ID: 41737360
Hey it_saige I have another Attribute called DisplayName along with my RequiredAttribute and I want to check the Display Name I have set for it, via this attribute, and use that as my column header. I have a loop through my source data, check the attribute and set the header/column name. Can I do that in the RowDataBound like I did with the Required attribute? I tried adding another Where to the statement you sent me but to no avail. Here is the code that fixed my Required attribute question and in bold is where I tried to add the DisplayName attribute, but its not working?
I just wanted to give you a heads up that I could use a little more help so I will create a new question

Thanks again
0

Featured Post

3 Use Cases for Connected Systems

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, testing some more, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

"In order to have an organized way for empathy mapping, we rely on a psychological model and trying to model it in a simple way, so we will split the board to three section for each persona and a scenario and try to see what those personas would Do,…
Any business that wants to seriously grow needs to keep the needs and desires of an international audience of their websites in mind. Making a website friendly to international users isn’t prohibitively expensive and can provide an incredible return…
The viewer will learn how to look for a specific file type in a local or remote server directory using PHP.
Learn how to create flexible layouts using relative units in CSS.  New relative units added in CSS3 include vw(viewports width), vh(viewports height), vmin(minimum of viewports height and width), and vmax (maximum of viewports height and width).

803 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question