Next not looping in vb.net - asp.net-mvc

I have create a function:
Public Shared Function appid()
Dim appidQ = From v In db_apps.app_users
Where v.NT_id = System.Environment.UserName
Select v
For Each v In appidQ
Return Convert.ToInt32(v.app_id)
Next v
Return appid()
End Function
I am trying to return EVERY app_id for a user a place it in a viewdata (just for testing I will eventually be placing this info in a cookie.) Now this should be returning 2 records, as I currently have 2 records that meet the criteria of the query specified in appidQ. Upon debugging appidQ is indeed returning both records. However when I step into a little further the "For Each" doesn't loop so although appidQ is returning 2 records the function is only returning the first record. Any help would be greatly appreciated.
UPDATE
Obviously the Return appid() cause it to exit the loop here is my new code:
Public Shared Function appid()
Dim appidQ = From v In db_apps.app_users
Where v.NT_id = System.Environment.UserName
Select v
For Each v In appidQ
Dim var = v.app_id
Next v
Return appid()
End Function
But it still doesn't do what I need it to. I need it to return the results of
For Each v In appidQ
Dim var = v.app_id
Next v

As already noticed the return statement should be moved after the loop to get all the results.
Public Shared Function appid() As List(Of Int32)
Dim appidQ = From v In db_apps.app_users
Where v.NT_id = System.Environment.UserName
Select v
Dim result As New List(Of Int32)
For Each v In appidQ
result.Add(Convert.ToInt32(v.app_id))
Next v
Return result
End Function
EDIT
It seems from your comment that what you need is a String representation of the list. And when you try the ToString() extension, it returns the name of the object (ex: System.Collections.Generic.List1[System.Int32] So I don't know if there is a more efficient way, but this should work:
Public Shared Function appid() As String
Dim appidQ = From v In db_apps.app_users
Where v.NT_id = System.Environment.UserName
Select v
'Create a String representation
Dim stringList As New System.Text.StringBuilder
Dim counter As Integer = 0
For Each v In appidQ
stringList.Append(v.app_id.ToString())
'Separator
If Not counter = appidQ.Count - 1 Then
stringList.Append("; ")
End If
counter += 1
Next
Return stringList.ToString
End Function

You've got a Return statement in your loop.
Return is at the function level, so your loop (and function) will be exited after first passage in the loop.
You should do somtething like that (I'm not a VB guy).
Public Shared Function appid()
Return (From v In db_apps.app_users
Where v.NT_id = System.Environment.UserName
Select v).ToList()
.Select(Function(p) Convert.ToInt32(p.app_id)).ToList()
End Function
Then in your view, if you're using a ViewData, something like that.
For Each id As Int32 In CType(ViewData("foo"), List(Of Int32)
...
Next

Inside the loop, you Return, so you exit the function altogether (and the loop in particular).
If you do not Return, you will not exit the function, so you will have a chance to continue looping.

You REALLY should have Option Strict On. Since we have no idea what the data type of app_id is, and you have Option Strict Off, we can't tell what exactly we are supposed to be returning.
Try this:
Public Shared Function appid()
Return (From v In db_apps.app_users
Where v.NT_id = System.Environment.UserName
Select v.app_id).ToList()
End Function
It would be better if it were strongly-typed, but this should give you the result you want.
EDIT: If you need to convert to Int32, try this:
Public Shared Function appid()
Return (From v In db_apps.app_users
Where v.NT_id = System.Environment.UserName
Select v).ToList()
.Select(Function(p) Convert.ToInt32(p.app_id)).ToList()
End Function

Related

A public action method 'FetchClaimsFor?pn=11111&cm=12&cy=2016' was not found on controller 'MyAPP.Controllers.ClaimMonthController'

I have a View that has an Http.Action to get a partial View.
My View has the following:
#Code
ViewData("Title") = "View Claims"
Dim actionUrl As String = "FetchClaimsFor?pn=" & ViewData("PersonnelNo") & "&cm=" & ViewData("ClaimMonth") & "&cy=" & ViewData("ClaimYear")
End Code
<div class="col-sm-12 col-md-6 col-lg-6">
#Html.Action(actionUrl, "ClaimMonth")
</div>
My ClaimMonthController has the following:
<HttpGet>
<ChildActionOnly>
Function FetchClaimsFor() As PartialViewResult
Dim pn As String = Request.QueryString("pn")
Dim cm As Integer = Request.QueryString("cm")
Dim cy As Integer = Request.QueryString("cy")
Dim ClaimsMade = New OvertimeClaims
ClaimsMade.GetClaimsFor(pn, cm, cy)
Select Case tsbClaimsMade.CoreDays
Case 0
Return PartialView("_TSB0", OvertimeClaims)
Case 5
Return PartialView("_TSB5", tsbClaimsMade)
Case 6
Return PartialView("_TSB6", tsbClaimsMade)
Case 8
Return PartialView("_TSB8", tsbClaimsMade)
Case Else
Return PartialView("_TSB0", tsbClaimsMade)
End Select
End Function
I did this approach as the partialview can be one of 4 types based on a value returned in the ClaimsMade object.
Unfortunately I'm getting the error...
A public action method 'FetchClaimsFor?pn=11111&cm=12&cy=2016' was not
found on controller 'MyAPP.Controllers.ClaimMonthController'.
Looking at other similar question in SO I have tried with and without <HttpGet> and with and without <ChildActionOnly> - each time I get the same error.
UPDATE
forgot to mention I also tried adding Public to the function
SOLUTION
View code should be:
#Html.Action("FetchClaimsFor", "ClaimMonth", New With { .pn = ViewData("PersonnelNo"), .cm = ViewData("ClaimMonth"), .cy = ViewData("ClaimYear") })
Controller code should be:
Function FetchClaimsFor(pn As String, cm As Integer, cy As Integer) As PartialViewResult
REMOVE the next three lines.
Dim pn As String = Request.QueryString("pn")
Dim cm As Integer = Request.QueryString("cm")
Dim cy As Integer = Request.QueryString("cy")
The first param to Html.Action is not a URL, but rather an action name. You're correctly being told that there's no action that matches FetchClaimsFor?pn=11111&cm=12&cy=2016. Instead, you should be doing:
#Html.Action("FetchClaimsFor", "ClaimMonth", New With { .pn = ViewData("PersonnelNo"), .cm = ViewData("ClaimMonth"), .cy = ViewData("ClaimYear") })
Note: I'm not fluent in VB, so the syntax may be off

Populating a ViewModel from a database model

I have a ViewModel that inherits a database model. I can't work out how to populate the ViewModel from the database.
"ViewModel"
Public Class CustomerView
Inherits Customer
Private lookUp As New LookUpData
ReadOnly Property OwnerList As List(Of SelectListItem)
Get
Return lookUp.OwnersList(True)
End Get
End Property
End Class
"Controller"
Function Edit(Optional Id As Integer = Nothing) As ActionResult
Dim model As New CustomerView
model = (From c In db.Customers Where c.Id = Id AndAlso c.OrganisationId = s.OrganisationId).FirstOrDefault
If model Is Nothing Then
Return RedirectToAction("List")
Else
Return View(model)
End If
End Function
I get an invalid cast exception.
Any help would be greatly appreciated.
Your Linq query is returning (I assume) as list of Customer object which you need to project into your view model object. Change your Linq by adding a select:
model = (From c In db.Customers _
Where c.Id = Id AndAlso _
c.OrganisationId = s.OrganisationId _
Select New CustomerView With { _
.CompanyName = c.CompanyName, _
.Address = c.Address, _
.City = cust.City, _
.Country = cust.Country}).FirstOrDefault
Been a while since I did VB, but that should either work or require only a tweak.

LINQ concatenate 2 fields to search on

I'm trying to concatenate two fields in LINQ so that I can then filter with a keyword. I found a question posted here that I thought was my answer, but I'm getting 0 records back for some reason. This is supposed to return a JSON result for an autocomplete textbox (it works when I don't concatenate fields).
Here's my code:
Function CostCodeList(ByVal term As String) As ActionResult
Dim results = From c In db.ORG_CHART_V
Let Fullname = CStr(c.COSTCTR_CD & " - " & c.BREADCRUMB)
Where Fullname.ToUpper.Contains(CStr(term).ToUpper)
Order By Fullname
Select New With {.label = Fullname, .id = c.ORG_NODE_ID}
Return Json(results.ToArray, JsonRequestBehavior.AllowGet)
End Function
I'm also getting this error on the Return:
Public member 'ToArray' on type 'DbQuery(Of VB$AnonymousType_3(Of
String,Integer))' not found.
Before trying to concatenate the two fields I was searching on them separately, successfully. But when I concatenate them, it seems like everything I try either gets me an error and/or zero records.
Here is a different function that does work:
Function RoleList(ByVal term As String) As ActionResult
Dim list As New ArrayList
Dim results As IQueryable(Of JOB_ROLE)
If IsNumeric(term) Then
results = From c In db.JOB_ROLE
Where CStr(c.JBROLE_NO).StartsWith(term)
Else
results = From c In db.JOB_ROLE
Where c.JOB_ROLE_NAME.ToUpper.Contains(CStr(term).ToUpper)
End If
results = results.OrderBy(Function(e) e.JOB_ROLE_NAME)
For Each item In results
list.Add(New With {.label = item.JOB_ROLE_NAME, .id = item.JOB_ROLE_ID})
Next
Return Json(list.ToArray, JsonRequestBehavior.AllowGet)
End Function
Here is the new function that works as intended:
Function CostCodeList(ByVal term As String) As ActionResult
Dim list As New ArrayList
Dim results = db.ORG_CHART_V.Where(Function(e) (CStr(e.COSTCTR_CD) + " - " + e.BREADCRUMB).Contains(CStr(term).ToUpper)).OrderBy(Function(o) o.COSTCTR_CD)
For Each item In results
list.Add(New With {.label = item.COSTCTR_CD & " - " & item.BREADCRUMB, .id = item.ORG_NODE_ID})
Next
Return Json(list.ToArray, JsonRequestBehavior.AllowGet)
End Function

Sorting or Ordering values returned in a EF query MVC 3 vb.net app

I am using a where comparer in the below snippet from my function.. I need to order or sort the returned items by one of the columns... I tried using .OrderBy(function(f) f.regDate) but that dont work at all...
The part of the function in question looks like this:
Function ClassFiller() As ActionResult
Dim _courses As List(Of cours) = db.courses.ToList
Dim _registrants As List(Of reg_info) = db.reg_info.ToList
Dim _classSpec As List(Of classrm) = db.classrms.ToList
Dim _CurrRegistrants As List(Of reg_classes) = db.reg_classes.ToList
For Each Course In _courses.Where(Function(a) a.course_day = "Tuesday")
Dim _CurrCourse As cours = Course
Dim _classRoom As classrm = db.classrms.Where(Function(b) b.Course_ID = _CurrCourse.course_ref).FirstOrDefault()
Dim _classmax As Integer = _classRoom.ClassMax - 1
For Each reg In _registrants.Where(Function(d) d.tues_class1 = _CurrCourse.course_ref).OrderBy(Function(f) f.reg_date)
Dim _ClassCount As Integer = db.reg_classes.Where(Function(c) c.tues_class = _CurrCourse.course_ref).Count
I need to have the _registrants ordered or sorted by a value that is in the db.reg_info under the reg_date column... Any ideas??
Where _registrant is declared at I should have used the following instead:
Dim _registrants As List(Of reg_info) = db.reg_info.OrderBy(Function(t) t.reg_date).ToList
then it will already be ordered.. So the orderby is not needed in the For Each reg In _Registrants.

Combining extension methods

I'm trying to write 2 extension methods to handle Enum types. One to use the description attribute to give some better explanation to the enum options and a second method to list the enum options and their description to use in a selectlist or some kind of collection.
You can read my code up to now here:
<Extension()> _
Public Function ToDescriptionString(ByVal en As System.Enum) As String
Dim type As Type = en.GetType
Dim entries() As String = en.ToString().Split(","c)
Dim description(entries.Length) As String
For i = 0 To entries.Length - 1
Dim fieldInfo = type.GetField(entries(i).Trim())
Dim attributes() = DirectCast(fieldInfo.GetCustomAttributes(GetType(DescriptionAttribute), False), DescriptionAttribute())
description(i) = If(attributes.Length > 0, attributes(0).Description, entries(i).Trim())
Next
Return String.Join(", ", description)
End Function
<Extension()> _
Public Function ToListFirstTry(ByVal en As System.Enum) As IEnumerable
Dim type As Type = en.GetType
Dim items = From item In System.Enum.GetValues(type) _
Select New With {.Value = item, .Text = item.ToDescriptionString}
Return items
End Function
<Extension()> _
Public Function ToListSecondTry(ByVal en As System.Enum) As IEnumerable
Dim list As New Dictionary(Of Integer, String)
Dim enumValues As Array = System.Enum.GetValues(en.GetType)
For Each value In enumValues
list.Add(value, value.ToDescriptionString)
Next
Return list
End Function
So my problem is both extension methods don't work that well together. The methods that converts the enum options to an ienumerable can't use the extension method to get the description.
I found all kind of examples to do one of both but never in combination with each other. What am I doing wrong? I still new to these new .NET 3.5 stuff.
The problem is that Enum.GetValues just returns a weakly typed Array.
Try this:
Public Function ToListFirstTry(ByVal en As System.Enum) As IEnumerable
Dim type As Type = en.GetType
Dim items = From item In System.Enum.GetValues(type).Cast(Of Enum)() _
Select New With {.Value = item, .Text = item.ToDescriptionString}
Return items
End Function
(It looks like explicitly typed range variables in VB queries don't mean the same thing as in C#.)

Resources