I am having a problem displaying different text based on the result I get from my controller.
Column command_status_codeis returning value between 0 to 12 from the table. However, I would like to display different text based on the values I get from the controller.
i.e if I get 0 I would like to display Verify and if I get 1 I would like to display Active and so on.
I am not sure if I add the check in the view or do the conversion in the controller itself.
Here is the relevant code:
View
#model List<Models.AuditLogs>
<table>
<tr>
<th>User</th>
<th>Command Status Code</th>
</tr>
#foreach (var AuditLogsDetail in Model)
{
<tr>
<td>#AuditLogsDetail.user_id</td>
<td>#AuditLogsDetail.command_status_code</td>
</tr>
}
</table>
Controller
public ActionResult AuditLogs() {
string connectionstring = "MY_CONNECTION_STRING";
string sql = "select * from table_name";
SqlConnection conn = new SqlConnection(connectionstring);
SqlCommand cmd = new SqlCommand(sql, conn);
var Details = new List < AuditLogs > (); {
conn.Open();
SqlDataReader rdr = cmd.ExecuteReader();
while (rdr.Read()) {
var AuditLogsDetail = new AuditLogs {
user_id = rdr["user_id"].ToString(),
command_status_code = rdr["command_status_code"].ToString(),
};
Details.Add(AuditLogsDetail);
}
}
return View(Details);
}
Model
public class AuditLogs
{
public string user_id { get; set; }
public string command_status_code { get; set; }
}
}
I would leave the Controller for routing or controlling which view is called (which should be it's job, you should put as few presentation or application logic in the controller as possible).
Since this conversion is logic related to the model itself, I would put it in the Model class where it belongs and can be tested easily (if it becomes more complicated).
I would add a new property in the AuditLogsDetail model class which would return a string using a switch statement (since there are many possible values):
public class AuditLogsDetail
{
public int CommandStatusCode { get; set; }
public string CommandStatus
{
get
{
switch (CommandStatusCode)
{
case 0:
return "Verify";
case 1:
return "Active";
// and so on for the other 12 cases
default:
// you could throw an exception here or return a specific string like "unknown"
throw new Exception("Invalid Command Status Code");
}
}
}
}
In the Razor view you then simply have to call this property likewise:
<tr>
<td>#AuditLogsDetail.user_id</td>
<td>#AuditLogsDetail.CommandStatus</td>
</tr>
You could put a switch statement or if statement in the view but then you would clutter it. If you have several of these statements the view would be hard to read.
This sounds like a good candidate for an enum.
enum CommandStatus
{
def = 0,
success = 1,
A = 2,
B = 3,
...
}
public class AuditLogs
{
public string user_id { get; set; }
public CommandStatus command_status_code { get; set; }
}
Then when you fetch the value, just cast the int to the enum:
var AuditLogsDetail = new AuditLogs
{
user_id = rdr["user_id"].ToString(),
command_status_code = (CommandStatus)rdr["command_status_code"],
};
This doesn't provide the robustness of a switch, however.
in your view you can do something like this:
#model List<Models.AuditLogs>
<table>
<tr>
<th>User</th>
<th>Command Status Code</th>
</tr>
#foreach (var AuditLogsDetail in Model)
{
#if (#AuditLogsDetail.command_status_code == 0)
{
// what i need to do
}
#else if (#AuditLogsDetail.command_status_code == 1)
{
// what i need to do
}
<tr>
<td>#AuditLogsDetail.user_id</td>
<td>#AuditLogsDetail.command_status_code</td>
</tr>
}
</table>
Related
I want to auto select two checkboxes of the files named "File1" and "File2" that have the job order type of 1 or 2 or 3 when the page is open. I use a property bool type in the Model to return true if the "File1" and "File2" are found in a For loop. But somehow, all the checkboxes of other files are automatically checked, it should be only the checkboxes for the "File1" and "File2." Here are my codes:
Web.Config
<appsettings>
<add key="JobOrderType" value="1,2,3"/>
</appsettings>
CustomerDocument.cs - my view model
public class CustomerDocument
{
public bool IncludeInEmail { get; set; }
public long DocumentId { get; set; }
public string DisplayName { get; set; }
public string DocumentPath { get; set; }
public bool IsAutoSelectFile { get; set; }
}
ShowJobTypeController.cs
[HttpGet]
public ActionResult ShowJobType() {
try
{
//Make auto select for File1 and File2 for some certain job order types
List<CustomerCustomers> customerDocuments;
var myQuery = dbTest2.JobOrders.FirstOrDefault(z => z.Id == JobOrderId);
var jobOrderTypeId = new List<int>();
var configJOTypeValues = ConfigurationManager.AppSettings["JobOrderType"].Split(',');
for (var i = 0; i < configJOTypeValues.Length; i++)
{
var IdValue = 0;
if (int.TryParse(configJOTypeValues[i], out IdValue))
jobOrderTypeId.Add(IdValue);
}
ViewBag.IsAutoSelectFileForJobOrder = false;
var vmCustomerDoc = new ViewModels.CustomerDocument();
var isDocSelected = false;
foreach (var doc in customerDocuments)
{
if (doc != null && jobOrderTypeId.Contains(myQuery.JobTypeId) && (doc.DocumentName.Contains("File1") || doc.DocumentName.Contains("File2")))
{
vmCustomerDoc.IsAutoSelectFile = true;
isDocSelected = vmPCustomerDoc.IsAutoSelectFile;
ViewBag.IsAutoSelectFileForJobOrder = isDocSelected;
}
else
{
vmCustomerDoc.IsAutoSelectFile = false;
ViewBag.IsAutoSelectFileForJobOrder = isDocSelected;
}
}
}
catch
{
//Leave it empty
}
return View();
}
ShowJobType.cshtml
#{
ViewBag.Title = "ViewJobType";
Layout = "~/Views/Shared/_Layout.cshtml";
}
var docs = ViewBag.CustomerDocuments as List<VM.CustomerDocument>; //Links to CustomerDocument.cs View Model
<table>
<tr>
<th>Check to Include in Email</th>
<th>Files</th>
</tr>
#foreach (var doc in docs)
{
<tr>
<td>
#{
var docValue = doc.DocumentId + (string.IsNullOrEmpty(doc.DocumentPath) ? "" : "/" + doc.DocumentPath);
}
<input type="checkbox" name="DocEmail" id="DocEmail" value="#docValue" #(ViewBag.IsAutoSelectGuideForJobOrder) ? "checked=\"checked\"" : "") />
</td>
</tr>
}
</table>
Assuming ViewBag.CustomerDocuments has the view models that have been updated to set their IsAutoSelectFile property, you can change your logic for displaying checks to check for that property value on each document and use it to add the check to the input field.
<input type="checkbox" name="DocEmail" id="DocEmail" value="#docValue" #(doc.IsAutoSelectFile) ? "checked" : "") />
Additionally, in your current logic in the back end, once isDocSelected is set to true, it will always be true. If you use the ViewModel's property instead of the view bag, you can remove it's usage from your logic anyways.
I am pretty new to MVC however I have been trying to use a dropdownlist in a view which has a model of type List<>. The reason for this is to create multiple records on a single page.
I have been able to successfully create a view that is not of type List<> and a single record at a time, but in spite of a lot of googling can not implement the solution when I implement the view with a model of type List<>.
Model
public class Product
{
public int ProductID { get; set; }
public string Description { get; set; }
public int VatRateID { get; set; }
[ForeignKey("VatRateID")]
public virtual VatRate VatRate { get; set; }
}
Controller
// GET: /Product/Bulkdata
public ActionResult BulkData()
{
PopulateVatRateDropDownList();
List<Product> model = new List<Product>();
model.Add(new Product
{
ProductID = 0,
Description = "",
VatRateID = 1
}
);
return View(model);
}
//
// POST: /Product/Bulkdata
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult BulkData(
[Bind(Include = "Description,VatRateID")]
List<Product> products)
{
try
{
if (ModelState.IsValid)
{
foreach (var p in products)
{
db.Product.Add(p);
}
db.SaveChanges();
return RedirectToAction("Index");
}
}
catch (DataException)
{
ModelState.AddModelError("", "Bulk - Unable to save changes, Try again, and if the probelm persists contact your administrator");
}
PopulateVatRateDropDownList();
return View(products);
}
private void PopulateVatRateDropDownList(object selectedVatRate = null)
{
var vatRateQuery = from v in db.VatRate
select v;
ViewBag.VatRateID = new SelectList(vatRateQuery, "VatRateID", "VatRateDescription", selectedVatRate);
}
View
#if (Model != null && Model.Count > 0)
{
int j = 0;
foreach (var i in Model)
{
<tr style="border:1px solid black">
<td>
#Html.EditorFor(m => m[j].Description)
#Html.ValidationMessageFor(m => m[j].Description)
</td>
<td>
#Html.DropDownList("VatRateID", String.Empty)
#Html.ValidationMessageFor(m => m[j].VatRateID)
</td>
<td>
#if (j > 0)
{
Remove
}
</td>
</tr>
j++;
}
}
When I run the application with this code then 0 is always past back to vatRateID. I have tried numerous other solution other than the above including
ASP.NET MVC DropDownListFor with model of type List<string>. As I have mentioned I am new to mvc so I know there is probably something simple that I am missing. Any help would be hugely appreciated.
Thanks
Answered by Stephen in comments:
In the view, changed the foreach to a for loop as per the article in Stephen's comment and used DropdDownListFor
#Html.DropDownListFor(m => m[i].VatRateID, (IEnumerable<SelectListItem>)ViewBag.VatRateList)
Also amended the controller to rename the ViewBag property to VatRateList
'
private void PopulateVatRateDropDownList(object selectedVatRate = null)
{
var vatRateQuery = from v in db.VatRate
select v;
ViewBag.VatRateID = new SelectList(vatRateQuery, "VatRateID", "VatRateDescription", selectedVatRate);
}
'
I am trying to populate an HTML table with data from a table in my database. The issue is simply that the HTML table is not getting populated with any data.
Here is the ViewModel:
public class TestViewModel
{
public string MatchedId { get; set; }
public string UnmatchedId { get; set; }
public string Auth { get; set; }
public DateTime CreditDate { get; set; }
public string CreditNumber { get; set; }
public decimal CreditAmount { get; set; }
public DateTime DeniedDate { get; set; }
public int DeniedReasonId { get; set; }
public string DeniedNotes { get; set; }
}
Controller Action:
[HttpPost]
public ActionResult UploadValidationTable(HttpPostedFileBase csvFile)
{
var inputFileDescription = new CsvFileDescription
{
SeparatorChar = ',',
FirstLineHasColumnNames = true
};
var cc = new CsvContext();
var filePath = uploadFile(csvFile.InputStream);
var model = cc.Read<Credit>(filePath, inputFileDescription);
try
{
var entity = new Entities();
//model here is the .csv, doesn't have anything to do with this issue
foreach (var item in model)
{
var tc = new TemporaryCsvUpload
{
Id = item.Id,
CreditAmount = item.CreditAmount,
CreditDate = item.CreditDate,
CreditNumber = item.CreditNumber,
DeniedDate = item.DeniedDate,
DeniedReasonId = item.DeniedReasonId,
DeniedNotes = item.DeniedNotes
};
entity.TemporaryCsvUploads.Add(tc);
}
entity.SaveChanges();
System.IO.File.Delete(filePath);
//This is where the database table is getting filled
entity.Database.ExecuteSqlCommand("Insert into CsvReport Select p.Id as MatchedId, case when p.Id is null then t.Id end as UnmatchedId, p.Auth,p.CreditDate, p.CreditNumber,p.CreditAmount, p.DeniedDate,p.DeniedReasonId, p.DeniedNotes from TemporaryCsvUpload t left join PermanentTable p on p.Id = t.Id;");
TempData["Success"] = "Updated Successfully";
}
catch (LINQtoCSVException)
{
TempData["Error"] = "Upload Error: Ensure you have the correct header fields and that the file is of .csv format.";
}
return View("Upload");
}
View:
#model IEnumerable<TestProject.TestViewModel>
#if (Model != null)
{
foreach (var item in Model.Where(x => x.IdMatched != null))
{
<tr>
<td>
#item.MatchedId
</td>
<td>
#item.Auth
</td>
<td>
#item.CreditDate
</td>
<td>
#item.CreditNumber
</td>
<td>
#item.CreditAmount
</td>
<td>
#item.DeniedDate
</td>
<td>
#item.DeniedReasonId
</td>
<td>
#item.DeniedNotes
</td>
</tr>
}
}
It's a little weird because I am populating the database with an SQL command. What am I missing here? Do I need to try and pass it through the controller action? Let me know if you need more information. Thanks!
Edit
I tried to pass the instance through, but I may still be doing it incorrectly:
var testModel = new TestViewModel();
return View("Upload", testModel);
Here is what its padding through:
public class TestViewModel
{
public IEnumerable<Test> Test { get; set; }
}
Made an answer so essentially the view doesn't know what to render you need to pass an actual filled model (in your case an IEnumerable to the view). This can be done using the method:
View("Upload", viewModelList);
Controller.View docs on MSDN
It looks like you are not adding any data to your view model.
If your view model is a collection of Test objects, you need to add some
Test objects to the collection.
var model = new TestViewModel()
{
Test = new List<Test>() { new Test(), new Test(), ... }
}
return View("Upload", model);
Hi I'm new in MVC now working with dual listboxes. I wanted to move the data from listbox1 to listbox2. For that I'm using the following code:
View
<tbody>
<tr>
<td>
<%:Html.HiddenFor(m=>m.objMemberAccessRights.Id) %>
<%:Html.ListBoxFor(model =>model.objMemberAccessRights.AvailableSelected, newMultiSelectList(Model.objMemberAccessRights.AvailableNames, "Id", "InstituteName", Model.objMemberAccessRights.AvailableSelected), new { size="8"})%>
</td>
<td>
<br/>
<%:Html.ActionLink(">>", "AddNames", "MemberDetails") %>
<br/>
<br/>
<%:Html.ActionLink("<<", "RemoveNames", "MemberDetails") %>
</td>
<td>
<%:Html.ListBoxFor(model=>model.objMemberAccessRights.RequestedSelected,newMultiSelectList(Model.objMemberAccessRights.RequestedNames,"Id","InstituteName",Model.objMemberAccessRights.RequestedSelected), new { size="8"}) %>
</td>
</tr>
</tbody>
Controller
//
// GET: /MemberDetails/Create
public ActionResult Create()
{
MemberDetailsWrapper MD = new MemberDetailsWrapper();
MD.objMemberAccessRights = newMemberAccessRights{ AvailableNames = getAllInstituteNameList(), RequestedNames = new List<InstituteInformation>() };
return View(MD);
}
//AddNames
public ActionResult AddNames(MemberDetailsWrapper MD, string add)
{
ModelState.Clear();
RestoreSavedState(MD);
if (!add.Equals(">>"))
{
if (MD.objMemberAccessRights.AvailableSelected != null)
{
var names = getAllInstituteNameList().Where(p => MD.objMemberAccessRights.AvailableSelected.Contains(p.InstituteName));
MD.objMemberAccessRights.RequestedNames.AddRange(names);
MD.objMemberAccessRights.AvailableSelected = null;
}
}
SaveState(MD);
return View(MD);
}
//RemoveNames
public ActionResult RemoveNames(MemberDetailsWrapper MD, string remove)
{
ModelState.Clear();
RestoreSavedState(MD);
if (!remove.Equals("<<"))
{
if (MD.objMemberAccessRights.RequestedSelected != null)
{
MD.objMemberAccessRights.RequestedNames.RemoveAll(p => MD.objMemberAccessRights.RequestedSelected.Contains(p.InstituteName));
MD.objMemberAccessRights.RequestedSelected = null;
}
SaveState(MD);
return View(MD);
}
#regionSupportFuncs
public void SaveState(MemberDetailsWrapper MD)
{
MD.objMemberAccessRights.SavedRequested = string.Join(",", MD.objMemberAccessRights.RequestedNames.Select(p =>p.InstituteName).ToArray());
////Available Names = All - Requested
MD.objMemberAccessRights.AvailableNames = getAllInstituteNameList().Except(MD.objMemberAccessRights.RequestedNames).ToList();
}
//RestoreSavedState
public void RestoreSavedState(MemberDetailsWrapper MD)
{
MD.objMemberAccessRights.RequestedNames = new List<InstituteInformation>();
if (!string.IsNullOrEmpty(MD.objMemberAccessRights.SavedRequested))
{
string[] nameids = MD.objMemberAccessRights.SavedRequested.Split(',');
var name = getAllInstituteNameList().Where(p =>nameids.Contains(p.InstituteName));
MD.objMemberAccessRights.RequestedNames.AddRange(name);
}
}
#endregion
In model:
public class InstituteInformation
{
public int Id { get; set; }
public string InstituteName { get; set; }
}
public class MemberAccessRights
{
public int Id { get; set; }
public List<InstituteInformation> AvailableNames { get; set; }
public string[] AvailableSelected { get; set; }
public List<InstituteInformation> RequestedNames { get; set; }
public string[] RequestedSelected { get; set; }
public string SavedRequested { get; set; }
}
Here When I click on >> button then this button returns the Error:
Object reference not set to an instance of an object. Description: An
unhandled exception occurred during the execution of the current web
request. Please review the stack trace for more information about the
error and where it originated in the code. Exception Details:
System.NullReferenceException: Object reference not set to an instance
of an object.
Source Error:
Line 170: public void RestoreSavedState(MemberDetailsWrapper MD)
Line 171: {
Line 172: MD.objMemberAccessRights.RequestedNames = new List<InstituteInformation>();
Line 173:
Line 174: if (!string.IsNullOrEmpty(MD.objMemberAccessRights.SavedRequested))
Your object is null (MD.objMemberAccessRights that is). MVC will not pass that back in the WHOLE model with out tweaking. especially lists
The simplest solution is to assume the lists are empty rebuild the lists after each request. By the looks of your code you are not persisting the data but i assume you will at the end?
What you need to do is persist the item after it has been moved and then requery the dB to recreate the lists.
You can avoid all this dB chattiness using jquery but that has its own challenges.
I am very new to MVC 3 framework. I have added an Entity with the EntityFramework 6.0, and in my controller, I would like to query the entity for all "DeviceInterfaces" which belong to a particular device. My view is throwing this error:
The model item passed into the dictionary is of type System.Data.Entity.Infrastructure.DbQuery`1[<>f__AnonymousType1`2[System.String,System.String]], but this dictionary requires a model item of type System.Collections.Generic.IEnumerable`1[FindDevice.DeviceInterfaces].
My Controller:
public ActionResult DeviceName(string name)
{
SampleEntities sampleEntities = new SampleEntities();
try
{
var Model = (from dev in sampleEntities.NetworkDevices
where dev.Name == name
from inter in sampleEntities.DeviceInterfaces
where inter.NetworkDevice.Id == dev.Id
//select inter);
select new { DeviceName = dev.Name, InterfaceName = inter.Name});
return View(Model);
}
catch
{
}
return View();
}
My View:
#model IEnumerable<FindDevice.DeviceInterfaces>
#{
ViewBag.Title = "DeviceName";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Displaying Device with name "#ViewBag.MyName"</h2>
<table>
<tr>
<th>Device</th>
<th>Interface</th>
<th>IPv4 Address</th>
<th>Subnet Mask</th>
<th>CIDR</th>
<th>Network</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>item.NetworkDevice.Name</td>
<td>#item.Name</td>
<td>#item.IPv4Address</td>
<td>#item.IPv4SubnetMask</td>
<td>#item.CIDR</td>
<td>#item.Subnet</td>
</tr>
}
I understand why the error is thrown, what I don't understand is what I can change my #model statement to so that I can display the Device Name, as well as the Interface Name and all other interface properties in this view.
I'd suggest using a strongly typed model. Add the below class in Models folder
public class DeviceInterfaceModel
{
public string DeviceName { get; set; }
public string InterfaceName { get; set; }
public string IPv4Address { get; set; }
public string IPv4SubnetMask { get; set; }
public string CIDR { get; set; }
public string Subnet { get; set; }
}
Then map the query results to a List<DeviceInterfaceModel> in your controller
public ActionResult DeviceName(string name)
{
SampleEntities sampleEntities = new SampleEntities();
try
{
var model = (from dev in sampleEntities.NetworkDevices
where dev.Name == name
from inter in sampleEntities.DeviceInterfaces
where inter.NetworkDevice.Id == dev.Id
select new DeviceInterfaceModel
{
DeviceName = dev.Name,
InterfaceName = inter.Name,
IPv4Address = inter.IPv4Address,
IPv4SubnetMask = inter.IPv4SubnetMask,
CIDR = inter.CIDR,
Subnet = inter.Subnet
}).ToList();
return View(model);
}
catch
{
}
return View();
}
and change the model type to IEnumerable<DeviceInterfaceModel> in your view
#model IEnumerable<DeviceInterfaceModel>
#{
ViewBag.Title = "DeviceName";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Displaying Device with name "#ViewBag.MyName"</h2>
<table>
<tr>
<th>Device</th>
<th>Interface</th>
<th>IPv4 Address</th>
<th>Subnet Mask</th>
<th>CIDR</th>
<th>Network</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>#item.DeviceName</td>
<td>#item.InterfaceName</td>
<td>#item.IPv4Address</td>
<td>#item.IPv4SubnetMask</td>
<td>#item.CIDR</td>
<td>#item.Subnet</td>
</tr>
}