How to add an addition Of T to a System.Linq.Iqueryable - asp.net

I was in the middle of writing this post, but to the great help of stackoverflow I found a hint that helped me solve my issue, but I wanted to post this in order to help other developers if they come accross this issue and are new to VB.NET, ASP.NET and MVC5.
I have a variable of type faqs declared as System.Linq.IQuerable(Of ViewModels.FaqViewModel) 'Note I created a FaqViewModel to pass the Model data that is needed to view.
However, there might be times when the query results are null, but I need to pass at least one item back to the view in order to show some results and return the original search query back to the search box.
Here is my code, what am I missing?
VIEW
--- #ModelType IEnumerable(Of CompanyName.ViewModels.FaqViewModel)
CONTROLLER
Function SearchFaqs() As ActionResult
Dim url As String
Dim txtSearchTerm As String
If Request("txtSearch").IsNullOrWhiteSpace() Then
txtSearchTerm = ""
Else
txtSearchTerm = Request("txtSearch")
End If
url = Request.UrlReferrer.ToString()
Dim faqs = (From f In _db.Faqs _
Where Not f.Hk_DeletedDt.HasValue _
And f.Question.Contains(txtSearchTerm) _
Or f.Answer.Contains(txtSearchTerm) _
Or f.Hk_DeletedDt = New DateTime(1900, 1, 1) _
And f.Active = 1 _
Order By f.CategoryId Descending _
Select New FaqViewModel With {
.Question = f.Question,
.Answer = f.Answer,
.SearchTerm = txtSearchTerm
})
If Not faqs.Any() Then
faqs.Union(Of FaqViewModel)(IEnumerable)
'(New FaqViewModel With {
' .Question = "Your Search did not contain any results please try again.",
' .Answer = "",
' .SearchTerm = txtSearchTerm
' })
End If
Return View("Faq", faqs)
End Function

What I found to fix the problem.
**CONTROLLER UPDATED, simply converted to a .ToList !!! **
<HttpPost>
Function SearchFaqs() As ActionResult
Dim url As String
Dim txtSearchTerm As String
If Request("txtSearch").IsNullOrWhiteSpace() Then
txtSearchTerm = ""
Else
txtSearchTerm = Request("txtSearch")
End If
url = Request.UrlReferrer.ToString()
Dim faqs = (From f In _db.Faqs _
Where Not f.Hk_DeletedDt.HasValue _
And f.Question.Contains(txtSearchTerm) _
Or f.Answer.Contains(txtSearchTerm) _
Or f.Hk_DeletedDt = New DateTime(1900, 1, 1) _
And f.Active = 1 _
Order By f.CategoryId Descending _
Select New FaqViewModel With {
.Question = f.Question,
.Answer = f.Answer,
.SearchTerm = txtSearchTerm
})**.ToList**
If Not faqs.Any() Then
**Dim noResultsFaq As New FaqViewModel
noResultsFaq.Question = "Your Search did not contain any results please try again."
noResultsFaq.Answer = ""
noResultsFaq.SearchTerm = txtSearchTerm
faqs.Add(noResultsFaq)**
End If
Return View("Faq", faqs)
End Function

Related

PDFs missing EOF section on customer's server

