Binding a calculated field in Blazor - blazor-server-side

I have a form that allows me to create an entity. There are a few decimal model properties bound and working. A new requirement came where I have to show totals as the decimal field value are changed.
So, the user will change the four numeric inputs to any value and I need the QTotal to update on the fly. Here is what I did and it doesn't work as intended. The QTotal only picks up the value of Q1:
Page:
<DxFormLayoutGroup Caption="Additional Budget Info (Optional)" ColSpanMd="12">
#*Inputs ffor Q1, Q2, Q3, Q4*#
<DxFormLayoutItem Caption="Q Total:" ColSpanMd="2">
<Template >
<DxSpinEdit Id="approvedTotals" #bind-Value="#Model.QTotal" DisplayFormat="N2" ReadOnly="true"/>
</Template >
</DxFormLayoutItem >
</DxFormLayoutGroup>
Code behind:
public class BudgetReleaseRequestViewModel
{
[Display(Name = "Approved Q1")]
public decimal? ApprovedQ1 { get; set; }
[Display(Name = "Approved Q2")]
public decimal? ApprovedQ2 { get; set; }
[Display(Name = "Approved Q3")]
public decimal? ApprovedQ3 { get; set; }
[Display(Name = "Approved Q4")]
public decimal? ApprovedQ4 { get; set; }
public decimal? QTotal
{
get => ApprovedQ1 ?? 0 + ApprovedQ2 ?? 0 + ApprovedQ3 ?? 0 + ApprovedQ4 ?? 0;
set => QTotal = value;
}
public decimal? QDelta => ApprovedAnnualBudget ?? 0 - QTotal;
}
Obviously, it is not going to be this simple as there needs to be some kind of event binding to update the value of QTotal for the UI as per Blazor. Would like some help here.

Related

ASP.NET Core : how to sum the column based on another tables's column

I am new to ASP.NET Core.
public List<LineItem> LineItems { get; set; }
public double Total => this.LineItems.Sum(x => x.LineTotal);
LineItem
public int Quantity { get; set; }
public double UnitPrice { get; set; }
public double LineTotal => Math.Round(this.Quantity * this.UnitPrice, 2);
The error said Sum() is not used properly.
ArgumentNullException: Value cannot be null. (Parameter 'source')
I think this error may be due to Object reference not set to an instance of an object,you could try to modify the code:
public List<LineItem> LineItems { get; set; }
to
public List<LineItem> LineItems =new List<LineItem>();
And I get the excepted result after I changed the codes,If you have any other problems please tell me more details.
Result

Asp.Net Mvc, Rdlc reports - How do I show associated name from parent table instead of just it's ID?

