Adding a list of objects to SQL Server - ASP.NET Web API - asp.net

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 { }
}

Related

An error I encountered while getting a json file

I need to pull a json file on the remote server.I leave the link of the file here.
turkmedya.com.tr/anasayfa.json
I also share the open version of the json file as a photo.enter image description here
I also have to pull the categories from the file. Can you give me a hand?
Anasayfa.cs
public class data
{
public string sectionType { get; set; }
public string titleBgColor { get; set; }
public IList<veri> itemList { get; set; }
}
public class veri
{
public string shortText { get; set; }
public string fullPath { get; set; }
public string itemId { get; set; }
public string imageUrl { get; set; }
}
public class cat
{
public string categoryId { get; set; }
public string Title{ get; set; }
}
public class ListJson
{
public string errorMessage { get; set; }
public IList<data> data { get; set; }
public IList<cat> category { get; set; }
}
HomeController.cs
public ActionResult Index()
{
string url = #"http://turkmedya.com.tr/anasayfa.json";
string jsonVerisi = "";
try
{
using (WebClient response = new WebClient())
{
jsonVerisi = response.DownloadString(url);
}
ListJson account = JsonConvert.DeserializeObject<ListJson>(jsonVerisi);
foreach (var list in account.data)
{
System.Console.WriteLine(list.ToString());
ViewBag.ca = list.itemList.ToList();
var a = account.data.Count;
var b = list.itemList.Count;
}
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
return View();
}

Post JSON Array in Asp.Net Web API

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; }
}

AutoMapper with auto-incremented values

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;
});
}

Selecting a subset of data in ServiceStack.OrmLite

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>();

Insert multiple values from text box to the data base using the list<string>

