public class OrderDTO
{
public string ClientName { get; set; }
public ICollection<OrderDetailDTO> Details { get; set; }
}
public class Order
{
public string ClientName { get; set; }
public ICollection<OrderDetail> Details { get; set; }
}
public class OrderDetailDTO
{
public int Quantity { get; set; }
public string ProductName { get; set; }
}
public class OrderDetail
{
public int OrderId { get; set; }
public int Quantity { get; set; }
public string ProductName { get; set; }
}
Let's say there are 4 OrderDetailDTO, I want to have the mapped OrderDetail instances with auto-incremented integer values. What I am doing now is post-process the mapped instance.
var mappedOrder = Mapper.Map<OrderDTO, Order>(orderDto);
var orderId = 1;
foreach (OrderDetail detail in mappedOrder.Details)
{
detail.OrderId = orderId++;
}
How can I configure the mapping options, so that the mapped ICollection<OrderDetail> contains 4 OrderDetail instances with OrderId as 1, 2, 3, 4?
You could configure AutoMapper to do this with AfterMap:
Mapper.CreateMap<OrderDTO, Order>()
.AfterMap((src, dest) =>
{
int orderId = 1;
foreach (OrderDetail detail in dest.Details)
{
detail.OrderId = orderId++;
}
});
I don't think there's really a "cleaner" way to do it using AutoMapper.
I use the following method which is much simpler and can be written in a base class or an extension method. The example here uses Generics but can be easily transformed
protected virtual IEnumerable<T> ConvertCsvLines(IEnumerable<TV> lines)
{
var lineNumber = 0;
return lines.Select(x =>
{
var retVal = Mapper.Map<TV, T>(x);
retVal.LineNumber = lineNumber++;
return retVal;
});
}
Related
i have this controller method that return an array of objects
public async Task<ActionResult<List<AllClientsDataModelDb>>> GetAll()
{
var ReturnValue = new List<AllClientsDataModelDb>();
ReturnValue = await Clda.GetClients(new { cm = 1 });
return (ReturnValue);
}
here is the code of AllClientsDataModelDb class
public class AllClientsDataModelDb
{
public long IDCLIENT { get; set; }
public string CL_CODE { get; set; }
public string CL_NOM { get; set; }
public string CL_ADRESSE { get; set; }
public string CL_CODEPOS { get; set; }
public string CL_VILLE { get; set; } = null;
public int CL_ETATCOMPTE { get; set; }
public int CL_AlerteCompta { get; set; }
}
but the result of that method (in browser) does not respect the case sensitivity of the class properties
Example :
[{"idclient":1,"cL_CODE":"1","cL_NOM":"EUROPEQUIPEMENTMysql","cL_ADRESSE":"ModifSoft","cL_CODEPOS":"44","cL_VILLE":"STDENIS","cL_ETATCOMPTE":1,"cL_AlerteCompta":0},
{"idclient":2,"cL_CODE":"2","cL_NOM":"A UTOMATISMES-SERVICESzzzz","cL_ADRESSE":null,"cL_CODEPOS":"97420","cL_VILLE":"LEPORT","cL_ETATCOMPTE":1,"cL_AlerteCompta":0},
what i'm doing wrong ?
You need to create your own Json Profile Formatter by inheriting from JsonOutputFormatter.
public class PascalCaseJsonProfileFormatter : JsonOutputFormatter
{
public PascalCaseJsonProfileFormatter() : base(new JsonSerializerSettings { ContractResolver = new DefaultContractResolver() }, ArrayPool<char>.Shared)
{
SupportedMediaTypes.Clear();
SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse
("application/json;profile=\"https://en.wikipedia.org/wiki/PascalCase\""));
}
}
Then modify your Startup.cs file's ConfigureServices Method like this.
services.AddMvc()
.AddMvcOptions(options =>
{
options.OutputFormatters.Add(new PascalCaseJsonProfileFormatter());
});
Try this, it should work.
I'm trying to add a list of objects to a SQL Server database via Entity Framework but I get an error with Add
[HttpPost]
public void Post(List<Row> rows)
{
try
{
using (DbModel dbModel = new DbModel())
{
foreach (var el in rows)
{
dbModel.Provider_Status.Add(el);
}
dbModel.SaveChanges();
}
}
catch { }
}
Row class:
public class Row
{
public string FileName { get; set; }
public string FileTitle { get; set; }
public string ProviderID { get; set; }
public string ServiceID { get; set; }
public string PublishDate { get; set; }
public string ExpiryDate { get; set; }
}
Database Model DbModel:
public partial class Provider_Status
{
public int Id { get; set; }
public string FileName { get; set; }
public string FileTitle { get; set; }
public string ProviderID { get; set; }
public string ServiceID { get; set; }
public string PublishDate { get; set; }
public string ExpiryDate { get; set; }
}
Error Message:
CS1503 Argument 1: cannot convert from 'File_Upload.Models.Row' to 'File_Upload.Models.Provider_Status
Your DbModel defines a data set of type Provider_Status - so if you want to add data to this data set, you need to provide Provider_Status objects - not Row objects (as you do now).
You need to convert those Row object to Provider_Status - try something like this:
[HttpPost]
public void Post(List<Row> rows)
{
try
{
using (DbModel dbModel = new DbModel())
{
foreach (var el in rows)
{
// create a new "Provider_Status" object, based on the
// "Row" values being passed in
Provider_Status status = new Provider_Status
{
FileName = el.FileName
FileTitle = el.FileTitle
ProviderID = el.ProviderID
ServiceID = el.ServiceID
PublishDate = el.PublishDate
ExpiryDate = el.ExpiryDate
};
// add that new Provider_Status object to your dbModel
dbModel.Provider_Status.Add(status);
}
dbModel.SaveChanges();
}
}
catch { }
}
I have a model class
namespace myapp.Models
{
public class SubjectModels
{
[Key]
public int SubjectId { get; set; }
[Required]
public int SubjectType { get; set; }
[Required]
[MinLength(5)]
public string SubjectName { get; set; }
}
}
Here, SubjectType = 1 for Optional and SubjectType = 2 for Compulsory
Now in another class I have to create a drop down for this class,
namespace myapp.Models
{
public class SelectionModels
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int SelectionId { get; set; }
[Required]
[MinLength(5)]
public string SelectionDate { get; set; }
[ForeignKey("SubjectId")]
public SubjectModels Subject { get; set; }
public int SubjectId { get; set; }
}
}
When I genereted controller and create.cshtml via scaffolding, my create controller method:
public ActionResult Create()
{
ViewBag.SubjectId = new SelectList(db.Subjects, "SubjectId", "SubjectName");
return View();
}
But I have to create a drop down concatenating the fields "SubjectName" and "SubjectType". Also, display for SubjectType should be Optional and Compulsory not integer.
for example,
"Optional - ResearchMethodology"
"Compulsory - BioChemistry"
How shall I do this? I googled but could not found suitable solutions. Please help!!!
I would create an extra property in the SubjectModels class.
class SubjectModels
{
public int SubjectId { get; set; }
public int SubjectType { get; set; }
public string SubjectName { get; set; }
public string SubjectNameAndType
{
get
{
return string.Format("{0} - {1}", SubjectName, SubjectType);
}
}
}
Then in the Controller you can use that property to fill the SelectList
var list = new List<SubjectModels>()
{
new SubjectModels()
{
SubjectType = 1,
SubjectName = "Name 1"
},
new SubjectModels()
{
SubjectType = 2,
SubjectName = "Name 2"
}
};
ViewBag.SubjectId = new SelectList(list, "SubjectId", "SubjectNameAndType");
Now you will see the correct values in the DropDownList.
#Html.DropDownListFor(m => m.MyValue, (SelectList)ViewBag.SubjectId, "Select...")
Hi every one I am new to ASP.Net Web API and I want to Post JSON array data any get there response.
My JSON POST Array format is
{
"User_Id":"admi12n#1234","Key_Code":"3F-47-AB-84-9F-EB-D6-6B-9C-62-CC-85-98-4D-28-6B",
"ProductDetails": [
{"Product_Id":"ELT-7035","Price":"999","Quantity":"5"},
{"Product_Id":"ELT-1254","Price":"1024","Quantity":"3"}
]
}
And I want response as follows
{
"User_Id":"admi12n#1234","Key_Code":"3F-47-AB-84-9F-EB-D6-6B-9C-62-CC-85-98-4D-28-6B",
"OrderID":"Ord-021","Name":"Sabyasachi"
"ProductDetails": [
{"Product_Id":"ELT-7035","Price":"999","Quantity":"5"},
{"Product_Id":"ELT-1254","Price":"1024","Quantity":"3"}
]
}
I generate OrderID as Random and Name from posted User_Id. Here I want to post multiple product in one order.
My Order class is as follows
public class Order
{
[Key]
public long ID { get; set; }
public string Order_Id { get; set; }
public string Product_Id { get; set; }
public long Quantity { get; set; }
public long Amount { get; set; }
public string User_Id { get; set; }
public string Key_Code { get; set; }
public DateTime Order_Date { get; set; }
public DateTime Modified_Date { get; set; }
}
And my Product class as follows
public class Product
{
[Key]
public int Id { get; set; }
public string Product_Code { get; set; }
public string Product_Name { get; set; }
public string Product_Category { get; set; }
public string Product_Description { get; set; }
public string Quantity { get; set; }
public string Price { get; set; }
public string Image { get; set; }
public DateTime Created_Date { get; set; }
public DateTime Modified_Date { get; set; }
}
I am not able to ind the best way to post the order
public Order Add(Order odrerDetails) //This will not give array of data for products
{
using (var context = new EcommerceDBContext())
{
odrerDetails.Order_Id = Helper.Random(7); //Generate random orderID from my class
odrerDetails.Created_Date = DateTime.Now;
odrerDetails.Modified_Date = DateTime.Now;
//How to Save other details
context.objOrderListing.Add(odrerDetails);
context.SaveChanges();
return odrerDetails;
}
}
In API controllers my code is as follows
public HttpResponseMessage PostOrder([FromBody] Order_Listing orderData)
{
orderData = repository.Add(orderData);
var response = Request.CreateResponse<Order_Listing>(HttpStatusCode.Created, orderData);
string uri = Url.Link("DefaultApi", new { customerID = orderData.ID });
response.Headers.Location = new Uri(uri);
return response;
}
Please help me how to achieve this.
There are several issues with your code:
Your Order and Product classes do not reflect the structure of
your JSON.
The Order class contains product details in a 1:1
relationship. Based on the JSON I assume you want a 1:n relationship.
Properties in your JSON need to have the same name as
in your classes or they won't be mapped.
Change your classes to the following and it should work.
Of course you could also change the property names in your JSON.
If you can't or don't want to change your property names, consider using DTOs
public class Order
{
public string User_Id { get; set; }
public string Key_Code { get; set; }
public string OrderID { get; set; }
public string Name { get; set; }
public List<Product> ProductDetails { get; set; }
// add the rest of your properties
}
public class Product
{
public string Product_Id { get; set; }
public string Price { get; set; }
public string Prd_Qty { get; set; }
// add the rest of your properties
}
Update: added code for Add method and Api method
Your Add method would look like this:
public Order Add(Order orderWithDetails)
{
using (var context = new EcommerceDBContext())
{
orderWithDetails.Order_Id = Helper.Random(7); //Generate random orderID from my class
orderWithDetails.Created_Date = DateTime.Now;
orderWithDetails.Modified_Date = DateTime.Now;
context.objOrderListing.Add(orderWithDetails);
// Save each Product
foreach (var detail in orderWithDetails.ProductDetails)
{
//whatever you need to do in your db-context
context.objOrderDetails.Add(detail); // just an example
}
context.SaveChanges();
return orderWithDetails;
}
}
The signature of your Api method looks wrong. What is Order_Listing? This should be Order, unless it's a DTO, in wich case you need a method to get an Order from Order_Listing.
public HttpResponseMessage PostOrder([FromBody] Order orderData)
{
orderData = repository.Add(orderData);
var response = Request.CreateResponse<Order_Listing>(HttpStatusCode.Created, orderData);
string uri = Url.Link("DefaultApi", new { customerID = orderData.ID });
response.Headers.Location = new Uri(uri);
return response;
}
A few more remarks:
If it is indeed a 1:n relationship, you probably need a property Product.OrderId.
The Order class should not have any reference to Product except for the list.
Quantity and Price should most likely not be String but numerical values, e.g. decimal.
If Order.ID is your primary key, then having Order.Order_ID is really confusing. Consider renaming it to Order.Order_Number.
public class Order
{
public string User_Id { get; set; }
public string Key_Code { get; set; }
public string OrderID { get; set; }
public string Name { get; set; }
public Product[] ProductDetails { get; set; }
}
Is there any way to return a subset of a table in ServiceStack.OrmLite?
Something like:
public class MyStuff
{
public Guid Id { get; set; }
public string Name { get; set; }
public byte[] Data { get; set; } // Some large blob, which is not desired in the list
}
var somestuff = db.Select<MyStuff>(x => new { Id = x.Id, Name = x.Name });
I am really hoping to avoid manual stuff, like "select blabla from somewhere"...
I had that exact same problem. Here is what I did:
public class MyStuff
{
public Guid Id { get; set; }
public string Name { get; set; }
public byte[] Data { get; set; }
}
var somestuff = Db.Select<MyStuff>(p => p.Select(x => new { x.Id, x.Name }));
The only changes made, to what you did above, were done to the Db.Select.
Create a class for your basic information and set an alias.
[Alias("MyStuff")]
public class MyBasicStuff
{
public Guid Id { get;set; }
public string Name { get; set; }
}
var basicStuff = db.Select<MyBasicStuff>();