Html table not populating from ViewModel - c#

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);

Related

ASP.NET MVC 5 POST checkboxfor to controller with onclick using Ajax

I am rather new to MVC so please bear with me.
My goal at hand is to POST a checkboxfor html helper that contains the property called "Verified" to my controller using Ajax. I did mounds of research and yielded this post which is very similar, however it still does not reach the controller and instead I receive a 505 error. checkboxfor Ajax link. This post didn't show how the controller handled the data being passed to the and I am lead to believe that may be my issue but I am not certain. Or it may be something with the foreach block doing some weird stuff.(Side note on the table, we use datatables.net library for table formatting). Below is my code...
Model (comes directly from the EF entity class and is brought in via Meta Data)
namespace Entities
{
public class FPDrinkingWater : AccessibleRecord<FPDrinkingWater>
{
public FPDrinkingWater();
public bool Approved { get; set; }
public string ApprovedBy { get; set; }
public DateTime? ApprovedDate { get; set; }
public string Clorinated { get; set; }
public DateTime? CollectionDate { get; set; }
public TimeSpan? CollectionTime { get; set; }
public string Collectors { get; set; }
public string Comments { get; set; }
public override string CreatedBy { get; set; }
public override DateTime CreatedDate { get; set; }
public bool Deleted { get; set; }
public bool EC { get; set; }
public override int Id { get; set; }
public string Location { get; set; }
public bool RAG { get; set; }
//
// Summary:
// Drinking water record
public override string RecordName { get; }
public short? Replicate { get; set; }
public virtual SampleLog SampleLog { get; set; }
public int SID { get; set; }
public bool SWAT_LAB { get; set; }
public bool TIMS { get; set; }
public override string UpdatedBy { get; set; }
public override DateTime? UpdatedDate { get; set; }
public bool Verified { get; set; }
public string VerifiedBy { get; set; }
public DateTime? VerifiedDate { get; set; }
public override void UpdateTo(FPDrinkingWater entity);
protected override void ParameterChecks();
}
}
Controller action to populate view:
//unverified Drinking Water log
[OpenAction]
public async Task<ActionResult> UnverifiedDrinkingWaterLog(AlertModel alert)
{
//return partial Drinking water log view
return await UnverifiedDataTableAsync<FPDrinkingWater>(alert);
}
Definition of UnverifiedDataTableAsync:
//Unverified data table
[OpenAction]
public async Task<ActionResult> UnverifiedDataTableAsync<TEntity>(AlertModel alert, string viewName = null) where TEntity : class
{
// get data
var data = (from a in await LimsManager.AllAsync<TEntity>()
select a).ToList();
//LimsManager.AllAsync returns the entire context contents of the Entity in a List then the view tests if `Verified` is not populated.
// create sample log model with alert
var response = new TableModel<TEntity>
{
Alert = alert,
Data = data
};
// return partial data view
return PartialView(viewName ?? $"_Unverified{typeof(TEntity).Name}Table", response);
}
Controller update action:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> VerifyDrinkingWater(FPDrinkingWater drinkingWater, string id )
{
//create alert model
var response = new AlertModel();
//check model state
if(ModelState.IsValid)
{
//add the verifier to the DrinkingWater record
drinkingWater.Verified = true;
drinkingWater.VerifiedBy = User.Identity.Name;
drinkingWater.VerifiedDate = DateTime.Now;
//update the drinking water with the new verified information
var result = await LimsManager.UpdateAsync(drinkingWater);
//check update result
if(result.Succeeded)
{
response.AddInfo($"All SID's successfully verified in the database.", BSContextualTypes.success);
}
else
{
//add failure to alert
response.AddInfo($"Unable to verify SID's in database.", BSContextualTypes.warning);
}
}
else
{
InvalidState(response);
}
return await UnverifiedDrinkingWaterLog(response);
}
The view should iterate over the context of the entity and building the table for each record it finds that is not verified:
#model MyProgram.Application.TableModel<Entities.FPDrinkingWater>
#{
Layout = null;
var insertionMode = InsertionMode.Replace;
var fail = "displayFailure";
var target = "UnverifiedDrinkingWaterContent";
var ajax = "UnverifiedDrinkingWaterLogLoader";
var verify = Html.UserHasClaim("FP/DrinkingWater/VerifyDrinkingWater");
}
<br />
#if (Model != null && Model.Alert != null && Model.Alert.Message != null)
{
#Html.Alert(Model.Alert)
}
#MyHelper.Loader(ajax)
<table id="UnverifiedDrinkingWaterTable" class="table table-hover">
<thead>
<tr>
<th>#Html.LabelFor(m => m.Data.FirstOrDefault().SID)</th>
<th>#Html.LabelFor(m => m.Data.FirstOrDefault().Location)</th>
<th>#Html.LabelFor(m => m.Data.FirstOrDefault().Replicate)</th>
<th>#Html.LabelFor(m => m.Data.FirstOrDefault().CollectionDate)</th>
<th>#Html.LabelFor(m => m.Data.FirstOrDefault().CollectionTime)</th>
<th>#Html.LabelFor(m => m.Data.FirstOrDefault().Collectors)</th>
<th>#Html.LabelFor(m => m.Data.FirstOrDefault().Clorinated)</th>
<th>#Html.LabelFor(m => m.Data.FirstOrDefault().Comments)</th>
<th>#Html.LabelFor(m => m.Data.FirstOrDefault().Verified)</th>
</tr>
</thead>
<tbody>
#if (Model.Data.Any(v => !v.Verified))
{
foreach (var log in Model.Data.Where(v => !v.Verified))
{
<tr data-record-id="#log.Id">
<td>#log.SID</td>
<td>#log.Location</td>
<td>#log.Replicate</td>
<td>#log.CollectionDate.Value.ToShortDateString()</td>
<td>#log.CollectionTime</td>
<td>#log.Collectors</td>
<td>#log.Clorinated</td>
<td>#log.Comments</td>
<td>#Html.CheckBoxFor(m => log.Verified, new { data_url = Url.Action("VerifyDrinkingWater", "DrinkingWater"), id = "mycheckbox", #class = "toggle" })</td>
</tr>
}
}
else
{
<tr>
<td colspan="#Html.ColumnCount(3)"><em>No Drinking Water data to verify.</em></td>
</tr>
}
</tbody>
</table>
<hr />
#if (Model.Data.Count > 0)
{
<script>
$(document).ready(function () {
makeDataTable('UnverifiedDrinkingWaterTable');
$(function () {
$('.toggle').change(function () {
var self = $(this);
var url = self.data('url');
var id = self.attr('id');
var value = self.prop(':checked');
$.ajax({
url: url,
data: { id: id },
type: 'POST',
success: function (result) {
alert(response)
}
});
});
});
});
</script>
}
Generated HTML:
<tr data-record-id="3" role="row" class="odd">
<td>5</td>
<td>Location</td>
<td>1</td>
<td>3/31/1997</td>
<td>18:00:00</td>
<td>YY</td>
<td>Y</td>
<td></td>
<td><input class="toggle" data-url="/FP/DrinkingWater/VerifyDrinkingWater" data-val="true" data-val-required="The Verified field is required." id="mycheckbox" name="log.Verified" type="checkbox" value="true"><input name="log.Verified" type="hidden" value="false"></td>
</tr>
And that data-record-id matches the ones in the database.

