I am having some trouble here. The situation is to update an existing record, at the same time, save a new row if there is no record by searching first the table.
When I am saving a new record, there is no problem. But when I'm trying to update an existing one, there are no changes. I tried to place some breakpoints specifically on the code that do the thing. It just ending up on the line if(!ModelState.IsValid).
Note:
Some of the lines are hard-coded for the sake of having some dummy data.
Function for retrieving some data from DB to pass to view model
[HttpGet]
public ActionResult CardNumberAssignment(string empId, int cardNumberId)
{
var getIdDetails = dbContext.CardNumberAssignments.Where(c => c.CardNumberId == cardNumberId && c.IsActive == true).SingleOrDefault();
if (cardNumberId == 0) //EMPLOYEE HAS NO CARD NUMBER YET
{
var viewModel = new CardNumberQRCodeVM
{
CardNumberId = 0,
CMId = empId,
OldQRCode = "No QR Code history",
OldReservedCardNumber = "No Card Number history",
NewReservedCardNumber = GetRandomCardNumber()
};
return View(viewModel);
}
else
{
if (getIdDetails.CMId != empId) //JUST CHECKING IF THE EMPLOYEE HAS THE CORRECT CARDNUMBERID FROM DB
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var empCardDetails = dbContext.CardNumberAssignments
.Include(c => c.ReservedCardNumber)
.Where(emp => emp.CMId == empId && emp.IsActive == true)
.Select(fields => new CardNumberQRCodeVM
{
CardNumberId = fields.CardNumberId,
CMId = empId,
OldQRCode = fields.QRCode,
IsActive = fields.IsActive,
OldReservedCardNumber = fields.ReservedCardNumber.CardNumber,
}).FirstOrDefault();
empCardDetails.NewReservedCardNumber = GetRandomCardNumber();
return View(empCardDetails);
}
}
Function for adding/editing record
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult SaveIdInformation(CardNumberQRCodeVM vm)
{
if (!ModelState.IsValid)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
// JUST ADDING/EDITING SOME CARD NUMBERS....
else
{
if (vm.CardNumberId == 0) //INSERT A NEW ROW FOR NEW CARD NUMBER AND QR CODE
{
var newCardNumber = new ReservedCardNumber
{
CardNumber = vm.NewReservedCardNumber,
IsActive = true,
CreatedDate = DateTime.Now,
CreatedBy = "Paolo",
ModifiedDate = DateTime.Now,
ModifiedBy = "Paolo"
};
dbContext.ReservedCardNumbers.Add(newCardNumber);
var newIdInfo = new CardNumberAssignment
{
CardNumberId = newCardNumber.Id,
QRCode = vm.NewQRCode,
CMId = vm.CMId,
IsActive = true,
CreatedDate = DateTime.Now,
CreatedBy = "Paolo",
ModifiedDate = DateTime.Now,
ModifiedBy = "Paolo"
};
dbContext.CardNumberAssignments.Add(newIdInfo);
}
else // EDIT EXISTING
{
var getEmployeeIdInDb = dbContext.CardNumberAssignments.Single(e => e.Id == vm.CardNumberId);
getEmployeeIdInDb.ReservedCardNumber.CardNumber = vm.NewReservedCardNumber;
getEmployeeIdInDb.QRCode = vm.NewQRCode;
getEmployeeIdInDb.IsActive = true;
getEmployeeIdInDb.ModifiedDate = DateTime.Now;
getEmployeeIdInDb.ModifiedBy = "Paolo";
}
dbContext.SaveChanges();
}
return RedirectToAction("CMDetails", "Admin", new { #empId = vm.CMId });
}
View model
public class CardNumberQRCodeVM
{
public int CardNumberId { get; set; }
public string CMId { get; set; }
[Display(Name = "Existing QR Code")]
public string OldQRCode { get; set; }
[Required]
[Display(Name = "New QR Code")]
public string NewQRCode { get; set; }
[Display(Name = "Resigned Cast Member?")]
public bool IsActive { get; set; }
public string CreatedBy { get; set; }
public DateTime CreatedDate { get; set; }
public string ModifiedBy { get; set; }
public DateTime ModifiedDate { get; set; }
public ReservedCardNumber ReservedCardNumber { get; set; }
[Display(Name = "Old Card Number")]
public string OldReservedCardNumber { get; set; }
[Display(Name = "New Card Number")]
public string NewReservedCardNumber { get; set; }
}
Related
In my ASP.NET Core 6 Web API using Entity Framework, I am working on an Employee Leave Application.
And I have this model class:
public class EmployeeLeave
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
public virtual Employee Employee { get; set; }
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
public LeaveType LeaveType { get; set; }
public bool? IsCurrent { get; set; }
}
Then I also created some DTO as shown here:
public class LeaveRequestDto
{
public Guid EmployeeId { get; set; }
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
public LeaveType LeaveType { get; set; }
}
public class LeaveResponseDto
{
public EmployeeResponseDto Employee { get; set; }
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
public string LeaveType { get; set; }
public bool? IsCurrent { get; set; }
}
Then I have the service for the implementation.
Interface:
Task<GenericResponseDto<LeaveResponseDto>> CreateAsync(LeaveRequestDto request);
Implementation:
public async Task<GenericResponseDto<LeaveResponseDto>> CreateAsync(LeaveRequestDto request)
{
var response = new GenericResponseDto<LeaveResponseDto>();
var employee = await _context.Employees.FirstOrDefaultAsync(e => e.Id == request.EmployeeId);
if (employee == null)
{
response.Error = new ErrorResponseDto()
{
ErrorCode = 404,
Message = "Employee does not exist in the system!"
};
response.StatusCode = 404;
}
else
{
var leave = _mapper.Map<EmployeeLeave>(request);
leave.Employee = employee;
leave.IsCurrent = true;
try
{
_context.EmployeeLeaves.Add(leave);
await _context.SaveChangesAsync();
response.Result = _mapper.Map<LeaveResponseDto>(leave);
response.StatusCode = 201;
}
catch (Exception ex)
{
response.Error = new ErrorResponseDto()
{
ErrorCode = 500,
Message = ex.Message
};
response.StatusCode = 500;
}
}
return response;
}
Currently, what I have will insert a new record for the Employee Leave Application into the database.
What I want to achieve is that I want to keep all the records of the Leave Applications for each employee.
At the point of insert, the application should check the last leave application record of that particular employee, change isCurrent to false, and then insert a new record, and the new record will have isCurrent as true.
How do I achieve this?
Thanks
You can retrieve the last record using LastOrDefault() and update it using EntityState.Modified
Try this
public async Task<GenericResponseDto<LeaveResponseDto>> CreateAsync(LeaveRequestDto request)
{
var response = new GenericResponseDto<LeaveResponseDto>();
var employee = await _context.Employees.FirstOrDefaultAsync(e => e.Id == request.EmployeeId);
if (employee == null)
{
response.Error = new ErrorResponseDto()
{
ErrorCode = 404,
Message = "Employee does not exist in the system!"
};
response.StatusCode = 404;
}
else
{
var lastLeave = _context.Set<EmployeeLeave>().where(leave =>
leave.Employee.Id == request.EmployeeId ).LastOrDefault();
if(lastLeave != null)
{
lastLeave .IsCurrent = false;
_context.Entry(lastLeave).State = EntityState.Modified;
}
var leave = _mapper.Map<EmployeeLeave>(request);
leave.Employee = employee;
leave.IsCurrent = true;
try
{
_context.EmployeeLeaves.Add(leave);
await _context.SaveChangesAsync();
response.Result = _mapper.Map<LeaveResponseDto>(leave);
response.StatusCode = 201;
}
catch (Exception ex)
{
response.Error = new ErrorResponseDto()
{
ErrorCode = 500,
Message = ex.Message
};
response.StatusCode = 500;
}
}
return response;
}
Parent:
public class Currency
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string? Name { get; set; }
}
Child:
public class CurrencyRate
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Column(TypeName = "date")]
public DateTime Date { get; set; }
[Column(TypeName = "decimal(18,6)")]
public decimal Value { get; set; }
public virtual Currency? Currency { get; set; }
}
Seed:
modelBuilder.Entity<Currency>().HasData(
new Currency { Id = 1, Name = "JPY" },
new Currency { Id = 2, Name = "USD" },
new Currency { Id = 3, Name = "EUR" },
new Currency { Id = 4, Name = "TRY" }
);
Insert:
public async Task UpdateCurrencyRates()
{
var trackedCurrencies = await _context.Currency.ToListAsync();
BulkConfig bulkConfig = new BulkConfig()
{
IncludeGraph = true,
SetOutputIdentity = true,
CalculateStats = true,
PropertiesToIncludeOnUpdate = new List<string> { string.Empty }
};
List<CurrencyRate> currencyRates = GetCurrencyRatesFromSomewhere();
currencyRates.ForEach(currencyRate =>
{
var trackedCurrency = trackedCurrencies.SingleOrDefault(r => r.Name == currencyRate.Currency?.Name);
if (trackedCurrency != null)
{
currencyRate.Currency = trackedCurrency;
}
else if (currencyRate.Currency != null)
{
trackedCurrencies.Add(currencyRate.Currency);
}
});
_context.BulkInsertOrUpdate(currencyRates, bulkConfig);
}
The above code works well unless new currency comes in (the one not included in Seed). Then I get 'The MERGE statement conflicted with the FOREIGN KEY constraint'. Why is it so? From what I read BulkExtensions should insert new currency first, then update CurrencyRates with its Id and only then perform insert of CurrencyRates.
Update:
If I do this, it works, but that defeats the grace of the BulkInsert:
currencyRates.ForEach(async currencyRate =>
{
var trackedCurrency = trackedCurrencies.SingleOrDefault(r => r.Name == currencyRate.Currency?.Name);
if (trackedCurrency != null)
{
currencyRate.Currency = trackedCurrency;
}
else if (currencyRate.Currency != null)
{
trackedCurrencies.Add(currencyRate.Currency);
//this line added
await _context.AddAsync(currencyRate.Currency);
}
});
//this line added
await _context.SaveChangesAsync();
I am still having real performance issue in a list there our 38 thousand entrys and I need to map them to another table for export I am thinking of moving it to stored proc but still worried what performance would be like there. The code works but takes a very long time to execute and wish to turn it into a stored proc.
private List<TradeItemsExport> MapTradeItems(List<TradeItems> tradeItem)
{
List<TradeItemsExport> retList = new List<TradeItemsExport>();
try
{
var StockImport = new StockItemExported();
List<StandardLookUpList> _AnalsisCodes = GetAnayalsisCodesForExportCode();
StandardLookUpList sport = new StandardLookUpList();
StandardLookUpList gender = new StandardLookUpList();
StandardLookUpList colour = new StandardLookUpList();
StandardLookUpList Size = new StandardLookUpList();
StandardLookUpList categorycode = new StandardLookUpList();
StandardLookUpList categorydesc = new StandardLookUpList();
StandardLookUpList subcategorycode = new StandardLookUpList();
StandardLookUpList subcategorydesc = new StandardLookUpList();
StandardLookUpList brandcode = new StandardLookUpList();
StandardLookUpList branddesc = new StandardLookUpList();
using (var db = new liveEntities1())
{
int count = 0;
foreach (var item in tradeItem)
{
count++;
bool hasprocessed = HasTransactionBeenProcessed(item.ItemCode);
if (hasprocessed == false)
{
var codesForThisItem = _AnalsisCodes.Where(w => w.ItemCode == item.ItemCode);
if (codesForThisItem.Any())
{
sport = codesForThisItem.FirstOrDefault(x => x.code == Constants.Sport);
gender = codesForThisItem.FirstOrDefault(x => x.code == Constants.Gender);
colour = codesForThisItem.FirstOrDefault(x => x.code == Constants.Colour);
Size = codesForThisItem.FirstOrDefault(x => x.code == Constants.Size);
categorycode = codesForThisItem.FirstOrDefault(x => x.code == Constants.Category);
categorydesc = codesForThisItem.FirstOrDefault(x => x.code == Constants.Category);
subcategorycode = codesForThisItem.FirstOrDefault(x => x.code == Constants.SubCategory);
subcategorydesc = codesForThisItem.FirstOrDefault(x => x.code == Constants.SubCategory);
brandcode = codesForThisItem.FirstOrDefault(x => x.code == Constants.Brand);
string SportCodeValue, SportDescValue;
if (sport == null)
{
SportCodeValue = "";
SportDescValue = "";
}
else
{
SportCodeValue = sport.LookupValue.ToString();
SportDescValue = sport.description;
}
string GenderCodeValue, GenderCodeDesc;
if (gender == null)
{
GenderCodeValue = "";
GenderCodeDesc = "";
}
else
{
GenderCodeValue = gender.LookupValue.ToString();
GenderCodeDesc = gender.description;
}
string ColourCodeValue, ColourCodeDesc;
if (colour == null)
{
ColourCodeValue = "";
ColourCodeDesc = "";
}
else
{
ColourCodeValue = colour.LookupValue.ToString();
ColourCodeDesc = colour.description;
}
string SizeCodeValue, SizeCodeDesc;
if (Size == null)
{
SizeCodeValue = "";
SizeCodeDesc = "";
}
else
{
SizeCodeValue = Size.LookupValue.ToString();
SizeCodeDesc = Size.description;
}
string CategoryCodeValue, CategoryCodeDesc;
if (categorycode == null)
{
CategoryCodeValue = "";
CategoryCodeDesc = "";
}
else
{
CategoryCodeValue = categorycode.LookupValue.ToString();
CategoryCodeDesc = categorydesc.description;
}
string subcategorycodevalue, subcategorycodedesc;
if (categorycode == null)
{
subcategorycodevalue = "";
subcategorycodedesc = "";
}
else
{
subcategorycodevalue = subcategorycode.LookupValue.ToString();
subcategorycodedesc = subcategorydesc.description;
}
string brandcodecodevalue, brandcodecodedesc;
if (brandcode == null)
{
brandcodecodevalue = "";
brandcodecodedesc = "";
}
else
{
brandcodecodevalue = brandcode.LookupValue.ToString();
brandcodecodedesc = brandcode.description;
}
retList.Add(new TradeItemsExport()
{
ItemCode = item.ItemCode,
BarCode = item.BarCode,
Description = item.Description,
SupplierCode = item.SupplierCode,
SupplierStockCode = item.SupplierStockCode,
Product_Group_Code = "",
Product_Group_Desc = "",
SportCode = SportCodeValue,
SportDesc = SportDescValue,
GenderCode = GenderCodeValue,
GenderDesc = GenderCodeDesc,
ColourCode = ColourCodeValue,
ColourDesc = ColourCodeDesc,
SizeCode = SizeCodeValue,
SizeDesc = SizeCodeDesc,
CategoryCode = CategoryCodeValue,
CategoryDesc = CategoryCodeDesc,
subcategorycode = subcategorycodevalue,
subcategorydesc = subcategorycodedesc,
BrandsCode = brandcodecodevalue,
BrandsDesc = brandcodecodedesc,
Vat = item.Vat,
GrossWeight = item.Weight,
CommodityCode = item.CommodityCode,
price_exVAT = item.price_exVAT,
price_incVAT = item.price_incVAT,
currentprice_exVAT = item.currentprice_exVAT,
currentprice_incVAT = item.currentprice_incVAT,
creation_date = item.creation_date,
Inactive_date = item.Inactive_date,
status = 1
});
Console.Write(String.Format("Exporting stock item {0} with a current record of {1} of {2} \n", item.ItemCode.ToString(), count.ToString(), tradeItem.Count.ToString()));
EFStockItemExported _newStockitemImported = new EFStockItemExported();
_newStockitemImported.StockItemID = item.ItemCode;
_newStockitemImported.IsProcessed = true;
_newStockitemImported.DateImported = DateTime.Now;
db.EFStockItemExporteds.Add(_newStockitemImported);
db.SaveChanges();
}
else
{
Console.Write(string.Format("Stock Items to Process [{0}] check the table and remove entry if wish to re process.", 0));
}
}
}
}
}
catch (Exception ex)
{
}
return retList;
}
My problem that this takes around 30 mins to compute the results which is very slow.
This is the sql that I am doing which is a view that is the tradeitem that I am passing.
SELECT
dbo.PLSupplierAccount.SupplierAccountNumber, dbo.PLSupplierAccount.PLSupplierAccountID, dbo.PLSupplierAccount.SupplierAccountName,
dbo.PLSupplierAccount.SYSCurrencyID, dbo.PLSupplierAccount.MainTelephoneAreaCode, dbo.PLSupplierAccount.MainTelephoneCountryCode,
dbo.PLSupplierAccount.MainTelephoneSubscriberNumber, dbo.PLSupplierAccount.MainFaxCountryCode, dbo.PLSupplierAccount.MainFaxSubscriberNumber,
dbo.PLSupplierAccount.MainFaxAreaCode, dbo.PLSupplierContact.ContactName, dbo.PLSupplierContact.Description, dbo.PLSupplierContact.FirstName,
dbo.PLSupplierContact.MiddleName, dbo.PLSupplierContact.LastName, loc.AddressLine1, loc.AddressLine2, loc.AddressLine3, loc.AddressLine4, loc.PostCode,
loc.City, loc.County,
CAST(CASE WHEN loc.Country = 'Ireland' THEN 'IRL'
WHEN loc.Country = 'Great Britain'
THEN 'GBR'
ELSE 'ERR'
END AS nvarchar(3)) AS Country,
dbo.SYSCurrency.SYSCurrencyISOCodeID, dbo.SYSCurrency.SYSExchangeRateTypeID, dbo.SYSCurrency.Name AS CurrencyDescription,
dbo.SYSCurrency.Symbol AS CurrencySymbol
FROM
dbo.PLSupplierAccount
INNER JOIN
dbo.PLSupplierContact ON dbo.PLSupplierAccount.PLSupplierAccountID = dbo.PLSupplierContact.PLSupplierAccountID
INNER JOIN
dbo.PLSupplierLocation AS loc ON dbo.PLSupplierAccount.PLSupplierAccountID = loc.PLSupplierAccountID
AND dbo.PLSupplierContact.PLSupplierLocationID = loc.PLSupplierLocationID
INNER JOIN
dbo.SYSCurrency ON dbo.PLSupplierAccount.SYSCurrencyID = dbo.SYSCurrency.SYSCurrencyID
My quesiton is how would I change the above to include a sub query that would do the same as this function is doing above.
The query for the codes look up which is again another view is below.
SELECT
dbo.StockItem.ItemID, dbo.StockItem.Code, dbo.StockItem.Name, dbo.StockItemSearchCatVal.SearchValueID, dbo.SearchValue.Name AS Expr1,
dbo.SearchCategory.Name AS Expr2
FROM
dbo.SearchCategory
INNER JOIN
dbo.SearchValue ON dbo.SearchCategory.SearchCategoryID = dbo.SearchValue.SearchCategoryID
INNER JOIN
dbo.StockItemSearchCatVal ON dbo.SearchCategory.SearchCategoryID = dbo.StockItemSearchCatVal.SearchCategoryID
AND dbo.SearchValue.SearchValueID = dbo.StockItemSearchCatVal.SearchValueID
INNER JOIN
dbo.StockItem ON dbo.StockItemSearchCatVal.ItemID = dbo.StockItem.ItemID
I just feel I would get more benefit changing this into a subquery so that I am just returning the results to .net I am using the filehelpers library to output the results set of MapTradeItems to csv so obv more things I can do the better on the server.
Obv I would need some kind of temporary table to loop through the results but how quick would that be in sql server compared to a .net for each loop.
This is the poco class which I have to reproduce to csv.
[DelimitedRecord(",")]
public class TradeItemsExport
{
[FieldOrder(1)]
public string ItemCode { get; set; }
[FieldOrder(2)]
public string BarCode { get; set; }
[FieldOrder(3)]
public string Description { get; set; }
[FieldOrder(4)]
public string SupplierCode { get; set; }
[FieldOrder(5)]
public string SupplierStockCode { get; set; }
[FieldOrder(6)]
public string Product_Group_Code { get; set; }
[FieldOrder(7)]
public string Product_Group_Desc { get; set; }
[FieldOrder(8)]
public string SportCode { get; set; }
[FieldOrder(9)]
public string SportDesc { get; set; }
[FieldOrder(10)]
public string GenderCode { get; set; }
[FieldOrder(11)]
public string GenderDesc { get; set; }
[FieldOrder(12)]
public string ColourCode { get; set; }
[FieldOrder(13)]
public string ColourDesc { get; set; }
[FieldOrder(14)]
public string SizeCode { get; set; }
[FieldOrder(15)]
public string SizeDesc { get; set; }
[FieldOrder(16)]
public string CategoryCode { get; set; }
[FieldOrder(17)]
public string CategoryDesc { get; set; }
[FieldOrder(18)]
public string subcategorycode { get; set; }
[FieldOrder(19)]
public string subcategorydesc { get; set; }
[FieldOrder(20)]
public string BrandsCode { get; set; }
[FieldOrder(21)]
public string BrandsDesc { get; set; }
[FieldOrder(22)]
public Nullable<short> Vat { get; set; }
[FieldOrder(23)]
public decimal GrossWeight { get; set; }
[FieldOrder(24)]
public string CommodityCode { get; set; }
[FieldOrder(25)]
public decimal price_exVAT { get; set; }
[FieldOrder(26)]
public Nullable<decimal> price_incVAT { get; set; }
[FieldOrder(27)]
public Nullable<decimal> currentprice_exVAT { get; set; }
[FieldOrder(28)]
public Nullable<decimal> currentprice_incVAT { get; set; }
[FieldOrder(29)]
public System.DateTime creation_date { get; set; }
[FieldOrder(30)]
public Nullable<System.DateTime> Inactive_date { get; set; }
[FieldOrder(31)]
public int status { get; set; }
}
In an Action Result that does a HttpPost i get an error from EF
"ModelState.Errors Internal error in the expression evaluator"
My model in View is OrdineOmaggio
public partial class OrdineOmaggio
{
public int Id { get; set; }
public string Id_Gioielleria { get; set; }
public System.DateTime Data_Ordine { get; set; }
public virtual Consumatore MD_CONSUMATORE { get; set; }
public virtual Omaggio MD_OMAGGIO { get; set; }
public virtual CodiceRandomConsumatore MD_RANDOM_CONSUMATORE { get; set; }
}
My Action is so
public async Task<ActionResult> ChooseGift(
[Bind(Include ="Data_Ordine,MD_RANDOM_CONSUMATORE,MD_OMAGGIO,Id_Gioielleria")]
OrdineOmaggio ordineOmaggio,
string codiceOmaggio, string codice)
{
var randomConsumatore = _context.CodiciRandomConsumatori
.SingleOrDefault(c => c.Codice == codice) ??
new CodiceRandomConsumatore
{
Id = -1,
Codice = "",
Assegnato = null,
Distinzione = ""
};
var consumatore = _context.CodiciRandomConsumatori
.Where(c => c.Codice == codice)
.Select(c => c.MD_CONSUMATORE)
.SingleOrDefault();
var omaggio = _context.Omaggi
.SingleOrDefault(c => c.CodiceOmaggio == codiceOmaggio);
if (ModelState.IsValid)
{
ordineOmaggio.Data_Ordine = DateTime.Now;
ordineOmaggio.Id_Gioielleria = ordineOmaggio.Id_Gioielleria;
ordineOmaggio.MD_CONSUMATORE = consumatore; // FK
ordineOmaggio.MD_OMAGGIO = omaggio; // FK
ordineOmaggio.MD_RANDOM_CONSUMATORE = randomConsumatore; // FK
_context.OrdiniOmaggio.Add(ordineOmaggio);
randomConsumatore.Assegnato = true;
_context.SaveChanges();
return RedirectToAction("Success");
}
return View(ordineOmaggio);
}
The error is about dataAnnotation: it say that not all field all filled
The metadata is
public class OrdineOmaggioMetadata
{
[Required(ErrorMessage = "Scegli la gioiellereia.")]
public string Id_Gioielleria;
[Required(ErrorMessage = "Seleziona una foto.")]
public Omaggio MD_OMAGGIO;
...
}
In my view i placed
#Html.HiddenFor(m=> m.MD_OMAGGIO.CodiceOmaggio)
#Html.ValidationMessageFor(m => m.MD_OMAGGIO.CodiceOmaggio)
but this helper pass null to ActionResult
MD_OMAGGIO is a table foreign key for product codes.
what i wrong ?
At the moment I have a drop down box which only displays a Suppliers Name with the value of the ID hidden behind it. I would also like to display the Suppliers account number next to the Supplier Name.
HTML:
#Html.DropDownListFor(
m => m.SupplierID,
new SelectList(Model.Suppliers, "SupplierID", "SupplierName"),
new { #id = "SuppNameDD", #class = "GRDropDown" }
)
Controller:
public ActionResult Index(string client) {
int clientID = clientRepo.GetClientIDByName(client);
DashboardViewModel model = new DashboardViewModel();
model.ClientID = clientID;
model.ClientName = client;
model.FinancialsAtAGlance = reportRepo.GetFinancialsAtAGlance(model.ClientID);
model.SupplierID = -1;
model.AccountNo = null;
model.Suppliers = supplierRepo.GetAllSuppliersByClient(clientID);
model.ReviewID = -1;
model.AccountNo = null;
model.Reviews = reviewRepo.GetAllReviewsByClientID(clientID);
return View(model);
}
ViewModel:
public class DashboardViewModel {
public int ClientID { get; set; }
public string ClientName { get; set; }
public IQueryable<FinancialsAtAGlanceModel> FinancialsAtAGlance { get; set; }
public Dictionary<string, Dictionary<string, decimal?>> Budgets { get; set; }
public class SelectReport {
public int ReportID { get; set; }
public string ReportType { get; set; }
public static IEnumerable<SelectReport> Reports = new List<SelectReport> {
new SelectReport {
ReportID = 1,
ReportType = "Claims By Supplier"
},
new SelectReport {
ReportID = 2,
ReportType = "Department breakdown"
},
new SelectReport {
ReportID = 3,
ReportType = "Reason Code breakdown"
},
new SelectReport {
ReportID = 4,
ReportType = "Monthly Debiting report"
}
};
}
public List<SelectReport> allReports { get; set; }
public int SupplierID { get; set; }
public IEnumerable<Supplier> Suppliers { get; set; }
public int ReviewID { get; set; }
public string AccountNo { get; set; }
public IEnumerable<Review> Reviews { get; set; }
}
How can add this is as the other value is a selected value and this is not what I want. It should be another datatext field.
If this display name is something that would be used multiple times, I would suggest adding a property to your Supplier class. Something like DisplayName:
public class Supplier
{
//...
public string SupplierName { get; set; }
public string AccountNumber { get; set; }
//...
public string DisplayName
{
get { return String.Format("{0} ({1})", SupplierName, AccountNumber); }
}
}
Then, you just need to change your drop down list to use DisplayName instead of SupplierName as the text field:
#Html.DropDownListFor(m => m.SupplierID, new SelectList(Model.Suppliers, "SupplierID", "DisplayName"), new { #id = "SuppNameDD", #class = "GRDropDown" })
EDIT:
There is another way to do this that can be done all in the view:
#Html.DropDownListFor(m => m.SupplierID, Model.Suppliers.Select(item => new SelectListItem
{
Value = item.SupplierID.ToString(),
Text = String.Format("{0} ({1})", item.SupplierName, item.AccountNumber.ToString()),
Selected = item.SupplierID == Model.SupplierID
}))
Probably you can achieve your desired output by 1.create a custom helper with with extension method which will return MvcHtmlString which will create your custom HTML for dropdown and call that method in your view.
Like Below
public static class CustomDropdown
{
public static string Dropdown(Priority priority)
{
StringBuilder sb=new StringBuilder ();
sb+="<Select id='drop'>";
for(int i=0;i<priority.name.length;i++)
{
sb+="<option id='dropop' value='"+priority.value[i]+"'title='"+priority.title[i]+"'>"+priority.name[i]+"</option>";
}
sb+="</select>";
return Convert.ToString(sb);
}
}
2.Bind the options of the given select with help of jquery like
var i=0;
$('.drpclass option').each(function(){
$(this).attr('title',Model.priority.title[i])
i++;
});