I am using Asp.net MVC 5 with EF 6 for a college project. I am using RDLC for generating reports.
I created a simple report showing Items and its associated details. But I have no idea how to show Manufacturer Name of an Item instead of its ManufacturerID.
Could anyone help me out with this?
It has been so many days, and I am still struggling with reports. Looks like, its easy with webforms and ADO.net. But I am finding it hard to incorporate reports in MVC using Entity Framework.
If there are better options please let me know.
Well for this report I refered to this tutorial .
Here is my code for generating reports:
public ActionResult Report(string id)
{
LocalReport lr = new LocalReport();
string path = Path.Combine(Server.MapPath("~/Reports"), "Report_item.rdlc");
if (System.IO.File.Exists(path))
{
lr.ReportPath = path;
}
else
{
return View("Index");
}
List<Item> cm = new List<Item>();
cm = db.Items.ToList();
ReportDataSource rd = new ReportDataSource("MyData_Item", cm);
lr.DataSources.Add(rd);
string reportType = id;
string mimeType;
string encoding;
string fileNameExtension;
string deviceInfo =
"<DeviceInfo>" +
" <OutputFormat>" + id + "</OutputFormat>" +
" <PageWidth>8.5in</PageWidth>" +
" <PageHeight>11in</PageHeight>" +
" <MarginTop>0.5in</MarginTop>" +
" <MarginLeft>1in</MarginLeft>" +
" <MarginRight>1in</MarginRight>" +
" <MarginBottom>0.5in</MarginBottom>" +
"</DeviceInfo>";
Warning[] warnings;
string[] streams;
byte[] renderedBytes;
renderedBytes = lr.Render(
reportType,
deviceInfo,
out mimeType,
out encoding,
out fileNameExtension,
out streams,
out warnings);
return File(renderedBytes, mimeType);
}
Item Model :
public class Item
{
public int ID { get; set; }
[Required]
[Display(Name="Item")]
public string Name { get; set; }
[Display(Name="Generic Name")]
public int? DrugGenericNameID { get; set; }
[Display(Name = "Manufacturer")]
public int? ManufacturerID { get; set; }
[Display(Name = "Categeory")]
public Categeory? Categeory { get; set; }
public int AlertQty { get; set; }
public string Description { get; set; }
[Display(Name = "Last Update")]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime? LastUpdated { get; set; }
//reference entity
public virtual DrugGenericName DrugGenericName { get; set; }
public virtual Manufacturer Manufacturer { get; set; }
public virtual ICollection<Stock> Stocks { get; set; }
public virtual ICollection<PurchaseItem> PurchaseItems { get; set; }
}
public enum Categeory
{
Drug,
Supplies,
other
}
Here is my report. How can I derive associated Names instead of its ID?
Generally RDLC reports use a fairly flat structure for their data model - you can have associated child tables within the report; but for a flat table in your report all of your fields should be in the same table/model.
So, consider this as your Item model (removed most of your original properties for brevity):
public class Item
{
public int ID { get; set; }
[Required]
[Display(Name="Item")]
public string Name { get; set; }
// Properties as per your original model ...
//reference entity
public virtual DrugGenericName DrugGenericName { get; set; }
public virtual Manufacturer Manufacturer { get; set; }
public virtual ICollection<Stock> Stocks { get; set; }
public virtual ICollection<PurchaseItem> PurchaseItems { get; set; }
// Added properties:
public string ManufacturerName {
get { return Manufacturer.Name; }
}
// etc.
}
You'll then be able to reference the Manufacturer Name directly.

check empty or invalid properties

I have a model with validation properties. On a post back to server I would like to check if model values are empty or for example dropdownlist should not be have 0 or something!
Depending on how you have created your models you could do the validation on he model properties.
Example:
public class Foo
{
public long Id { get; set; }
[Required(ErrorMessage = "Please enter name")]
public string Name { get; set; }
[Required(ErrorMessage = "Please select a gender")]
public string SelectedGenderId{ get; set; }
}
Then in your view under your dropDownList:
#Html.ValidationMessageFor(m=> m.SelectedGenderId)
EDIT thanks to #danludwig:
Then in your controller you can validate the state of your model but doing this:
if (ModelState.IsValid)
{
// do your updates/saves
}
I hope that's is what you are after.

asp.net MVC: TryUpdateModel doesn't bind DateTime properly