Datastore Query Array

I am trying run a Datastore query to get a list of names and prices. However, I keep getting this error message:
Cannot implicitly convert type 'Google.Cloud.Datastore.V1.DatastoreQueryResults' to 'System.Collections.Generic.List<TestApp.Models.AllSportsStore>'
This is the code I am using:
AllSportsStore.cs Page
public DatastoreDb _db;
[BindProperty]
public List<AllSportsStore> SportsStoreList { get; set; }
public void OnGet()
{
Environment.SetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS", Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "xxxxx.json"));
_db = DatastoreDb.Create("projectid");
Query query = new Query("Sports_db");
IEnumerable<Entity> stores = _db.RunQuery(query).Entities;
SportsStoreList = stores.Select(_ => new AllSportsStore
{
Name = _["Name"].ToString(),
Price = _["Price"].ToString(),
}).ToList();
}
AllSportsStore.cshtml page
#for (var i = 0; i < Model.SportsStoreList.Count; i++)
{
<tr>
<td>
#Html.DisplayFor(model => model.SportsStoreList[i].Name)
</td>
<td>
#Html.DisplayFor(model => model.SportsStoreList[i].Price)
</td>
</tr>
}
This is the image of the datastore
Updated code result based on a comment
As already stated in the comments, you are trying to assign the wrong type to the SportsStoreList property.
Have a model to hold entity details from storage
public class SportsStoreItem {
public string Name { get; set; }
public decimal Price { get; set; }
}
Use the model in the AllSportsStore.cs Page
public class AllSportsStore : PageModel {
private readonly DatastoreDb _db;
public AllSportsStore() {
_db = DatastoreDb.Create("projectid");
}
[BindProperty]
public List<SportsStoreItem> SportsStoreList { get; set; }
public IActionResult OnGet() {
Query query = new Query("Sports_db");
IEnumerable<Entity> stores = _db.RunQuery(query).Entities;
SportsStoreList = stores.Select(_ => new SportsStoreItem {
Name = (string)_["Name"],
Price = (decimal)_["Price"]
}).ToList();
return Page();
}
}
Note how the entities retrieved from the data store db were converted to strongly typed objects.
You should then be able to access the items in the list in the view/page.
#for (var i = 0; i < Model.SportsStoreList.Count; i++) {
<tr>
<td>
#Html.DisplayFor(model => model.SportsStoreList[i].Name)
</td>
<td>
#Html.DisplayFor(model => model.SportsStoreList[i].Price)
</td>
</tr>
}

