I've seen examples on here for saving one string to pass onto the next page. But, I haven't been able to find or figure out how to save multiple search parameters without requiring a variable for each search string, which is something I'd rather not do, as I have 12 search fields.
I've seen examples with saving your variables to a viewbag and then passing that when you go to the next page. That works for the one variable, but not for multiple.
Is there a more eloquent solution then to have to pass individual view bags for each variable?
Thanks!
You can use a class for it like this:
public class SearchField
{
public string Field1 { get; set; }
public int Field2 { get; set; }
// other fields
}
And save object to ViewBag like this:
SearchField objSearchField = new SearchField();
objSearchField.Field1="value1";
objSearchField.Field2 = 100;
// set other fields
ViewBag.SearchFields = objSearchField;
You can use viewbag or tempdata["stringid"]. tempdata might be a better choice here. What you will do is create an array of strings (or a list might be even better!) and store all your information in that array. Then you store it on tempdata. Something like this:
string[] URLs = new string[12];
//do stuff
Tempdata["URLs"] = URLs;
When you get to the page you need the URLs in again, either in the controller or in the view you will write:
string[] URLS = (string[])Tempdata["URLs"];
//do stuff
or
string[] URLS = Tempdata["URLs"] as string[];
Something like that should work. You should read up on the other ways to pass data in ASP MVC:
http://www.c-sharpcorner.com/UploadFile/abhikumarvatsa/various-ways-to-pass-data-from-controller-to-view-in-mvc/
Passing an object array as TempData[] to view
Related
I have an ASP.NET MVC web application.
The SQL table has one column ProdNum and it contains data such as 4892-34-456-2311.
The user needs a form to search the database that includes this field.
The problem is that the user wants to have 4 separate fields in the UI razor view whereas each field should match with the 4 parts of data above between -.
For example ProdNum1, ProdNum2, ProdNum3 and ProdNum4 field should match with 4892, 34, 456, 2311.
Since the entire search form contains many fields including these 4 fields, the search logic is based on a predicate which is inherited from the PredicateBuilder class.
Something like this:
...other field to be filtered
if (!string.IsNullOrEmpty(ProdNum1) {
predicate = predicate.And(
t => t.ProdNum.toString().Split('-')[0].Contains(ProdNum1).ToList();
...other fields to be filtered
But the above code has run-time error:
The LINQ expression node type 'ArrayIndex' is not supported in LINQ to Entities`
Does anybody know how to resolve this issue?
Thanks a lot for all responses, finally, I found an easy way to resolve it.
instead of rebuilding models and change the database tables, I just add extra space in the search strings to match the search criteria. since the data format always is: 4892-34-456-2311, so I use Startwith(PODNum1) to search first field, and use Contains("-" + PODNum2 + "-") to search second and third strings (replace PODNum1 to PODNum3), and use EndWith("-" + PODNum4) to search 4th string. This way, I don't need to change anything else, it is simple.
Again, thanks a lot for all responses, much appreciated.
If i understand this correct,you have one column which u want to act like 4 different column ? This isn't worth it...For that,you need to Split each rows column data,create a class to handle the splitted data and finally use a `List .Thats a useless workaround.I rather suggest u to use 4 columns instead.
But if you still want to go with your existing applied method,you first need to Split as i mentioned earlier.For that,here's an example :
public void test()
{
SqlDataReader datareader = new SqlDataReader;
while (datareader.read)
{
string part1 = datareader(1).toString.Split("-")(0);///the 1st part of your column data
string part2 = datareader(1).toString.Split("-")(1);///the 2nd part of your column data
}
}
Now,as mentioned in the comments,you can rather a class to handle all the data.For example,let's call it mydata
public class mydata {
public string part1;
public string part2;
public string part3;
public string part4;
}
Now,within the While loop of the SqlDatareader,declare a new instance of this class and pass the values to it.An example :
public void test()
{
SqlDataReader datareader = new SqlDataReader;
while (datareader.read)
{
Mydata alldata = new Mydata;
alldata.Part1 = datareader(1).toString.Split("-")(0);
alldata.Part2 = datareader(1).toString.Split("-")(1);
}
}
Create a list of the class in class-level
public class MyForm
{
List<MyData> storedData = new List<MyData>;
}
Within the while loop of the SqlDatareader,add this at the end :
storedData.Add(allData);
So finally, u have a list of all the splitted data..So write your filtering logic easily :)
As already mentioned in a comment, the error means that accessing data via index (see [0]) is not supported when translating your expression to SQL. Split('-') is also not supported hence you have to resort to the supported functions Substring() and IndexOf(startIndex).
You could do something like the following to first transform the string into 4 number strings ...
.Select(t => new {
t.ProdNum,
FirstNumber = t.ProdNum.Substring(0, t.ProdNum.IndexOf("-")),
Remainder = t.ProdNum.Substring(t.ProdNum.IndexOf("-") + 1)
})
.Select(t => new {
t.ProdNum,
t.FirstNumber,
SecondNumber = t.Remainder.Substring(0, t.Remainder.IndexOf("-")),
Remainder = t.Remainder.Substring(t.Remainder.IndexOf("-") + 1)
})
.Select(t => new {
t.ProdNum,
t.FirstNumber,
t.SecondNumber,
ThirdNumber = t.Remainder.Substring(0, t.Remainder.IndexOf("-")),
FourthNumber = t.Remainder.Substring(t.Remainder.IndexOf("-") + 1)
})
... and then you could simply write something like
if (!string.IsNullOrEmpty(ProdNum3) {
predicate = predicate.And(
t => t.ThirdNumber.Contains(ProdNum3)
I work for a school district and we are having to manually create user logins (AD), and GAFE accounts. We would like automate this as much as we can. Currently, We have a CSV file that is exported daily from our SIS (Student information system) that has a list of all new students and I need to read that data, apply some formulas, and output two CSVs, one for GAFE and one for AD, with the results from my formulas.
My thoughts are to read the CSV and save it into a tuple data type, then write a new tuple with the output I need, then save to new CSVs. I thought tuple would work nicely, but I'm still new to C# that I'm not sure what would work best. If you guys have any recommendation on other data types I would love the input.
Here's the header-
"SchoolName","firstName","middleName","lastName","grade","studentNumber","Change","startDate","endDate","EnrStartStatus","CalcStartStatus","DateAdded"
"AHS","John","Smith","Doe","12","1779123445","New Student at School","2016-11-29 00:00:00","","","","2016-11-22 20:00:00"
So, I'm having some mental logic issues. I'm not sure on how to convert the CSV to tuple without having to do nested foreach loops (the way I'm thinking about going about it doesn't seem efficient.). I figured that there would be a library or something built into C# that would make it so much easier... Any input that is given would greatly be appreciated.
Thanks,
Throdne
There are several really powerful libraries to most of the work for you. One really good one is CSVHelper which will not only read and write the data for you, but perform type conversions so that your numbers and dates are stored as numbers and dates.
Given sample data similar to yours:
"FirstName","MiddleName","LastName","Grade","StudentNumber","EnrollDate"
"Ziggy","V.","Aurantium","12","4001809","12/13/2016 6:18:21 PM"
"Nancy","W.","Stackhouse","11","9762164","12/15/2016 7:06:20 PM"
"Sullivan","N.","Deroche","11","7887589","12/11/2016 1:31:50 PM"
1. Devise a class for the data
public class Student
{
public int StudentNumber { get; set; }
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
public int Grade { get; set; }
public DateTime EnrollDate { get; set; }
public Student()
{ }
}
2. Load the Data
// a form/class level collection for the data
List<Student> myStudents;
Then to load the data:
using (var sr = new StreamReader(#"C:\Temp\students.csv", false))
using (var csv = new CsvReader(sr))
{
csv.Configuration.HasHeaderRecord = true;
csv.Configuration.QuoteAllFields = true;
myStudents = csv.GetRecords<Student>().ToList();
}
That's it: 3 lines of code. There are many other Configuration options to fine tune how it works. Also:
If there are a lot of rows, you can leave off the ToList() and work with the IEnumerable result and load each row as needed
If the Property names you want to use dont match the CSV header names, you can supply a Map to tell CSVHelper which fields map to which properties.
Ditto for when there are no field names.
Exporting your collection to new output CSVs is just as easy as reading them
You would also probably need a Map (or two) to control the output order for the output CSVs.
Best of all, it converts the data types for you. No, wait, best of all is that it wont split up fields with embedded commas (as in "Ziggy","V.","Aurantium, II","12"... note the last name data) the way String.Split(',') will.
I recommend to use a string array instead of Tuples.
You can easily convert a line of csv values into a string array with this line of code:
line.Split( new char[] { '"', ',' }, StringSplitOptions.RemoveEmptyEntries );
This returns a string array.
Using " and , both as separator characters lets you get rid of the "'s in the same step.
I need to select multiple fields into an enumerator to run a foreach in my Razor web app.
In the controller, I have:
...
cols = (from b in a.RefTable select new {b.Col1,b.Col2,b.Col3}),
...
It returns the values correctly when I use:
#foreach(var col in #item.cols)
{
#col
}
However, the representation on the page is:
{ Col1 = col1Value, Col2 = col2Value, Col3 = col3Value }
Two things I want to do:
Only show the column values on the page without being comma separated (will be separated onto each line within a dataTable field), and then not to show any value if the "col2Value", for example, is blank.
Edit:
Created a new ViewModel to resolve this, e.g.:
public class ColViewModel
{
public string Col1 {get;set;}
...
}
And replaced the Linq with:
...
cols = from b in a.RefTable select new ColViewModel{Col1 = b.Col1, ...},
...
Then, using the example from #Sacrilege below, I'm able to get the strings in the format I need them in.
What you are seeing is the string representation of the object you asked the view to render. You'll need to render each value separately to get your desired output.
#foreach(var col in item.cols)
{
if (!string.IsNullOrEmpty(col.Col1))
{
<div>#col.Col1</div>
}
if (!string.IsNullOrEmpty(col.Col2))
{
<div>#col.Col2</div>
}
if (!string.IsNullOrEmpty(col.Col3))
{
<div>#col.Col3</div>
}
}
You didn't mention the types for each of those fields but I guessed from your comment about them being blank that they were strings. I also added the extra markup because you wanted them each to appear on a separate line and that was a straight forward and easily maintainable way to do so.
#col is an Anonymous Type. So you must access the properties by using #col.Col1 etc. Because this is not supported in razor views in combination with Anonymous Types, you must convert it to an ExpandoObject in order to access the properties.
Take a look here for an example Dynamic Anonymous type in Razor causes RuntimeBinderException
I've written a SQL select statement that returns multiple fields from 1 record in the table.
Here is my statement:
-- (item_num being the PK)
SELECT item_num,
category,
weight,
cost,
description
FROM inv
WHERE item_num = #inumber;
How do I save each field into a variable?
I've seen samples written in while loops but my statement returns ints and chars so I would like to save them to the respectable variables and not an array.
Please bear with me as I'm new to working with database with coding. I just need to better understand the format.
I've searched for the answer but couldnt have anything related. Maybe my approach is all wrong.
Your help is appreciated.
Ultimately, you should be using a Datareader and from this it is possible to assign the values directly to the variables;
using (var rdr = db.ExecuteReader(cmd))
{
myIntValue = (int) rdr["IntValue"];
myStringValue = rdr["StringValue"].ToString();
}
However, in your case, my suggestion would be to use a DTO and populate these accordingly from your Data Layer
public class MyDTO
{
public int MyInt { get; set; }
public string MyString { get; set; }
}
and return IEnumerable<MyDTO>
First of all, your returns will not be ints and chars. It'll be strings. At least, that's my experience. And you should be storing them all in a MySQL datareader. This will allow you to do something like:
List<string> weight = new List<string>();
while(dataReader.Read())
{
weight.Add(dataReader["weight"]);
}
What this does is it will create a list of strings from all the results of your query that were under the "weight" column. From there, if you need them to be chars and ints, you can convert them. But I suggest you read up on MySQL datareaders. My example above isn't perfect, but it's a start.
hi guy's here is one problem regarding asp.net state managenment.
I want to store three values into single viewstate.Is it possible to store in single or i will go for three viewstate variables.
the basic need is that,I am using gridview rowcommand event for finding three values.
and i wanted to use these values in button_click event.it is directely not possible so i prefer viewstate.
if any other way to do this you can post.I am new in .net development so please share some knowledge of you.
You can make a class, and mark it with a Serializable attribute. Then make a list instance of that class and store it as 1 item in the viewstate. This is when you have a lot of values to store. However yours is a simple case I think:
[Serializable()]
class SomeData
{
public string Value1 {get; set;}
public string Value2 {get; set;}
public string Value3 {get; set;}
}
Add to viewstate:
ViewState.Add("myData", new SomeData () {Value1 = "A",
Value2 = "B",
Value2 = "3"});
Retrieve back from ViewState on postback:
var data = (SomeData)ViewState["myData"];
Label1.Text = string.Format("{0}, {1}, {2}",
data.Value1, data.Value2, data.Value3);
You can use whatever separator you want.
But your code would be a lot cleaner if you used three separate variables.
Let .net handle the viewstate. Using one variable seems like an unnecessary complication.
In your scenario you don't need ViewState - you can store them in variables in the code behind because the rowcommand and button_click will both fire on the same post back. You only need to store items in ViewState if they're needed across post backs.
You can use any separator. For e.g.:
ViewState["items"] = item1 + "~" + item2 + "~" + item3
For retrieving values from ViewState, split the values by "~".