How to pass multiple model as parameter in WEB API - entity-framework

Can anyone please help me to pass multiple models as a parameter to the request's content in WEB API?
I have 2 different Model Student and Employee
public class Student
{
public int StudentId { get; set; }
public string StudentName { get; set; }
public string Branch { get; set; }
}
public class Employee
{
public int EmployeeId { get; set; }
public string EmployeeName { get; set; }
public string Department { get; set; }
}
I have created an API and want to pass both these models as parameters in my action method InsertTestAPI.
[HttpPost]
[Route("TestAPI")]
public HttpResponseMessage InsertTestAPI(Student modelStudent, Employee modelEmployee)
{
// other logical operations
}
When I pass these models as JSON in the request body, I get the following error from Postman.
{
"$id": "1",
"Message": "An error has occurred.",
"ExceptionMessage": "Can't bind multiple parameters ('modelStudent' and 'modelEmployee') to the request's content.",
"ExceptionType": "System.InvalidOperationException",
"StackTrace": " at System.Web.Http.Controllers.HttpActionBinding.ExecuteBindingAsync(HttpActionContext actionContext, CancellationToken cancellationToken)\r\n at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__5.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__15.MoveNext()"
}
Can anyone please help me?

public class StudentEmployeModel
{
public Student Students{get;set;}
public Employee Employees{get;set;}
}
Create the StudentEmpendedModel class this way.
public HttpResponseMessage InsertTestAPI(StudentEmployeModel model)
{// other logical operations }
request this way
{ "students": { "studentId":"0", "studentName":"Mehmet", "branch":"software" } ,
"employees":
{"employeeId ":0,"employeeName":"Test","department":"IT"} }
This way you can send requests as Json

You can call Empolyee class in student class after that .then you can call multiple model call in api
public class Student
{
public int StudentId { get; set; }
public string StudentName { get; set; }
public string Branch { get; set; }
public Employee EmpData {get;set;}
}

Related

asp.net web api server data not syncing with database between BL

Hello I am new to servers and REST API and am trying to extract data from a dynamically created table and the data does not sync with the data in the database.
I have an sql database from which I extracted an entity database in asp.net web project.
This is an example for GET of one entity class (exists in database):
public class EmployeeBL
{
private FSProject1Entities db = new FSProject1Entities();
public List<Employee> GetEmployees(string fname, string lname, string depID)
{
return GetEmployeeSearchResult(fname, lname, depID);
}
}
And this is an example for a method from a class such as I created in order to combine data from 2 tables:
public class ShiftEmployeeDataBL
{
private FSProject1Entities db = new FSProject1Entities();
private List<ShiftEmployeeDataBL> GetEmployeeByShiftID(int id)
{
List<ShiftEmployeeDataBL> shiftEmpData = new List<ShiftEmployeeDataBL>();
foreach (Employee emp in db.Employee)
{//build list... }
return shiftEmpData;
}
My problem is that db.Employee via this GET request path (ShiftEmployeeData) is old data and via Employee GET request is good data (assuming the data was updated via Employee path).
And vice versa - it would appear that if I update Employee via ShiftEmployeeData class, it would appear as good data for ShiftEmployeeData class and not update for Employee.
I have APIcontrollers for both classes.
what is happening? I feel like I am missing something.
I tried closing cache options in browser.
update with code for elaboration:
entity Employee:
public partial class Employee
{
public int ID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int StartWorkYear { get; set; }
public int DepartmentID { get; set; }
}
employee update(auto generated by entity model code generation from db):
public void UpdateEmployee(int id, Employee employee)
{
Employee emp= db.Employee.Where(x => x.ID == id).First();
emp.FirstName = employee.FirstName;
emp.LastName = employee.LastName;
emp.StartWorkYear = employee.StartWorkYear;
emp.DepartmentID = employee.DepartmentID;
db.SaveChanges();
}
employeeshiftdata class (not a db table but still in the models folder):
public class EmployeeShiftData
{
public int ID { get; set; } //EmployeeID
public string FirstName { get; set; }
public string LastName { get; set; }
public int StartWorkYear { get; set; }
public string DepartmentName { get; set; }
public List<Shift> Shifts { get; set; }
}
employeeshift GET part of the controller:
[EnableCors(origins: "*", headers: "*", methods: "*")]
public class EmployeeShiftDataController : ApiController
{
private static EmployeeShiftDataBL empShiftDataBL = new EmployeeShiftDataBL();
// GET: api/EmployeeShiftData
public IEnumerable<EmployeeShiftData> Get(string FirstName = "", string LastName = "", string Department = "")
{
return empShiftDataBL.GetAllEmployeeShiftData(FirstName, LastName, Department);
}
//...
}
Would need to see the code that interacts with the database, especially the code that makes the updates.
If the changes are written with Entity Framework, are the models themselves properly related with navigational properties?
public class Employee
{
public int Id { get; set; }
public string Name { get; set; }
public List<EmployeeShift> EmployeeShifts { get; set; }
// etc.
}
public class EmployeeShift
{
public int Id { get; set; }
public Int EmployeeID { get; set; }
public Employee Employee { get; set; }
// etc.
}
If those are good, and both models are covered by Entity Framework's context tracking, then both should be updated.

ASP.NET WEB API Error While Updating Database with Entity Framework

I am new to WEB API, I have problem with crud operations-update
Auto-generated model class which is
public partial class CUSTOMER
{
public int ID { get; set; }
public string NAME { get; set; }
public string SURNAME { get; set; }
public string BIRTHPLACE { get; set; }
public string GENDER { get; set; }
public string IDENTITYNO { get; set; }
public Nullable<int> IDENTITYPINCODE { get; set; }
public Nullable<System.DateTime> BIRTHDATE { get; set; }
}
and I have a class which I save CRUD operations
public class CustomerCRUD
{
AlishEntities db = new AlishEntities();
public CUSTOMER UpdateCustomer(int id, CUSTOMER updatingCustomer)
{
db.Entry(updatingCustomer).State = System.Data.Entity.EntityState.Modified;
db.SaveChanges();
return updatingCustomer;
}
}
Controller:
public class SqlCrudController : ApiController
{
CustomerCRUD crud = new CustomerCRUD();
public HttpResponseMessage Put(int id, Models.CUSTOMER customer)
{
return Request.CreateResponse(HttpStatusCode.OK, crud.UpdateCustomer(id, customer));
}
}
When I test it with postman it says:
"ExceptionMessage": "Store update, insert, or delete statement
affected an unexpected number of rows (0). Entities may have been
modified or deleted since entities were loaded.

how to Pull data with paramter using Azure Offline Sync?

I have schema as below and I would like to know if I can get all the TaskCategoryMappings by CategoryId when I have to pulll all data. I went through the documentation here but I cant figure out how to do it ? All the examples are like this one based on UserId. but userid is used for also authentication and on the server side I already handle it fine to return only mappings belong to relevant user and i want in adition to filter by CategoryId?
another SO sample is here also using userId Parameter Passing with Azure Get Service
public class TaskCategoryMapping : TableData
{
public string TaskId { get; set; }
public string CategoryId { get; set; }
public string UserId { get; set; }
}
According to your description, I checked this issue on my side and found that it could work as expected, you could follow the details below to check your code:
Backend models:
public class Tag : EntityData
{
public string TagName { get; set; }
public bool Status { get; set; }
}
public class Message : EntityData
{
public string UserId { get; set; }
public string Text { get; set; }
public virtual Tag Tag { get; set; }
[ForeignKey("Tag")]
public string Tag_Id { get; set; }
}
GetAllMessage action:
// GET tables/Message
public IQueryable<Message> GetAllMessage()
{
return Query();
}
For the client, I just invoke the online table for retrieving the message entities as follows:
Model on client-side:
public class Message
{
public string Id { get; set; }
public string UserId { get; set; }
public string Text { get; set; }
public string Tag_Id { get; set; }
}
var result=await mobileServiceClient.GetTable<Message>().Where(msg => msg.Tag_Id == "c3cd4cf8-7af0-4267-817e-f84c6f0e1733").ToListAsync();
For offline table, the pull operation query would
await messageSyncTable.PullAsync($"messages_{userid}", messageSyncTable.Where(m => m.Tag_Id == "<Tag_Id>"));
Use fiddler, you could find that the request would look like this:
https://{your-app-name}.azurewebsites.net/tables/Message?$filter=Tag_Id eq 'c3cd4cf8-7af0-4267-817e-f84c6f0e1733'

Entity Framework: Transform names of entities with table of aliases

I have entities Task and TaskAlias:
public class Task {
public int Id { get; set; }
public string Name { get; set; }
}
public class TaskAlias {
public string SourceName { get; set; }
public string TargetName { get; set; }
}
I have Web API method that returns set of Task. For result I need to replace name of Task if table TaskAlias contains alias for the name. How to solve this problem in an optimal way?
foreach (taskCollection as task) {
taskAlias = taskAliasRepository.findByTask(task);
if (taskAlias) {
task.setName(taskAlias.getTargetName);
taskRepository.save(task);
}
}

Web Api: Return JSON with EF Included Member Field Count but not Member Object Data

Scenario: Complaint object can have many Votes. In the GET request for All Complaints, I want to return the Vote Count, and not each individual vote object with the Complaint in the API response.
Here's the main classes:
//Model: Complaint.cs
public class Complaint
{
public int Id { get; set; }
public string Summary { get; set; }
public List<Vote> Votes { get; set; }
public int UpVoteCount=> Votes.Count(v => v.IsUpvote);
public ApplicationUser Creator { get; set; }
}
//Model: Vote.cs
public class Vote
{
public int Id { get; set; }
public bool IsUpVote{ get; set; }
public Complaint Complaint { get; set; }
public ApplicationUser Creator { get; set; }
}
//DbContext: AppDbContext.cs
....
public IQueryable<Complaint> ComplaintsWithData =>
Complaint
.Include(complaint => complaint.Votes)
.AsNoTracking();
//ApiController: ComplaintsController.cs
[HttpGet]
public IEnumerable<Complaint> GetComplaints()
{
return _context.ComplaintsWithData.ToList();
}
In the current JSON response, I get the Vote count, however I also get each individual vote object's details as well (which I don't need in this call).
Current Response:
{
"id": 2,
"summary": "House was Stolen",
"votes": [
{
"id": 146,
"isUpvote": false,
"creator": null
},
{
"id": 147,
"isUpvote": false,
"creator": null
},
....
....
....
],
"upVoteCount": 211,
}
Desired Response:
{
"id": 2,
"summary": "House was Stolen",
"upVoteCount": 211,
}
I need to have the .Include(complaint => complaint.Votes) in the AppDbContext.cs file so that I can actually load the Votes to determine the Vote Count.
I do not want to store the Vote count as an actual database column.
Any advice would be greatly appreciated!
I am using .NET Core 2.0 Web API with Entity Framework Core.
Thanks in advance.
You can use OptIn on your class for members serialization:
//..
using Newtonsoft.Json;
//..
[JsonObject(MemberSerialization.OptIn)]
public class Complaint
{
[JsonProperty("id")]
public int Id { get; set; }
[JsonProperty("summary")]
public string Summary { get; set; }
public List<Vote> Votes { get; set; }
[JsonProperty("upVoteCount")]
public int UpVoteCount=> Votes.Count(v => v.IsUpvote);
public ApplicationUser Creator { get; set; }
}
Maybe something like:
public List<Complaint> ComplaintsWithData()
{
return this.DbContext.Complaints
.Include(complaint => complaint.Votes)
.Select(p => new Complaint
{
Id = p.Id,
IsUpVote = p.IsUpVote,
UpVoteCount = p.Votes.Count
}).ToList();
}
There are several options. Below are two of them:
You might consider adding view models - classes with the exact set of properties you would like to return to UI. You just need to map your entity records to them.
Or just mark the properties you'd like to hide from being serialized to your JSON or XML endpoint response with NonSerialized attribute.
public class Complaint
{
public int Id { get; set; }
public string Summary { get; set; }
[NonSerialized]
public List<Vote> Votes { get; set; }
public int UpVoteCount=> Votes.Count(v => v.IsUpvote);
public ApplicationUser Creator { get; set; }
}