c# mvc 5 call json web service and save on database

Greetings i want to call a web api that returns a json string from From Controller and i want to map it on a class so i can save the data on the database.But i dont understand how to map each data on the json with the class.
I only get the message that is succeed.
my code is:
public ActionResult API()
{
var client = new WebClient();
var text = client.DownloadString("https://www.example.com/api/all-users?name=user%20&pass=password");
wclients wclients = JsonConvert.DeserializeObject<wclients>(text);
if (wclients.message == "success")
{
ViewBag.name = ("name = " + wclients.name);
}
return View();
}
my view is this:
#foreach (var item in ViewBag.name) {
<tr>
<td>
#item
</td>
</tr>
}
The Response from web api is:
{"status":true,"message":"success","data":[{"name":"test test","email":"senthil#nscript.in","phone":"1234567890","affiliated_id":null,"account":{"real":[{"login":"1001175","pass":"4pJccK8AUWw8"},{"login":"3001180","pass":"4AeCqasw7jX2"},{"login":"3001182","pass":"fS2tf6Gsej7C"}]
try the below code:
public ActionResult API()
{
var client = new WebClient();
var text = client.DownloadString("https://www.example.com/api/all-users?
name=user%20&pass=password");
var wclients = JsonConvert.DeserializeObject<dynamic>(text);
if (wclients.message == "success")
{
var data = wclients.data;
}
return View();
}
wclients.name will never contain anything because there is not a property called "name" at the top level of the JSON object structure.
To access the name property you would need to enumerate through the data array (which should exist as a property on the wclients class) and get the name from there.
Update
As per the example below:
public class wclients
{
public bool status { get; set; }
public string message { get; set; }
public IEnumerable<Account> data { get; set; }
}
public class Account
{
public string name { get; set; }
public string email { get; set; }
public string phone { get; set; }
}
public ActionResult API()
{
var client = new WebClient();
var text = client.DownloadString("https://www.example.com/api/all-users?name=user%20&pass=password");
wclients clients = JsonConvert.DeserializeObject<wclients>(text);
if (wclients.message == "success")
{
ViewBag.name = clients.data;
}
return View();
}
and in the view
#foreach (var item in ViewBag.name)
{
<tr>
<td>
#item.name
</td>
</tr>
}
The JSON must map directly to your C# class.
For example, if the JSON has the following:
"name":"test test",
"email":"senthil#nscript.in"
Then your class (eg Person.cs) must have the same properties:
public class Person{
public string name {get;set}
public string email {get;set}
}
Then you would do:
Person person = JsonConvert.DeserializeObject<Person>(json);
In your example, you probably need wclients.data
if (wclients.message == "success")
{
ViewBag.name = ("name = " + wclients.data.name);
}
Finally, the name wclients suggests there are multiple... in which case:
var names = new List<string>();
foreach(var client in wclients){
if (client.message == "success")
{
names.Add("name = " + client.data.name);
}
}

How can I display a model property name that is coming from the database?

I currently am pulling a list of url's from a view using Entity Framework 5 and MVC 5. I have the view populating all the links but I need each link to display their 'LinkState' names like in my model so it will output:
Alabama
Georgia
etc.
with the link attached to the LinkState. Instead of the view foreach loop saying State Link. I cant get my model/controlled to pull the correct information.
Repository:
public class LinkRepository
{
private readonly LinkLibrary _entities = new LinkLibrary ();
public LinkRepository()
{
_entities = new LinkLibrary ();
}
public List<LinkModels> RetrieveStateLink(string year)
{
return
_entities.vw_URLLibrary.Where(s => s.YEAR.Equals(year) && s.URL_TYPE.Equals("United States")).Select(m => new LinkModels()
{
UrlLink = m.LinkLocation
}).ToList();
}
}
Model
public class LinkModels
{
public string LinkYear { get; set; }
public string LinkState { get; set; }
public string UrlLink { get; set; }
public string LinkType { get; set; }
public List<string> ListOfUrls{ get; set; }
}
Controller
public ActionResult GetStateLinks()
{
var stateLink = new List<string>();
var model = rr.RetrieveStateLinks("2014").Select(m=> m.UrlLink).ToList();
foreach (var s in model)
{
stateLink.Add(s);
}
var rm = new LinkModels();
rm.ListOfUrls = stateLink;
return View(rm);
}
View
#foreach (var item in Model.StateLinkList)
{
<td>
State Link
</td>
}
Your issue is that you are returning a List of strings as opposed to a list of LinkModels. I updated the repository to return the url and link name
removed some unneccessary code in your controller and updated it to work with a list of LinkObjects. Then updated the view to display the info.
You will have to update your view #model List<LinkModels> instead of #model List<string>
public class LinkRepository
{
private readonly LinkLibrary _entities = new LinkLibrary ();
public LinkRepository()
{
_entities = new LinkLibrary ();
}
public List<LinkModels> RetrieveStateLink(string year)
{
return
_entities.vw_URLLibrary.Where(s => s.YEAR.Equals(year) && s.URL_TYPE.Equals("United States")).Select(m => new LinkModels()
{
LinkState = m.LinkState,
UrlLink = m.LinkLocation
}).ToList();
}
}
public ActionResult GetStateLinks()
{
var stateLink = new List<LinkModels>();
var model = rr.RetrieveStateLinks("2014");
return View(model);
}
#foreach (var item in Model)
{
<td>
#item.LinkState
</td>
}
Controller
public ActionResult GetStateLinks()
{
var model = rr.RetrieveStateLinks("2014");
return View(model);
}
View (change your view model to list of LinkModels)
#foreach (var item in Model)
{
<td>
#item.LinkState
</td>
}

Which Model Statement to use in MVC 3

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>
}

Categories

Resources