public class BaseEntity
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public ObjectId Id { get; set; }
}
public class Order : BaseEntity
{
public string OrderId { get; set; }
public int CustomerId { get; set; }
public Payment Payment { get; set; }
public OrderStatus OrderStatus { get; set; }
public ShippingAddress ShippingAddress { get; set; }
public BillingAddress BillingAddress { get; set; }
[BsonRepresentation(BsonType.Double)]
public decimal Discount { get; set; }
//public BsonDateTime OrderDate { get; set; }
}
// PUT api/values/5
[HttpPut("{id}")]
public async Task<IActionResult> Put(string id, [FromBody]Order Order)
{
if (!ModelState.IsValid)
return BadRequest(ModelState);
await OrderContext.Put<Order>(x => x.OrderId == id, Order);
return Ok(Order);
}
This is my request body.But I am getting the Order model as null.I am not sure why .
I have a model Order which inherits from BaseEntity . I am trying to pass a model for PUT request from postman . But I am receiving the Order model as null .
However the interesting thing is if I remove id property from the request body I am getting all the model populated as the request body except the id field from the base entity. I receive the id property as 00000000000000 in that second case .
Related
I'm working on an web API, where it needs to receive the multi-part form data with in a model. As of now it's not receiving the request and showing the Bad request When I tried from the Postman.
My model :
public class InvoiceDetails
{
public int? po_id { get; set; }
public DateTime created_date { get; set; }
public string grn_status { get; set; }
public int utilization_amount { get; set; }
public int currency_id { get; set; }
public string currency_code { get; set; }
public string currency_symbol { get; set; }
[FromForm(Name = "invoice_file")]
public List<IFormCollection> invoice_file { get;set;}
[FromForm(Name = "other_files")]
public List<IFormCollection> other_files { get; set; }
}
In the above class/model "invoice_file" and "other_files" can have multiple file uploads so I made it List.
My Action Method :
[HttpPost]
[Route("CreateInvoice")]
public IActionResult CreateInvoice([FromForm]InvoiceDetails idobj )
{
//var modelData = Request.Form["invoice_file"];
Response resobj = new Response();
try
{
if (idobj.invoice_file.Count > 0)
{
resobj = _dataContext.AddInvoice(idobj);
if (resobj.flag == true)
{
Upload(idobj);
}
}
else
{
resobj.flag = false;
resobj.message = "please upload atleast one invioce file";
}
}
catch (Exception ex)
{
}
return Ok(resobj);
}
How can I make the action method or model, in such a way that user can upload the model with multiple files to the properties other_files & invoice_file.
Reference of postman Image
As CodeCaster says,add Content-Type:multipart/form-data; and change List<IFormCollection> to List<IFormFile>.It is not changing the whole model to List.So you can also retrieve other information which exists in your model with idobj.xxx.Change
public class InvoiceDetails
{
public int? po_id { get; set; }
public DateTime created_date { get; set; }
public string grn_status { get; set; }
public int utilization_amount { get; set; }
public int currency_id { get; set; }
public string currency_code { get; set; }
public string currency_symbol { get; set; }
[FromForm(Name = "invoice_file")]
public List<IFormCollection> invoice_file { get;set;}
[FromForm(Name = "other_files")]
public List<IFormCollection> other_files { get; set; }
}
to
public class InvoiceDetails
{
public int? po_id { get; set; }
public DateTime created_date { get; set; }
public string grn_status { get; set; }
public int utilization_amount { get; set; }
public int currency_id { get; set; }
public string currency_code { get; set; }
public string currency_symbol { get; set; }
[FromForm(Name = "invoice_file")]
public List<IFormFile> invoice_file { get; set; }
[FromForm(Name = "other_files")]
public List<IFormFile> other_files { get; set; }
}
result:
IFormCollection is used to retrieve all the values from posted form data.refer to the official document.
If you want to use c,you can try to use it,you can do like this
public IActionResult CreateInvoice([FromForm]IFormCollection idobj)
and you need to get the data you want to foreach keys of IFormCollection,so public List<IFormCollection> invoice_file { get;set;} is better than use IFormCollection.
I need to pass two models in the same view, however some elements have the same name.
I have two models Employee and HolidayRequestForm and I need to use both of these in the one view which will be a details page for each Employee.
Here is my Employee:
public partial class Employee
{
public int EmployeeID { get; set; }
public string FullName { get; set; }
public string EmailID { get; set; }
public string Password { get; set; }
public System.DateTime StartDate { get; set; }
public int RoleID { get; set; }
public int ShiftID { get; set; }
public int AreaID { get; set; }
public int DisciplineID { get; set; }
public int SiteID { get; set; }
public int ALCategory { get; set; }
public Nullable<int> HoursTaken { get; set; }
public Nullable<int> AwardedLeave { get; set; }
public Nullable<int> TotalHoursThisYear { get; set; }
public int HoursCarriedForward { get; set; }
public Nullable<int> EntitlementRemainingThisYear { get; set; }
public string Comments { get; set; }
}
Here is my HolidayRequestForm:
public partial class HolidayRequestForm
{
public int RequestID { get; set; }
public int EmployeeID { get; set; }
public System.DateTime StartDate { get; set; }
public System.DateTime FinishDate { get; set; }
public int HoursTaken { get; set; }
public string Comments { get; set; }
public int YearCreated { get; set; }
public int MonthCreated { get; set; }
public Nullable<int> DayCreated { get; set; }
public Nullable<int> YearOfHoliday { get; set; }
}
I have tried Creating a separate model that contains all elements to use in the view but I'm not sure how to differentiate elements with the same name eg. Comments Is it even possible to do so?
I would like to use both these models in my view as I'd like to create an Employee Profile page, with their info on the top displaying information about their profile and then holidays they have requested using the holidayrequestform in a table on the bottom of the page.
Write a ViewModel which will contain both Employee and HolidayRequestForm as follows and then pass the ViewModel to the view:
public class EmployeeViewModel
{
public Employee Employee {get; set;}
public HolidayRequestForm HolidayRequestForm {get; set;}
}
Then in your action method:
public ActionResult EmployeeDetails(int id)
{
Employee employee = _dbContext.Employees.FirstOrDefault(emp => emp.EmployeeID == id);
HolidayRequestForm holidayRequestForm = _dbContext.HolidayRequestForms.FirstOrDefault(hrf => hrf.EmployeeID == id);
EmployeeViewModel employeeViewModel = new EmployeeViewModel()
{
Employee = employee,
HolidayRequestForm = holidayRequestForm
}
return View(employeeViewModel);
}
Then in the view, access the model properties as follows:
#model EmployeeViewModel
<p>Full Name: #Model.Employee.FullName</p>
I want to fetch details of Employee from three tables based on employeeNumber.
Three Tables :
EmployeeDetails (employeeNumber primarykey & userID,designationId Foreignkey)
UserDetails (userId primaryKey)
Designations (designationId primarykey)
UserDetails
public partial class UserDetail
{
public UserDetail()
{
this.EmployeeDetails = new HashSet<EmployeeDetail>();
}
public System.Guid user_id { get; set; }
public string employee_name { get; set; }
public string employee_email { get; set; }
public decimal employee_contactnumber { get; set; }
public virtual ICollection<EmployeeDetail> EmployeeDetails { get; set; }
}
EmployeeDetails
public partial class EmployeeDetail
{
public System.Guid employee_id { get; set; }
public Nullable<System.Guid> user_id { get; set; }
public int employee_number { get; set; }
public Nullable<int> designation_id { get; set; }
public virtual Designation Designation { get; set; }
public virtual UserDetail UserDetail { get; set; }
}
Designations
public partial class Designation
{
public Designation()
{
this.EmployeeDetails = new HashSet<EmployeeDetail>();
}
public int designation_id { get; set; }
public string designation_name { get; set; }
public Nullable<System.DateTime> create_date { get; set; }
public virtual ICollection<EmployeeDetail> EmployeeDetails { get; set; }
}
I'd suggest to add navigation properties to your entity classes if you haven't yet. That would cause EF to inject the join without you having to specify join conditions.
Changed your identifiers to match conventions, otherwise you have to explicitly configure the associations.
public class Employee
{
public int EmployeeId { get; set; }
public int UserDetailId { get; set; }
public UserDetail UserDetail { get; set; }
}
public class UserDetail
{
public int UserDetailId { get; set; }
public string SomeUserDetailProperty{ get; set; }
public ICollection<Employee> Employees { get; set; }
}
This allows for
db.Employees.Select(e => new
{
e.EmployeeId,
e.UserDetail.SomeUserDetailProperty
})
Create a view in your database and fetch data using that view in entityframework
var data = entities.EmployeeDetails.Select(e => new GetUserInfo {designation= e.Designation,userDetail = e.UserDetail, employeeDetail = e }).Where(e => e.employeeDetail.employee_number == number);
This is working fine. Thank you
GetUserInfo class consists of :
public class GetUserInfo{
public UserDetails userDetail {get;set;}
public EmployeeDetails employeeDetail {get;set}
public Designations designation{get;set;}
}
I am using a custom model binder in order to put some custom logic in my model Binding.
Here's my DTOs:
public class TaskDto
{
public int Id { get; set; }
[MaxLength(100), Required]
public string Name { get; set; }
public List<StepDto> Steps { get; set; }
public List<ResourceDTO> Resources { get; set; }
}
Step DTO:
public class StepDto
{
public int Id { get; set; }
[MaxLength(100)]
public string Description { get; set; }
public StepType StepType { get; set; }
}
ResourceDTO:
public class ResourceDTO
{
public int Id { get; set; }
[MaxLength(250), Required]
public string Title { get; set; }
[Required]
public string Link { get; set; }
public string MetaTagUrl { get; set; }
[Required, Range(1, 1)]
public ResourceType ResourceType { get; set; }
}
Where ResourceType is an enumeration (only has 1 as value for now.)
I tried creating a custom model binder using this link.
Here's my API Action method signature:
[HttpPut]
[Route("datacapture/{activityId}/tasks")]
[Authorize]
public async Task<IHttpActionResult> UpdateAllDataCaptureActivities(int activityId, [FromBody][ModelBinder] TaskDto tasks)
{
...
}
I am getting the following error on calling the API:
"Message": "An error has occurred.",
"ExceptionMessage": "Can't bind parameter 'tasks' because it has conflicting attributes on it.",
"ExceptionType": "System.InvalidOperationException",
Don't use [FromBody] and [ModelBinder] at the same time.
I have a class, which has 8 props / 8 columns in DB. But on a Edit page, i dont want to show the AddedDate or UserID field, since i dont want user to change it.
public class Voucher
{
public int ID { get; set; }
public string Title { get; set; }
public string SiteName { get; set; }
public string DealURL { get; set; }
public DateTime AddedDate { get; set; }
public DateTime? ExpirationDate { get; set; }
public string VoucherFileURL { get; set; }
public Guid UserID { get; set; }
}
Here is what I have for Edit controller:
// POST: /Voucher/Edit/5
[HttpPost]
public ActionResult Edit(Voucher voucher)
{
if (ModelState.IsValid)
{
string[] excludeProperties = { "AddedDate", "UserID" };
UpdateModel(ModelState, "", null, excludeProperties);
db.Entry(voucher).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(voucher);
}
On Edit page, once i click on submit, i got the following error: System.Data.SqlServerCe.SqlCeException: An overflow occurred while converting to datetime.
Seems like the AddedDate didn't get excluded from the view model and triggered the error.
Would you please let me know how to fix it? Thanks!
public ActionResult Edit([Bind(Exclude = "AddedDate")]Voucher voucher)
no luck either
You are still passing in Voucher which could contain that field in it. I'm not sure what you are trying to accomplish with the UpdateModel here if you are already passing in a Voucher object?
Pass in Voucher, set it to modified and save it. If you want to use whats in the database then you'll have to
Load the object from the database
UpdateModel and exclude the properties
Save your entity.
You could simply use a View Model and post that.
public class Voucher
{
public int ID { get; set; }
public string Title { get; set; }
public string SiteName { get; set; }
public string DealURL { get; set; }
public DateTime? ExpirationDate { get; set; }
public string VoucherFileURL { get; set; }
public Guid UserID { get; set; }
}
and then load up your object from the db":
var voucher = db.Vouchers.Where(o=>o.ID==voucherViewModel.Id);
//manually copy the fields here then save it
//copy
db.SaveChanges();