After trying to mix a fileupload and json data in postman i finally found a method where it is possible to send them both in the same request. Therefore, I have moved my json data to a Key in Postman, so that it becomes possible to send files as well using form-data (Picture below).
Within the value I have JSON data as following:
{
"WorkshopEmail":"workshopemail",
"WorkshopContactperson":"workshopcontactperson",
"WorkshopCellphone":"workshopcellphone",
"Service":[
{
"service":"Claim Airbag",
"RequestTypeId":"1",
"DamageDate":"2021-05-03",
"DamageKilometerreading":"213",
"LatestServiceDate":"2021-05-03",
"LatestServiceKilometer":"1223",
"WorkshopDiagnos":"diagnos workshop",
"CarOwnerDescription":"carownerdescription",
"CategoryId":"25",
"works":[
{
"title":"arbete 1 airbag",
"chargePerHour":"11",
"hours":"12",
"price":"132.00",
"id":"13926"
},
{
"title":"arbete2 airbag",
"chargePerHour":"1",
"hours":"2",
"price":"2.00",
"id":"13927"
},
{
"title":"part1 airbag",
"pricePerUnit":"100",
"quantity":"1",
"price":"100.00",
"id":"13928"
},
{
"title":"part2 airbag",
"pricePerUnit":"100",
"quantity":"2",
"price":"200.00",
"id":"13929"
}
]
},
{},
{},
{},
{},
{}
]
}
The empty {} just contains more service types. Now when I send the request in Postman i get a 200 OK and when i debug i can see the following (sorry if the picture is blurry):
¨
However, my database does not get updated with these values. Here's the class for inserting data into the tables:
public async Task<bool> AddRequest(Request model, List<IFormFile> file, [FromForm] string jsonData)
{
bool CreateRequest = true;
int requestID = 0;
int claimID = 0;
//bool country = true;
//First Create the Request
foreach (Service item in model.Service)
{
//First Create the Request
if (CreateRequest)
{
var parameters = new DynamicParameters();
parameters.Add("WorkshopEmail", model.WorkshopEmail);
parameters.Add("WorkshopContactperson", model.WorkshopContactperson);
parameters.Add("WorkshopCellphone", model.WorkshopCellphone);
parameters.Add("DamageDate", model.DamageDate);
parameters.Add("LatestServiceDate", model.LatestServiceDate);
parameters.Add("LatestServiceKilometer", model.LatestServiceKilometer);
parameters.Add("DamageKilometerreading", model.DamageKilometerreading);
parameters.Add("CurrentKilometerreading", model.CurrentKilometerreading);
parameters.Add("CarOwnerDescription", model.CarOwnerDescription);
parameters.Add("WorkshopDiagnos", model.WorkshopDiagnos);
parameters.Add("AmountIncVat", model.AmountIncVat);
try
{
var requestIDenum = await _sqlconnection.QueryAsync<int>($#"INSERT INTO [dbo].[Request]
(WorkshopEmail,WorkshopContactperson,WorkshopCellphone,DamageDate,LatestServiceDate,
LatestServiceKilometer,DamageKilometerreading,CurrentKilometerreading,
CarOwnerDescription,WorkshopDiagnos,AmountIncVat)
VALUES
(#WorkshopEmail,#WorkshopContactperson,#WorkshopCellphone,#DamageDate,#LatestServiceDate,
#LatestServiceKilometer,#DamageKilometerreading,#CurrentKilometerreading,
#CarOwnerDescription,#WorkshopDiagnos,#AmountIncVat);SELECT SCOPE_IDENTITY();",parameters);
requestID = requestIDenum.First();
CreateRequest = false;
}
catch(Exception ex)
{
int hej = 0;
}
}
if (item.fileuploadresults != null)
{
foreach (FileUploadResult f in item.fileuploadresults)
{
var parameters = new DynamicParameters();
parameters.Add("file", f.filename);
var filemessage = await _sqlconnection.QueryAsync<int>($#"INSERT INTO [dbo].[OptionalFile] ([FileName])
VALUES (#file); SELECT SCOPE_IDENTITY();", parameters);
int FileMessageID = filemessage.First();
await _sqlconnection.QueryAsync<int>($#"INSERT INTO[dbo].[ClaimCrossOptionalFile]
(ClaimID,FileID)
VALUES
({claimID},{FileMessageID});");
}
}
return true;
//return list;
}
Controller:
[HttpPost]
public async Task<IActionResult> AddRequest(List<IFormFile> file, [FromForm] string jsonData)
{
// if (!ModelState.IsValid)
// {
Request request = JsonConvert.DeserializeObject<Request>(jsonData);
try
{
//await _request.AddRequest(request);
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
return Ok();
}
Interface:
Task<bool> AddRequest(Request model, List<IFormFile> file, [FromForm] string jsonData);
Sidenote: This is part of the code, as i've tried to keep it short, so perhaps some } or something is missing here, but there's no problem. If i should add the whole code i could perhaps send it in a link or something similar, as it would be a lot to upload here.
However, I do not now how to proceed with this issue at the moment. I've not worked with form-data much before, at least not with passing json as a value. Perhaps there's something I'm missing/have to do in the controller with the json data? I've tried looking for solutions but I've gotten stuck here. The only issue is that the database does not get updated.
Update, the model:
public class Work
{
//base for claim
public string title { get; set; } = "";
public string chargePerHour { get; set; } = "";
public string hours { get; set; } = "";
public string price { get; set; } = "";
public string id { get; set; } = "";
public string pricePerUnit { get; set; } = "";
public string quantity { get; set; } = "";
//service
public int rentreasonId { get; set; } = -1;
public int rentservicecartypeId { get; set; } = -1;
//tyres
public int tireserviceId { get; set; } = -1;
public IList<TireType> tireTypes { get; set; }
public IList<Labour> labours { get; set; }
public DateTime DateFrom{ get; set; } = DateTime.Parse("1753-01-01");
public DateTime DateTo { get; set; } = DateTime.Parse("1753-01-01");
//Insurance
public string totalAmount { get; set; }
public string requestInsuranceVatID { get; set; }
public string vat { get; set; } = "0.0";
public string totalExclVat { get; set; }="0.0";
public string totalIncVat { get; set; }="0.0";
}
public class Labour
{
public string title { get; set; } = "";
public string chargePerHour { get; set; } = "";
public string hours { get; set; } = "";
public string price { get; set; } = "";
}
public class TireType
{
public string quantity { get; set; } = "";
public string brand { get; set; } = "";
public string model { get; set; } = "";
public string pricePerUnit { get; set; } = "";
public string price { get; set; } = "";
public string tireTypeId { get; set; } = "";
public string widthID { get; set; } = "";
public string heightID { get; set; } = "";
public string diameterID { get; set; } = "";
}
public class Request
{
public string WorkshopEmail { get; set; } = "";
public string WorkshopContactperson { get; set; } = "";
public string WorkshopCellphone { get; set; } = "";
public int AmountIncVat { get; set; } = 0;
#region Claim
public DateTime DamageDate { get; set; } = DateTime.Parse("1753-01-01");
public DateTime LatestServiceDate { get; set; } = DateTime.Parse("1753-01-01");
public int LatestServiceKilometer { get; set; } = 0;
public int DamageKilometerreading { get; set; } = 0;
public int CurrentKilometerreading { get; set; } = 0;
public string CarOwnerDescription { get; set; } = "";
public string WorkshopDiagnos { get; set; } = "";
//public string OptionalMessage { get; set; } = "";
#endregion
public IList<Service> Service { get; set; }
}
public class TireTread
{
public string tireserviceId { get; set; } = "";
public string leftfront { get; set; } = "";
public string rightfront { get; set; } = "";
public string leftrear { get; set; } = "";
public string rightrear { get; set; } = "";
public string added1 { get; set; } = "";
public string added2 { get; set; } = "";
public string added3 { get; set; } = "";
public string added4 { get; set; } = "";
public string added5 { get; set; } = "";
}
public class TireMessage
{
public int tireserviceId { get; set; }
public string message { get; set; }
}
public class Service
{
// [JsonProperty("ServiceId")]
public string RequestTypeId { get; set; } = "";
public string CategoryId { get; set; } = "-1";
public string OptionalMessage { get; set; } = "";
public IList<Work> works { get; set; }
public IList<TireTread> treads { get; set; }
public IList<TireMessage> TireMessages { get; set; }
//filuppladdning
public IList<FileUploadResult> fileuploadresults { get; set; }
}
//filuppladdning
public class FileUploadResult
{
//public IFormFile files { get; set; }
public string filename { get; set; }
}
Firstly,the json format does not match the model structure.You need to pass json like this(Pay attention to DamageKilometerreading and LatestServiceKilometer,the type of them are int,so don't use ""):
{
"WorkshopEmail":"workshopemail",
"WorkshopContactperson":"workshopcontactperson",
"WorkshopCellphone":"workshopcellphone",
"DamageDate":"2021-05-03",
"DamageKilometerreading":213,
"LatestServiceDate":"2021-05-03",
"LatestServiceKilometer":1223,
"WorkshopDiagnos":"diagnos workshop",
"CarOwnerDescription":"carownerdescription",
"Service":[
{
"service":"Claim Airbag",
"RequestTypeId":"1",
"CategoryId":"25",
"works":[
{
"title":"arbete 1 airbag",
"chargePerHour":"11",
"hours":"12",
"price":"132.00",
"id":"13926"
},
{
"title":"arbete2 airbag",
"chargePerHour":"1",
"hours":"2",
"price":"2.00",
"id":"13927"
},
{
"title":"part1 airbag",
"pricePerUnit":"100",
"quantity":"1",
"price":"100.00",
"id":"13928"
},
{
"title":"part2 airbag",
"pricePerUnit":"100",
"quantity":"2",
"price":"200.00",
"id":"13929"
}
]
},
{},
{},
{},
{},
{}
]
}
Then try to add public string service { get; set; }="" inService model.
I found a solution, in case anyone else comes across this problem. I needed to modify the controller and add this code:
[HttpPost]
public async Task<IActionResult> AddRequest(List<IFormFile> file, [FromForm] string jsonData)
{
Request request = JsonConvert.DeserializeObject<Request>(jsonData);
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
try
{
await _request.AddRequest(request, file, jsonData);
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
return Ok();
}
Basically adding request (that I deserialize in the begining of the method), and adding the file, and jsonData in an await request, solved the problem. As for the fileuploading, I needed to modify that method as well, to get the filename into the database:
if (file != null)
{
foreach (IFormFile f in file)
{
string filename = Path.GetFileName(f.FileName);
var parameters = new DynamicParameters();
parameters.Add("file", filename);
var filemessage = await _sqlconnection.QueryAsync<int>($#"INSERT INTO
[dbo].[OptionalFile] ([FileName])
VALUES (#file); SELECT SCOPE_IDENTITY();", parameters);
}
}
Changing these to made it possible to send a request containg both the json key value, and multiple files, in the same request.
I have two POCO types
PdfIndex and PieceEM:
public class PdfIndex
{
public string Path { get; set; }
public PieceEM Pdf { get; set; }
}
And PieceEM:
public class PieceEM
{
public string Id { get; set; }
public string Content { get; set; }
public string Language { get; set; }
public string Profession { get; set; }
public string DeparmentOfPiece { get; set; }
public string PieceType { get; set; }
public string PricingType { get; set; }
public string PieceId { get; set; }
public string Author { get; set; }
}
All pdfs read and but not indexed.
The code does not fail, just this address has no data
http://localhost:9200/fullegalpieces/_search?pretty=true
This is my index code:
public void IndexPiece(IEnumerable<PdfIndex> pdfIndexes)
{
foreach (var pdfIndex in pdfIndexes)
{
if (!File.Exists(pdfIndex.Path)) continue;
var pdfReader = new PdfReader(pdfIndex.Path);
string text = string.Empty;
for (int page = 1; page <= pdfReader.NumberOfPages; page++)
{
text += PdfTextExtractor.GetTextFromPage(pdfReader, page);
}
pdfReader.Close();
PieceEM _pdf = pdfIndex.Pdf;
_pdf.Content = IndexDocumentHelper.RemoveSpecialChar(text);
_pdf.Content += _pdf.Author;
_elasticClient.Index(_pdf, i => i
.Type<PieceEM>());
}
}
Path is correct.
This pdf exists locally,
and my post action is here:
[HttpPost]
public void IndexPiece(List<PdfIndex> pdfIndexes)
{
var elastic = new ElasticHelper.ElasticSearchHelper("http://localhost:9200/", "fullegalpieces");
elastic.IndexPiece(new List<PdfIndex> {
new PdfIndex
{
Path = #"C:\Users\Yılmaz\Desktop\özgeçmiş.pdf",
Pdf = new PieceEM
{
Id = "042f01f8-befc-40a7-9339-fa4fffe2c4e0",
PieceId = "bd7aaa9c-7c81-4675-a037-0fa56ad09003",
Language = "1",
PieceType ="2",
PricingType = "1",
Profession = "1",
Author = "ykaraagac",
DeparmentOfPiece = "1"
}
}
});
}
I have similar examples, but this does not work.
What can I do?
Thanks.
i checked my local log file and i saw this:
i indexed different POCO type, not PieceEM
I would like to just post on Mvc Action result which is in controller name Home from an Action result in same controller,the Post request send successfully but the parameters lost passing value.
Calling Post From Controller Home
[ValidateInput(false)]
[HttpPost]
public ActionResult addToWishList(string customcode, string addcusimgSVG, string pagestatus = "", string userinformation="")
{
string URI = "http://localhost:49389/services";
string myParameters = "serviceAndVisitorModel=" + ServiceAndVisitroData;
using (WebClient wc = new WebClient())
{
wc.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
string HtmlResult = wc.UploadString(URI, myParameters);
}
//return some view here
}
Action Result Called by addToWishList present in same Controller
[Route("services")]
[HttpPost]
public ActionResult services(AllserviceWebApi serviceAndVisitorModel, string pagename = "service")//string selectedService,string userId,string DealInfo
{
//serviceAndVisitorModel is null here
}
Model
public class AllserviceWebApi
{
public string packageTypeID { get; set; }
public string packageTypeCode { get; set; }
public string pageUrl { get; set; }
public string pageName { get; set; }
public string displayName { get; set; }
public string name { get; set; }
public List<pakageInfoList> packageInfoList { get; set; }
//------visitor object
public string IPAddress { get; set; }
public string deviceName { get; set; }
public string OSName { get; set; }
public string browserName { get; set; }
public string countryName { get; set; }
public string selectedService{ get; set; }
public string userId{ get; set; }
public string OrderId { get; set; }
public string DealInfo { get; set; }
public long wishlishid { get; set; }
public string customlogoCode { get; set; }
public string customLogoImgSvg { get; set; }
public bool IsCustomllogo { get; set; }
}
Model Initializing
AllserviceWebApi ServiceAndVisitroData = new AllserviceWebApi()
{
selectedService = serviceids,
userId = "0",
OrderId = "0",
DealInfo = "",
IPAddress = ipaddress,
// deviceName: userDevicedata[0],
OSName = osandversion,
browserName = browsermajorversion,
wishlishid = wishid,
customlogoCode = logocode,
customLogoImgSvg = logosvg,
IsCustomllogo = true
};
Please tell me whats wrong with this code.
Try to send it via JSON
using Newtonsoft.Json;
using (WebClient wc = new WebClient())
{
wc.Headers[HttpRequestHeader.ContentType] = "application/json";
string HtmlResult = wc.UploadString(URI, JsonConvert.SerializeObject(ServiceAndVisitroData));
}
PS your need to install Newtonsoft.Json via nuget
I am consuming a REST API service. In the service response JSON, there are attribute names that include spaces and reserved words. I'm trying to map it to a C# class, but I can't assign attribute names that are the same as the field names.
Currently, the mapping only succeeds when the JSON attribute and C# class name of a field matches exactly, otherwise the value comes in as null.
Below is the JSON returned from the service:
{
"value": [ {
"accountNo": "JKBXXXXXXXXXVNX1",
"mainSalesPerson": "XXXXX",
"accountName": "XXXXXX",
"ledgerBalance": "-2,298.70",
"T+3": "0.00",
"T+4": "0.00",
"T+5 and Above": "2,298.70",
"riskRatedPortfolioValue": "109,057.50",
"exposure": "106,758.80",
"costToFirm": "",
"incomeToFirm": "14.59",
"costToIncome(%)": "",
"exposure(%)": "2.11",
"O/S Balance": "-2,298.70"
}],
"success": true
}
I have used the following mapping class:
public class CountObject
{
public string value { get; set; }
public string success { get; set; }
}
public class RiskManagementQueryValueObject
{
public string accountNo { get; set; }
public string mainSalesPerson { get; set; }
public string accountName { get; set; }
public string ledgerBalance { get; set; }
[SerializeAs(Name = "T+3")]
public string T3 { get; set; }
[SerializeAs(Name = "T+4")]
public string T4 { get; set; }
[SerializeAs(Name = "T+5 and Above")]
public string T5_and_Above { get; set; }
public string riskRatedPortfolioValue { get; set; }
public string exposure { get; set; }
public string costToFirm { get; set; }
public string incomeToFirm { get; set; }
[SerializeAs(Name = "costToIncome(%)")]
public string costToIncome { get; set; }
[SerializeAs(Name = "exposure(%)")]
public string exposure_per { get; set; }
[SerializeAs(Name = "O/S Balance")]
public string OS_Balance { get; set; }
}
public class RiskManagementQueryHeadertObject
{
public List<RiskManagementQueryValueObject> value { get; set; }
public bool success { get; set; }
}
And this how I talk to the service:
public List<RiskManagementQueryValueObject> getOverdues()
{
List<RiskManagementQueryValueObject> overdues = new List<RiskManagementQueryValueObject>();
var count = 0.0;
try
{
var restProxy = new RESTProxy();
var request = restProxy.initRestRequest("/cam/riskmanagement/1/query/count", Method.POST, new { requestCriteriaMap = new { currency = "LKR" } });
CountObject data = restProxy.Execute<CountObject>(request);
if (data.success.ToString().ToLower() != "true")
return null;
//get the page count
var pageCount = Math.Truncate(count / 300) + 1;
for (int j = 0; j < pageCount; j++)
{
var request2 = restProxy.initRestRequest(string.Format("/cam/riskmanagement/1/query/{0}", (j + 1).ToString()), Method.POST, new { requestCriteriaMap = new { currency = "LKR" } });
RiskManagementQueryHeadertObject data2 = restProxy.Execute<RiskManagementQueryHeadertObject>(request2);
overdues.AddRange(data2.value);
}
}
catch (Exception)
{
overdues = null;
}
return overdues;
}
public class RESTProxy
{
string DEFAULT_HOST = "http://xxx.xxx.xxx.xxx:xxx/";
string DEFAULT_MODULE = "xxx-rest";
string DEFAULT_USER = "xxx:xxx:xxx";
string DEFAULT_PASS = "xxx";
public T Execute<T>(RestRequest request) where T : new()
{
var client = new RestClient(string.Concat(DEFAULT_HOST, DEFAULT_MODULE))
{
Authenticator = new DigestAuthenticator(DEFAULT_USER, DEFAULT_PASS, DEFAULT_HOST)
};
var response = client.Execute<T>(request);
if (response.ErrorException != null)
{
throw response.ErrorException;
}
return response.Data;
}
public RestRequest initRestRequest(string pRestResourceName, Method pRestServiceVerb, object pRestRequestBody)
{
var request = new RestRequest(pRestResourceName, pRestServiceVerb);
request.RequestFormat = DataFormat.Json;
if (pRestRequestBody != null)
{
request.AddBody(pRestRequestBody);
}
return request;
}
}
How can I resolve this and serialize all the fields into my class definition?
Using the JsonProperty attribute worked for me:
Example:
This C# class:
public class Product
{
[JsonProperty(PropertyName = "Name/ + 1")]
public string Name { get; set; }
}
maps to the following javascript object:
var input = {"Name/ + 1": "PostName"};
I solved the issue. I added [DeserializeAs(Name ="")] instead of [SerializeAs(Name ="")]. I just did this in my C# Map class:
public class RiskManagementQueryValueObject
{
public string accountNo { get; set; }
public string mainSalesPerson { get; set; }
public string accountName { get; set; }
public string ledgerBalance { get; set; }
[DeserializeAs(Name = "T+3")]
public string T3 { get; set; }
[DeserializeAs(Name = "T+4")]
public string T4 { get; set; }
[DeserializeAs(Name = "T+5 and Above")]
public string T5_and_Above { get; set; }
public string riskRatedPortfolioValue { get; set; }
public string exposure { get; set; }
public string costToFirm { get; set; }
public string incomeToFirm { get; set; }
[DeserializeAs(Name = "costToIncome(%)")]
public string costToIncome { get; set; }
[DeserializeAs(Name = "exposure(%)")]
public string exposure_per { get; set; }
[DeserializeAs(Name = "O/S Balance")]
public string OS_Balance { get; set; }
}
public class News
{
public string author { get; set; }
public string title { get; set; }
public DateTime timestamp{ get; set; }
public string content { get; set; }
public bool forstudents { get; set; }
public List<link> links { get; set; }
public List<imgs> imgs { get; set; }
}
public class link
{
public string name { get; set; }
public string value { get; set; }
}
public class imgs
{
public string name { get; set; }
public string value { get; set; }
}
This is my Model Description then i connect to the Server
var _esServer = new ElasticSearchServer("http://localhost:9200");
var _esIndex = _esServer.GetIndex("campusoffice");
var news = _esIndex.Get<News>("/news", int.MaxValue);
and it should get everything right but
he doesnt map the name and the value in the list elements
{
"author": "soulseak",
"title": "Awsome",
"timestamp": 20130201,
"content": "Erster",
"forstudents": true,
"links": {
"myhome": "http://test.de"
},
"imgs": {
"myhome": "http://test.de"
}
}
the question is how to tell him what to put in name and value that myhome is in name and the url in value
You can do something like this:
public class User {
public User(string json) {
var jsonObject = Json.Decode(json);
MyName = (string)jsonObject.user.name;
MyTeamName = (string)jsonObject.user.teamname;
MyEmail = (string)jsonObject.user.email;
Players = (DynamicJsonArray) jsonObject.user.players;
}
public string MyName{ get; set; }
public string MyTeamName { get; set; }
public string MyEmail{ get; set; }
public Array Players { get; set; }
}
But would need to assign the values manually.
Example using your model (0 index based only, you would need to write a loop) but using a direct RestFul call:
var url = "http://localhost:9200/campusoffice/news";
var client = new WebClient();
var json = client.DownloadString(url);
var jsonObject = Json.Decode(json);
var links = (DynamicJsonArray) jsonObject.links;
var imgs = (DynamicJsonArray) jsonObject.imgs;
var news = new News
{ author = (string)jsonObject.author,
links = new List<link>() };
var aLink = new link { name = (string)links[0].myhome, value =
(string)imgs[0].myhome };
news.links.Add(aLink);
I typed this roughly without compiling/testing but should give you an idea.