Folks- I'm relatively new to ASP.NET, and have a question that has stumped my peers-- folks much more experienced than myself.
My company created a website that uses iTextSharp to build and stream PDFs. The functionality works perfectly on my company's development and staging/test servers. The customer's functionality isn't working well, however. The customer's server streams a file where the PDF is missing the last block of data representing the EOF section. The PDF seems to build correctly, streams correctly, but when users open the PDF, the following error displays: 'There was an error opening this document. The file is damaged and could not be repaired.'
By comparing the PDFs in a text viewer (comparing the PDFs from my server vice the customer's server), I can see that the EOF section is missing from the customer's PDF. I'll also note that no errors are thrown during PDF creation, if that's helpful. To make matters more difficult, I have no access to the customer's servers, so I won't be able to interact with the systems directly.
The asp.net version is 3.5. Both of our servers (my company and the customer) are: running IIS7.5 on Server 2008R2; using iTextSharp is 5.1.2; and are configured for FIPS compatibility.
I've read dozens and dozens of posts detailing why a PDF isn't created properly, why it may not be streaming, and all things related, but I haven't seen this particular issue before. I guess what I need to know in the short-term is: 1) what can I provide to help diagnose the issue, 2) where is a good place to start looking for areas of concern?
Also, I updated to revision 5.5.3 last night; same results-- it works fine on my servers, but produces broken PDFs on the customer's server.
Code added:
Public Function BuildReport(ByVal tblReport As DataTable, _
ByRef memStream As MemoryStream, _
ByRef strErrMsg As String) As Boolean
Dim booOK As Boolean = True
strErrMsg = String.Empty
' Create document
Try
' Create writer (listens to the document and directs PDF stream)
memStream = New MemoryStream()
Dim msWriter As PdfWriter = PdfWriter.GetInstance(_document, memStream)
msWriter.CloseStream = False
'Create header
Dim ev As New itsEvents
msWriter.PageEvent = ev
' Set document metadata
_document.AddTitle(_strMetaTitle)
_document.AddSubject(_strMetaSubject)
_document.AddCreator(_strMetaApplication)
_document.AddAuthor(_strMetaAuthor)
' Open document, add document content, close document
_document.Open()
AddReportContent(tblReport)
_document.Close()
Catch ex As Exception
booOK = False
strErrMsg = ex.Message
End Try
Return booOK
End Function
Private Sub AddReportContent(ByVal tblReport As DataTable)
' Count report columns
Dim intReportColumns As Integer = 0
For Each col As DataColumn In tblReport.Columns
If ContainedInColumnMask(col.ColumnName) Then
intReportColumns += 1
End If
Next
' Build table
Dim table As PdfPTable
Dim cell As PdfPCell
Dim phrase As Phrase
If intReportColumns >= 1 Then
' Init table
table = New PdfPTable(intReportColumns)
' Add title to table
'phrase = New Phrase(_strMetaTitle, _fontLarge)
'cell = New PdfPCell(phrase)
'cell.Colspan = intReportColumns
'cell.HorizontalAlignment = 1 ' 0=Left, 1=Centre, 2=Right
'table.AddCell(cell)
' Add column headers to table
Dim i As Integer = 0
Dim intColWidth As Integer
Dim intColWidths As Integer() = New Integer(intReportColumns - 1) {}
Dim intColWidthTotal As Integer = 0
Dim strColName As String
For Each col As DataColumn In tblReport.Columns
If ContainedInColumnMask(col.ColumnName) Then
strColName = col.ColumnName
If (col.ExtendedProperties.Item("NOTEXTEXPORT") <> True) Then
If col.ExtendedProperties.Contains("FRIENDLYNAME") Then
strColName = col.ExtendedProperties.Item("FRIENDLYNAME")
End If
End If
phrase = New Phrase(strColName, _fontMedium)
cell = New PdfPCell(phrase)
cell.BorderWidth = 1
cell.BackgroundColor = iTextSharp.text.BaseColor.LIGHT_GRAY
'cell.BackgroundColor = iTextSharp.text.Color.LIGHT_GRAY
table.AddCell(cell)
intColWidth = GetColumnWidth(col, strColName, _fontMedium.Size, _fontSmall.Size)
intColWidths(i) = intColWidth
intColWidthTotal += intColWidth
i += 1
End If
Next
table.TotalWidth = intColWidthTotal
table.SetWidths(intColWidths)
' Add rows to table
For Each row As DataRow In tblReport.Rows
For Each col As DataColumn In tblReport.Columns
If ContainedInColumnMask(col.ColumnName) Then
phrase = New Phrase(SetBlankIfNothing(row.Item(col.ColumnName).ToString()), _fontSmall)
cell = New PdfPCell(phrase)
cell.BorderWidth = 0.5
table.AddCell(cell)
End If
Next
Next
Else
' Init table
table = New PdfPTable(1)
' Nothing to add to table
table.AddCell(String.Empty)
End If
' Add table to document
_document.Add(table)
End Sub
Public Sub New(ByVal strMetaTitle As String, _
ByVal strMetaSubject As String, _
ByVal strMetaApplication As String, _
ByVal strMetaAuthor As String, _
Optional ByVal strColumnMask As String = "")
GetStaticInfo()
_strMetaTitle = strMetaTitle
_strMetaSubject = strMetaSubject
_strMetaApplication = strMetaApplication
_strMetaAuthor = strMetaAuthor
_document = New iTextSharp.text.Document(_itsPage, _itsMarginLeft, _itsMarginRight, _itsMarginTop, _itsMarginBottom)
If strColumnMask <> "" And Not strColumnMask Is Nothing Then
_strColumnMask = strColumnMask
End If
End Sub
Public Sub New(ByVal strMetaTitle As String, _
ByVal strMetaSubject As String, _
ByVal strMetaApplication As String, _
ByVal strMetaAuthor As String, _
Optional ByVal strColumnMask As String = "")
GetStaticInfo()
_strMetaTitle = strMetaTitle
_strMetaSubject = strMetaSubject
_strMetaApplication = strMetaApplication
_strMetaAuthor = strMetaAuthor
_document = New iTextSharp.text.Document(_itsPage, _itsMarginLeft, _itsMarginRight, _itsMarginTop, _itsMarginBottom)
If strColumnMask <> "" And Not strColumnMask Is Nothing Then
_strColumnMask = strColumnMask
End If
End Sub

The ObjectContext instance has been disposed and can no longer be used for operations that require a connection when adding additional dropdownlist

I had the following code:
If Page.IsPostBack = False Then
' If prospect is coming from unique url
Dim prospect_url As String = Page.RouteData.Values("value")
' Save prospect_url into session variable
Session("prospect_url") = prospect_url
Using dbContext As IRFEntities = New IRFEntities
' Prepopulate the states dropdown.
Dim getStates = (From p In dbContext.IRF_States _
Order By p.name _
Select p)
ddlState.DataSource = getStates
ddlState.DataTextField = "name"
ddlState.DataValueField = "id"
ddlState.DataBind()
' Grab info. about prospect based on unique url.
Dim getProspect = (From p In dbContext.IRF_Prospects _
Where p.url = prospect_url _
Select p).FirstOrDefault
' If they have a record...
If getProspect IsNot Nothing Then
'If IsDBNull(getProspect.user_id) Then
If getProspect.user_id Is Nothing Then
' Prepopulate the form with their information.
' These must have a value, so we need to make sure that no column is null in the database.
txtFirst.Text = getProspect.first_name
txtLast.Text = getProspect.last_name
txtAddress.Text = getProspect.address
txtCity.Text = getProspect.city
ddlState.SelectedValue = getProspect.state
txtZip.Text = getProspect.zip
txtPhone.Text = getProspect.phone
txtEmail.Text = getProspect.email_address
txtYearEnrolling.Text = getProspect.enrolling_in
Else
' Redirect them to login.
Response.Redirect("login.aspx")
End If
End If
End Using
End If
I then added directly below ddlState.DataBind() the following:
' Prepopulate the programs dropdown.
Dim getPrograms = (From p In dbContext.IRF_Program _
Order By p.name _
Select p)
ddlProgram.DataSource = getPrograms
ddlProgram.DataTextField = "name"
ddlProgram.DataValueField = "id"
ddlState.DataBind()
Now I get the error:
The ObjectContext instance has been disposed and can no longer be used for operations that require a connection
If I comment out the inserted code, the code works. Why is this code causing a problem?
You have lost this object:
dbContext
That is the resources (including the connection operations) for this object have already been disposed of and cleaned up. You can re-create the object if you need to databind another drop down list.
Dim dbContext as IRFEntities=Nothing
Using dbContext= New IRFEntities
//perform first databind
End Using
Using dbContext = New IRFEntities
//code to perform second databind
End Using

How to test a controller which updates what was posted to it

This seems really simple, but I can't seem to get it to work. I want to unit test my controller's assign action. It takes a IEnumerable(Of Integer) which represent the ID's of all the objects to assign.
Here's the code I've written, I'm getting an error on the Do statement (I copied the code from Ayende's blog here http://ayende.com/blog/3397/rhino-mocks-3-5-a-feature-to-be-proud-of-seamless-do).
<Test()> _
Public Sub Assign_Post_Should_Assign_All_Audits_Provided()
Dim auditsToAssign As IEnumerable(Of HvacAudit) = HvacAuditsGenerator.GenerateAudits() _
.Unassigned()
Dim auditIDs As IEnumerable(Of Integer) = auditsToAssign.Select(Function(audit, index) audit.HvacAuditID)
Dim hvacAuditRepo As IHvacAuditRepository = MockRepository.GenerateMock(Of IHvacAuditRepository)()
hvacAuditRepo.Stub(Sub(repo) repo.GetAuditByID(1)) _
.Do(Function(invocation) invocation.ReturnValue = auditsToAssign.Single(Function(audit) audit.HvacAuditID = invocation.Arguments(0)))
Dim controller As New HvacAuditController(hvacAuditRepo)
Dim r As ViewResult = controller.Assign(auditIDs).AssertViewRendered()
r.AssertAssignedAuditCount(auditsToAssign.Count)
auditsToAssign.AssertAreAssigned()
hvacAuditRepo.AssertWasCalled(Sub(h) h.SaveChanges())
End Sub
I was able to fix this by changing the code to use a function lambda instead of a sub lambda and return the value directly. I'm not sure what Ayende's blog was referring to.
<Test()> _
Public Sub Assign_Post_Should_Assign_All_Audits_Provided()
Dim auditsToAssign As IEnumerable(Of HvacAudit) = HvacAuditsGenerator.GenerateAudits() _
.Unassigned()
Dim auditIDs As IEnumerable(Of Integer) = auditsToAssign.Select(Function(audit, index) audit.HvacAuditID)
Dim hvacAuditRepo As IHvacAuditRepository = MockRepository.GenerateMock(Of IHvacAuditRepository)()
hvacAuditRepo.Stub(Sub(repo) repo.GetAuditByID(1)) _
.Do(Function(auditID as Integer) Return auditsToAssign.Single(Function(audit) audit.HvacAuditID = auditID))
Dim controller As New HvacAuditController(hvacAuditRepo)
Dim r As ViewResult = controller.Assign(auditIDs).AssertViewRendered()
r.AssertAssignedAuditCount(auditsToAssign.Count)
auditsToAssign.AssertAreAssigned()
hvacAuditRepo.AssertWasCalled(Sub(h) h.SaveChanges())
End Sub

Searching particular files in the folder

Hi I can search all the images with .jpg extension and pass it to the fancybox gallery , The issue is i just want the images of particular productid
for instance if a product has 5 images , and they are saved as (productid_imagenumber.jpg) , therefore a product with productid 99 will be saved as 99_1.jpg , 99_2.jpg similarly 99_5.jpg,
I can pass the productID but i cant find a away just to get the images of that productID , instead of getting all the images which is done by the function below:
Dim directory As DirectoryInfo = New System.IO.DirectoryInfo("C:Images\")
Dim allImages() = directory.GetFiles("*.jpg", SearchOption.AllDirectories)
Dim strContent As String = ""
For Each image As FileInfo In allImages
Dim strTemp As String = (String.Format("<img src=""{0}"" />", image.Name))
strContent = "<a class=""fancybox-thumb"" rel=""fancybox-thumb1"" href=""" & image.Name + image.Extension & """ title="""">" & _
"<img src=""" & image.Name + image.Extension & """ alt="" /></a>"
Next
If Not String.IsNullOrEmpty(strContent) Then
Return String.Format("<div id=""product-lightbox""><p>{0}</p></div>", strContent)
Else
Return String.Empty
End If
End Function
Can any one give any suggestion or assistance on how to do this.
Try this:
Dim images = (From img In directory.GetFiles("*.jpg", IO.SearchOption.AllDirectories)
Where img.Name.Contains("_") _
AndAlso img.Name.Split("_"c)(0) = productID).ToList
Ok, you are using .NET 2.0:
Dim allProductIDImages As New List(Of IO.FileInfo)
For Each img As IO.FileInfo In directory.GetFiles("*.jpg", IO.SearchOption.AllDirectories)
If img.Name.Contains("_") Then
Dim ID As String = img.Name.Split("_"c)(0)
If ID.Equals(productID) Then
allProductIDImages.Add(img)
End If
End If
Next
Another - possibly faster - approach is to let GetFiles pre-search:
Dim pattern As String = String.Format("*{0}_*.jpg", productID)
Dim allProductIDImages() As IO.FileInfo = _
directory.GetFiles(pattern, IO.SearchOption.AllDirectories)

Why doesn't this code work in another solution?

I have the below code in my current solution, which returns an error of 'The value '' is invalid'. The below snippet has been shortened to just show the problem area as opposed to the entire ActionResult.
Dim tComment As New hdComment
tComment.Comment = collection("wmd-input")
tComment.MadeOn = DateTime.Now
tComment.UserID = Session("LoggedInUser")
tComment.CallID = id
If Not tComment.Comment.Trim().Length = 0 Then
db.hdComments.InsertOnSubmit(tComment)
End If
db.SubmitChanges()
Return Redirect("/Calls/Details/" & id)
However, in a previous project, I have used exactly the same code, even the view is the same, but it still returns the above error.
Everything is receiving a value ok.
The only thing that's different is that it's a different project.
I'm at a bit of a loss with this one.
Anyone have any ideas?
EDIT For reference, here is the entire ActionResult.
'
' POST: /Calls/Details/5
<Authorize()> _
<AcceptVerbs(HttpVerbs.Post)> _
<ValidateInput(False)> _
Function Details(ByVal id As Integer, ByVal collection As FormCollection) As ActionResult
Dim calls As hdCall = callRepository.GetCall(id)
ViewData("MyCallID") = calls.CallID
ViewData("UserThatLogged") = calls.UserID
ViewData("TimeLogged") = calls.loggedOn.ToLongDateString & " " & calls.loggedOn.ToLongTimeString
ViewData("Title") = calls.Title
Dim dataContext As New CustomerServiceModelDataContext
ViewData("Status") = New SelectList(dataContext.hdStatus, "StatusID", "Status", calls.StatusID)
ViewData("Type") = New SelectList(dataContext.hdCategories, "CategoryID", "Title", calls.CategoryID)
ViewData("Company") = calls.hdCompany.Company
ViewData("Priority") = New SelectList(dataContext.hdPriorities, "PriorityID", "Priority", calls.PriorityID)
ViewData("CallDetails") = calls.CallDetails
ViewData("Customer") = calls.hdCustomer.CustomerName
ViewData("CustomerID") = calls.hdCustomer.CustomerID
ViewData("CustomerCallCount") = callRepository.CountCallsForThisCustomer(calls.hdCustomer.CustomerID).Count()
ViewData("ContactNumber") = calls.hdCustomer.Telephone
ViewData("AssignedTo") = New SelectList(dataContext.aspnet_Users, "UserName", "UserName", calls.AssignedTo)
Dim callComments = callRepository.GetCallComments(id)
Dim db As New CustomerServiceModelDataContext
Try
Dim tComment As New hdComment
tComment.Comment = collection("wmd-input")
tComment.MadeOn = DateTime.Now
tComment.UserID = Session("LoggedInUser")
tComment.CallID = id
If Not tComment.Comment.Trim().Length = 0 Then
db.hdComments.InsertOnSubmit(tComment)
End If
'Update any call changes
Dim tCall = (From c In db.hdCalls _
Where c.CallID = id _
Select c).SingleOrDefault
tCall.updatedOn = DateTime.Now
tCall.UpdatedBy = Session("LoggedInUser")
tCall.StatusID = collection("Status")
tCall.AssignedTo = collection("AssignedTo")
tCall.CategoryID = collection("Type")
tCall.PriorityID = collection("Priority")
db.SubmitChanges()
Return Redirect("/Calls/Details/" & id)
Catch ex As Exception
ModelState.AddModelError("Error", ex)
Return View(callComments)
End Try
Return View(callComments)
End Function
The rest of the code works, if the wmd-input field is left blank on the form, it's only when there is something in it does it throw the error.
EDIT bit of an update to this, this line:
If Not tComment.Comment.Trim().Length = 0 Then
now reads
If (Not tComment.Comment.Trim().Length = 0) Then
and the page updates if nothing is in the wmd-input box, but if there is, it returns the The value '' is invalid.
You are probably missing a reference. Or the framework version is different.
Also is it the same development machine, is asp.net-mvc installed both places?
I managed to fix this, the problem actually lay in the Foriegn Key Contraints between hdCalls and hdComments.
I removed the contraints and recreated them and all of a sudden it was fine.

Resources