I'm having issues with a date property not binding correctly using TryUpdateModel in MVC.
I am using a POCO class and a corresponding viewModel.
public class ContactModel
{
public int Id { get; set; }
[Display(Name = "First Name")]
[StringLength(50)]
[Required(ErrorMessage = "First name must be entered.")]
public string ContactGivenName { get; set; }
[Display(Name = "Last Name")]
[StringLength(50)]
[Required(ErrorMessage = "Last name must be entered.")]
public string ContactFamilyName { get; set; }
....
[Display(Name = "Date of Birth")]
public DateTime? DateOfBirth { get; set; }
}
the entity class:
public class Contact
{
[Key]
public int Id { get; set; }
[StringLength(50)]
[Column(TypeName = "varchar")]
public string ContactFamilyName { get; set; }
[StringLength(50)]
[Column(TypeName = "varchar")]
public string ContactGivenName { get; set; }
...
[Column(TypeName = "date")]
public DateTime? DateOfBirth { get; set; }
}
and in my controller :
[HttpPost]
[GridAction]
public virtual ActionResult UpdateContact(int id, FormCollection form)
{
//Find a customer whose CustomerID is equal to the id action parameter
var c = _contactService.Get(id);
if (c != null)
{
//Perform model binding (fill the customer properties and validate it).
if (TryUpdateModel(c, form))
{
The _contactService.Get returns the instance from EntityFramework.
The TryUpdateModel binds string properties like first and last name correctly, but despite a lot of tries, I can't get it to bind the date of birth.
I suspect it's a formatting issue of some kind but cannot find what it is.
When I debug, I can see in the FormCollection that the date is correctly there, with the value that was input in the view so the data is definitely passed on to the controller.
the value passed to the controller is in format :
yyyy-MM-dd
I tried modifying this on the fly with multiple format without success.
Any ideas what I'm doing wrong here ?
Thanks a lot
Well, first, I have no idea why you're using TryUpdateModel.. That's pretty archaic.
Second, it sounds to me like you have not set your culture to accept the format you expect. Add the following to your web.config if your browser is defaults already set to the correct culture:
<system.web>
<globalization culture="auto" uiculture="auto" enableclientbasedculture="true">
</globalization>
</system.web>
If you want to force a culture, then set the culture you wish in this setting.
the globalization didn't help and is actually already set, however I realized there's a custom binder for Datetime and that is probably where my problem is.
thanks

Dropdown List MVC 4 error

I am trying to get a drop down list to work but its not working for me. This application is mainly a festival based application where you can add a festival along with your events. The error I am getting is on line:
#Html.DropDownList("towns", (IEnumerable<SelectListItem>)ViewData["Town"], new{#class = "form-control", #style="width:250px" })
This is the error I get:
There is no ViewData item of type 'IEnumerable' that has the key 'towns'.
Create.cshtml
<div class="form-group">
#Html.LabelFor(model => model.FestivalTown, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("towns", (IEnumerable<SelectListItem>)ViewData["Town"], new{#class = "form-control", #style="width:250px" })
#Html.ValidationMessageFor(model => model.FestivalTown)
</div>
#*#Html.Partial("ddlFestivalCounty");*#
</div>
Controller.cshtml
//Get
List<SelectListItem> Towns = new List<SelectListItem>();
Towns.Add(new SelectListItem { Text = "Please select your Town", Value = "SelectTown" });
var towns = (from t in db.Towns select t).ToArray();
for (int i = 0; i < towns.Length; i++)
{
Towns.Add(new SelectListItem
{
Text = towns[i].Name,
Value = towns[i].Name.ToString(),
Selected = (towns[i].ID == 0)
});
}
ViewData["Town"] = Towns;
//Post
festival.FestivalTown.Town = collection["Town"];
Model.cs
public class Festival
{
public int FestivalId { get; set; }
[Required]
[Display(Name = "Festival Name"), StringLength(100)]
public string FestivalName { get; set; }
[Required]
[Display(Name = "Start Date"), DataType(DataType.Date)]
public DateTime StartDate { get; set; }
[Required]
[Display(Name = "End Date"), DataType(DataType.Date)]
public DateTime EndDate { get; set; }
[Required]
[Display(Name = "County")]
public virtual County FestivalCounty { get; set; }
[Display(Name = "Festival Location")]
public DbGeography Location { get; set; }
[Required]
[Display(Name = "Town")]
public virtual Town FestivalTown { get; set; }
[Required]
[Display(Name = "Festival Type")]
public virtual FestivalType FType { get; set; }
public UserProfile UserId { get; set; }
}
public class Town
{
public int ID { get; set; }
[Display(Name = "Town")]
public string Name { get; set; }
}
I suspect that this error occurs when you submit the form to the [HttpPost] action and not when you are rendering the form, right? And this action renders the same view containing the dropdown, right? And inside this [HttpPost] action you forgot to populate the ViewData["Town"] value the same way you did in your HttpGet action, right?
So, go ahead and populate this property the same way you did in your GET action. When you submit the form to your [HttpPost] action, only the selected value is sent to the controller. So you need to repopulate the collection values if you intend to redisplay the same view, because this view renders a dropdown which is attempting to bind its values from ViewData["Town"].
And here's what I mean in terms of code:
[HttpPost]
public ActionResult SomeAction(Festival model)
{
... bla bla bla
// don't forget to repopulate the ViewData["Town"] value the same way you did in your GET action
// if you intend to redisplay the same view, otherwise the dropdown has no way of getting
// its values
ViewData["Town"] = ... same stuff as in your GET action
return View(model);
}
And all this being said, I would more than strongly recommend you using view models instead of this ViewData/ViewBag weakly typed stuff. Not only that your code will become much more clean, but even the error messages will start making sense.