This is the required image, I want to insert multiple value through Name, Employee Code and E-mail Id, by submit button which is in this page.
My database contains following field Id(primary key),Name (varchar 50),Employee Code (varchar 50), E-mail Id (varchar 50).
In the data layer, I code as following:
public static bool AddParticipantlistemployeecode(DimensionQuestion dimension)
{
bool result;
using (var helper = new DbHelper())
{
_cmdtext = "sp_NewGeneratedUniqueCode";
var success = new SqlParameter("#Success", SqlDbType.Bit, 1, ParameterDirection.Output, true, 0, 0,
"Result", DataRowVersion.Default, 0);
foreach (string s in dimension.CandidateName)
{
if (s.Trim().Length > 0)
{
var parameter = new[]
{
// new SqlParameter("#CompanyName",dimension.CompanyName ),
new SqlParameter("#CandidateName",s ),
new SqlParameter("#EmployeeCode",s ),
new SqlParameter("#EmailId",s ),
success,
};
helper.ExecuteScalar(_cmdtext, CommandType.StoredProcedure, parameter);
}
}
result = (bool)success.Value;
}
return result;
}
In the Model layer:
using System.Text;
using System.Collections.Generic;
namespace Cengrow.Survey.Core.Model
{
public class DimensionQuestion
{
public string CompanyName { get; set; }
// public string DimensionNumber { get; set; }
public List<string> CandidateName { get; set; }
public List<string> EmployeeCode { get; set; }
public List<string> EmailId { get; set; }
public int DimensionName { get; set; }
public string Section { get; set; }
//public string Rating { get; set; }
public List<string> Questions { get; set; }
//public string Question2 { get; set; }
//public string Question3 { get; set; }
//public string Question4 { get; set; }
//public string Question5 { get; set; }
//public string Question6 { get; set; }
//public string Question7 { get; set; }
//public string Question8 { get; set; }
//public string Question9 { get; set; }
//public string Question10 { get; set; }
//public string Question11 { get; set; }
//public string Question12 { get; set; }
//public string Question13 { get; set; }
//public string Question14 { get; set; }
//public string Question15 { get; set; }
}
}
And finally in the business logic on the button click:
protected void Button1_Click(object sender, EventArgs e)
{
try
{
FillObjects();
//if (InsertData.InsertCandidateCompany(_CandidateCompanyInformation ))
if (InsertData.AddParticipantlistemployeecode(_DimensionQuestion))
{
ShowMessage("Information is saved");
//Reset();
}
else
{
ShowMessage("Please try again");
}
}
finally
{
_DimensionQuestion = null;
}
}
private void FillObjects()
{
List<string> sp = new List<string>();
_DimensionQuestion = new Cengrow.Survey.Core.Model.DimensionQuestion();
// _DimensionQuestion.CompanyName = txtCompanyName.Text.Trim();
sp.Add(txtName1.Text.Trim());
sp.Add(txtName2.Text.Trim());
sp.Add(txtName3.Text.Trim());
sp.Add(txtName4.Text.Trim());
sp.Add(txtName5.Text.Trim());
sp.Add(txtName6.Text.Trim());
sp.Add(txtName7.Text.Trim());
sp.Add(txtName8.Text.Trim());
sp.Add(txtName9.Text.Trim());
sp.Add(txtName10.Text.Trim());
sp.Add(txtName11.Text.Trim());
sp.Add(txtName12.Text.Trim());
sp.Add(txtName13.Text.Trim());
sp.Add(txtName14.Text.Trim());
sp.Add(txtName15.Text.Trim());
sp.Add(txtName16.Text.Trim());
sp.Add(txtName17.Text.Trim());
sp.Add(txtName18.Text.Trim());
sp.Add(txtName19.Text.Trim());
sp.Add(txtName20.Text.Trim());
sp.Add(txtName21.Text.Trim());
sp.Add(txtName22.Text.Trim());
sp.Add(txtName23.Text.Trim());
sp.Add(txtName24.Text.Trim());
sp.Add(txtName25.Text.Trim());
_DimensionQuestion.CandidateName = sp;
sp.Add(txtEmployeeCode1.Text.Trim());
sp.Add(txtEmployeeCode2.Text.Trim());
sp.Add(txtEmployeeCode3.Text.Trim());
sp.Add(txtEmployeeCode4.Text.Trim());
sp.Add(txtEmployeeCode5.Text.Trim());
sp.Add(txtEmployeeCode6.Text.Trim());
sp.Add(txtEmployeeCode7.Text.Trim());
sp.Add(txtEmployeeCode8.Text.Trim());
sp.Add(txtEmployeeCode9.Text.Trim());
sp.Add(txtEmployeeCode10.Text.Trim());
sp.Add(txtEmployeeCode11.Text.Trim());
sp.Add(txtEmployeeCode12.Text.Trim());
sp.Add(txtEmployeeCode13.Text.Trim());
sp.Add(txtEmployeeCode14.Text.Trim());
sp.Add(txtEmployeeCode15.Text.Trim());
sp.Add(txtEmployeeCode16.Text.Trim());
sp.Add(txtEmployeeCode17.Text.Trim());
sp.Add(txtEmployeeCode18.Text.Trim());
sp.Add(txtEmployeeCode19.Text.Trim());
sp.Add(txtEmployeeCode20.Text.Trim());
sp.Add(txtEmployeeCode21.Text.Trim());
sp.Add(txtEmployeeCode22.Text.Trim());
sp.Add(txtEmployeeCode23.Text.Trim());
sp.Add(txtEmployeeCode24.Text.Trim());
sp.Add(txtEmployeeCode25.Text.Trim());
_DimensionQuestion.EmployeeCode = sp;
sp.Add(TextBox1.Text.Trim());
sp.Add(TextBox2.Text.Trim());
sp.Add(TextBox3.Text.Trim());
sp.Add(TextBox4.Text.Trim());
sp.Add(TextBox5.Text.Trim());
sp.Add(TextBox6.Text.Trim());
sp.Add(TextBox7.Text.Trim());
sp.Add(TextBox8.Text.Trim());
sp.Add(TextBox9.Text.Trim());
sp.Add(TextBox10.Text.Trim());
sp.Add(TextBox11.Text.Trim());
sp.Add(TextBox12.Text.Trim());
sp.Add(TextBox13.Text.Trim());
sp.Add(TextBox14.Text.Trim());
sp.Add(TextBox15.Text.Trim());
sp.Add(TextBox16.Text.Trim());
sp.Add(TextBox17.Text.Trim());
sp.Add(TextBox18.Text.Trim());
sp.Add(TextBox19.Text.Trim());
sp.Add(TextBox20.Text.Trim());
sp.Add(TextBox21.Text.Trim());
sp.Add(TextBox22.Text.Trim());
sp.Add(TextBox23.Text.Trim());
sp.Add(TextBox24.Text.Trim());
sp.Add(TextBox25.Text.Trim());
_DimensionQuestion.EmailId = sp;
}
The data is not coming proper into the database
You are adding the same value to all three parameters:
new SqlParameter("#CandidateName",s ),
new SqlParameter("#EmployeeCode",s ),
new SqlParameter("#EmailId",s
In all cases you are adding "s" which is CandidateName.
Edit: Candidate should be a class:
public class Candidate
{
public string Name { get; set; }
public string EmployeeCode { get; set; }
public string Email { get; set; }
public Candidate(string name, string code, string email)
{
this.Name = name;
this.EmployeeCode = code;
this.Email = email;
}
}
Then your DimensionQuestion should contain a
List<Candidate> Candidates
instead of
public List<string> CandidateName { get; set; }
public List<string> EmployeeCode { get; set; }
public List<string> EmailId { get; set; }
Then you FillObjects method add Candidate objects to the Candidates list
Candidates.Add(new Candidate(txtName1.Text.Trim(),
txtEmployeeCode1.Text.Trim(),
TextBox1.Text.Trim()));
Candidates.Add(new Candidate(txtName2.Text.Trim(),
txtEmployeeCode2.Text.Trim(),
TextBox2.Text.Trim()));
Finaly your data layer should be:
foreach (Candidate candidate in dimension.Candidates)
{
if (!String.IsNullOrEmpty(candidate.Name))
{
var parameter = new[]
{
// new SqlParameter("#CompanyName",dimension.CompanyName ),
new SqlParameter("#CandidateName",candidate.Name ),
new SqlParameter("#EmployeeCode",candidate.Code ),
new SqlParameter("#EmailId",candidate.Email ),
success,
};
helper.ExecuteScalar(_cmdtext, CommandType.StoredProcedure, parameter);
}
}

Resources