Error "CUSTOM_ATTRIBUTE_DUPLICATE_NAME" when posting custom attribute definition - autodesk-forge

I'm trying to add a custom attribute to a BIM360 folder, using instructions here:
https://forge.autodesk.com/en/docs/bim360/v1/reference/http/document-management-custom-attribute-definitions-POST/
public async Task<long> addFolderCustomAttribute(string projectId, string folderId, string attributeName, string type)
{
var localVarPath = $"bim360/docs/v1/projects/{projectId.Replace("b.", "")}/folders/{System.Web.HttpUtility.UrlEncode(folderId)}/custom-attribute-definitions";
var localVarQueryParams = new Dictionary<String, String>();
Object localVarPostBody = null;
var localVarHeaderParams = new Dictionary<String, String>(Configuration.Default.DefaultHeader);
var localVarFormParams = new Dictionary<String, String>();
var localVarFileParams = new Dictionary<String, FileParameter>();
var localVarPathParams = new Dictionary<String, String>();
String[] localVarHttpContentTypes = new String[] {
"application/vnd.api+json"
};
String localVarHttpContentType = Configuration.Default.ApiClient.SelectHeaderContentType(localVarHttpContentTypes);
if (!String.IsNullOrEmpty(Configuration.Default.AccessToken))
{
localVarHeaderParams["Authorization"] = "Bearer " + Configuration.Default.AccessToken;
}
localVarPostBody = "{\"name\":\"" + attributeName + "\", \"type\":\"" + type + "\"}";
IRestResponse localVarResponse = (IRestResponse)await Configuration.Default.ApiClient.CallApiAsync(localVarPath,
Method.POST, localVarQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarFileParams,
localVarPathParams, localVarHttpContentType);
int localVarStatusCode = (int)localVarResponse.StatusCode;
var response = new ApiResponse</*JsonApiCollection*/dynamic>(localVarStatusCode,
localVarResponse.Headers.ToDictionary(x => x.Name, x => x.Value.ToString()),
/*(JsonApiCollection)*/ Configuration.Default.ApiClient.Deserialize(localVarResponse, typeof(JsonApiCollection)));
var id = (long)((Autodesk.Forge.Model.DynamicJsonResponse)response.Data).Dictionary["id"];
return id;
}
And I receive this error: CUSTOM_ATTRIBUTE_DUPLICATE_NAME
however when I enumerate the folder's custom attributes using:
https://forge.autodesk.com/en/docs/bim360/v1/reference/http/document-management-custom-attribute-definitions-GET/
public async Task<Dictionary<long, Tuple<string, string>>> getFolderCustomAttributeDefinition(string projectId, string folderId)
{
var localVarPath = $"bim360/docs/v1/projects/{projectId.Replace("b.", "")}/folders/{System.Web.HttpUtility.UrlEncode(folderId)}/custom-attribute-definitions";
var localVarQueryParams = new Dictionary<String, String>();
Object localVarPostBody = null;
var localVarHeaderParams = new Dictionary<String, String>(Configuration.Default.DefaultHeader);
var localVarFormParams = new Dictionary<String, String>();
var localVarFileParams = new Dictionary<String, FileParameter>();
var localVarPathParams = new Dictionary<String, String>();
String[] localVarHttpContentTypes = new String[] {
"application/vnd.api+json"
};
String localVarHttpContentType = Configuration.Default.ApiClient.SelectHeaderContentType(localVarHttpContentTypes);
if (!String.IsNullOrEmpty(Configuration.Default.AccessToken))
{
localVarHeaderParams["Authorization"] = "Bearer " + Configuration.Default.AccessToken;
}
IRestResponse localVarResponse = (IRestResponse) await Configuration.Default.ApiClient.CallApiAsync(localVarPath,
Method.GET, localVarQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarFileParams,
localVarPathParams, localVarHttpContentType);
int localVarStatusCode = (int)localVarResponse.StatusCode;
var response = new ApiResponse</*JsonApiCollection*/dynamic>(localVarStatusCode,
localVarResponse.Headers.ToDictionary(x => x.Name, x => x.Value.ToString()),
/*(JsonApiCollection)*/ Configuration.Default.ApiClient.Deserialize(localVarResponse, typeof(JsonApiCollection)));
var sret = ((Autodesk.Forge.Model.DynamicJsonResponse)response.Data).Dictionary["results"];
var resultsDic = ((Autodesk.Forge.Model.DynamicDictionary)sret).Dictionary;
Dictionary<long, Tuple<string, string>> ret = new Dictionary<long, Tuple<string, string>>();
foreach (var att in resultsDic) {
var attrDic = (Autodesk.Forge.Model.DynamicDictionary)att.Value;
ret.Add((long)attrDic.Dictionary["id"], new Tuple<string, string>((string)attrDic.Dictionary["name"], (string)attrDic.Dictionary["type"]));
}
return ret;
}
It does not show any attribute with that name.
Any ideas?

Related

How to split pdf file by book marks using itext 7 , if pdf contains "Duplicate Bookmarks"

I am trying to split pdf by its bookmarks using itext7.
Problem : if Pdf is having same bookmark in other place in the outline tree , it is over ridding and unable to split.
Sample code to reproduce the problem:
public void walkOutlines(PdfOutline outline, Map<String, PdfObject> names, PdfDocument pdfDocument,List<String>titles,List<Integer>pageNum) { //----------loop traversing all paths
for (PdfOutline child : outline.getAllChildren()){
if(child.getDestination() != null) {
prepareIndexFile(child,names,pdfDocument,titles,pageNum,list);
}
}
}
//------------Getting pageNumbers from outlines
public void prepareIndexFile(PdfOutline outline, Map<String, PdfObject> names, PdfDocument pdfDocument,List<String>titles,List<Integer>pageNum) {
String title = outline.getTitle();
PdfDestination pdfDestination = outline.getDestination();
String pdfStr = ((PdfString)pdfDestination.getPdfObject()).toUnicodeString();
PdfArray array = (PdfArray) names.get(pdfStr);
PdfObject pdfObj = array != null ? array.get(0) : null;
Integer pageNumber = pdfDocument.getPageNumber((PdfDictionary)pdfObj);
titles.add(title);
pageNum.add(pageNumber);
if(outline.getAllChildren().size() > 0) {
for (PdfOutline child : outline.getAllChildren()){
prepareIndexFile(child,names,pdfDocument,titles,pageNum);
}
}
}
public boolean splitPdf(String inputFile, final String outputFolder) {
boolean splitSuccess = true;
PdfDocument pdfDoc = null;
try {
PdfReader pdfReaderNew = new PdfReader(inputFile);
pdfDoc = new PdfDocument(pdfReaderNew);
final List<String> titles = new ArrayList<String>();
List<Integer> pageNum = new ArrayList<Integer>();
PdfNameTree destsTree = pdfDoc.getCatalog().getNameTree(PdfName.Dests);
Map<String, PdfObject> names = destsTree.getNames();//--------------------------------------Core logic for getting names
PdfOutline root = pdfDoc.getOutlines(false);//--------------------------------------Core logic for getting outlines
walkOutlines(root,names, pdfDoc, titles, pageNum,content); //------Logic to get bookmarks and pageNumbers
if (titles == null || titles.size()==0) {
splitSuccess = false;
}else { //------Proceed if it has bookmarks
for(int i=0;i<titles.size();i++) {
String title = titles.get(i);
String startPageNmStr =""+pageNum.get(i);
int startPage = Integer.parseInt(startPageNmStr);
int endPage = startPage;
if(i == titles.size() - 1) {
endPage = pdfDoc.getNumberOfPages();
}else {
int nextPage = pageNum.get(i+1);
if(nextPage > startPage) {
endPage = nextPage - 1;
}else {
endPage = nextPage;
}
}
String outFileName = outputFolder + File.separator + getFileName(title) + ".pdf";
PdfWriter pdfWriter = new PdfWriter(outFileName);
PdfDocument newDocument = new PdfDocument(pdfWriter, new DocumentProperties().setEventCountingMetaInfo(null));
pdfDoc.copyPagesTo(startPage, endPage, newDocument);
newDocument.close();
pdfWriter.close();
}
}
}catch(Exception e){
//---log
}
}
Found root cause: In PdfNameTree items.put(name.toUnicodeString(), names.get(k));
How to over come this issue?
Thanks in advance
This part of the code:
PdfDestination pdfDestination = outline.getDestination();
String pdfStr = ((PdfString)pdfDestination.getPdfObject()).toUnicodeString();
PdfArray array = (PdfArray) names.get(pdfStr);
PdfObject pdfObj = array != null ? array.get(0) : null;
Integer pageNumber = pdfDocument.getPageNumber((PdfDictionary)pdfObj);
Does not take into account the case that the destination can be non-named and refer to a page explicitly.
So the code needs to be adapted into the following code:
PdfDestination pdfDestination = outline.getDestination();
PdfObject pdfObj = null;
if (pdfDestination.getPdfObject().isString()) {
String pdfStr = ((PdfString) pdfDestination.getPdfObject()).toUnicodeString();
PdfArray array = (PdfArray) names.get(pdfStr);
if (array != null) {
pdfObj = array.get(0);
}
} else if (pdfDestination.getPdfObject().isArray() && ((PdfArray)pdfDestination.getPdfObject()).get(0).isDictionary()) {
pdfObj = ((PdfArray)pdfDestination.getPdfObject()).get(0);
}
Integer pageNumber = pdfDocument.getPageNumber((PdfDictionary)pdfObj);
Additionally, if you want to obtain the full title names including the parent chain, you need to replace String title = outline.getTitle(); with the following piece of code:
String title = outline.getTitle();
PdfOutline parentChain = outline.getParent();
while (parentChain != null) {
title = parentChain.getTitle() + "." + title;
parentChain = parentChain.getParent();
}
As a result, I got 6 files in the output directory, with 5 files of 1 page each and one file of 4 pages.
Complete code:
public void walkOutlines(PdfOutline outline, Map<String, PdfObject> names, PdfDocument pdfDocument,
java.util.List<String>titles,java.util.List<Integer>pageNum) { //----------loop traversing all paths
for (PdfOutline child : outline.getAllChildren()){
if(child.getDestination() != null) {
prepareIndexFile(child,names,pdfDocument,titles,pageNum);
}
}
}
//------------Getting pageNumbers from outlines
public void prepareIndexFile(PdfOutline outline, Map<String, PdfObject> names, PdfDocument pdfDocument,
java.util.List<String>titles,java.util.List<Integer>pageNum) {
String title = outline.getTitle();
PdfOutline parentChain = outline.getParent();
while (parentChain != null) {
title = parentChain.getTitle() + "." + title;
parentChain = parentChain.getParent();
}
PdfDestination pdfDestination = outline.getDestination();
PdfObject pdfObj = null;
if (pdfDestination.getPdfObject().isString()) {
String pdfStr = ((PdfString) pdfDestination.getPdfObject()).toUnicodeString();
PdfArray array = (PdfArray) names.get(pdfStr);
if (array != null) {
pdfObj = array.get(0);
}
} else if (pdfDestination.getPdfObject().isArray() && ((PdfArray)pdfDestination.getPdfObject()).get(0).isDictionary()) {
pdfObj = ((PdfArray)pdfDestination.getPdfObject()).get(0);
}
Integer pageNumber = pdfDocument.getPageNumber((PdfDictionary)pdfObj);
titles.add(title);
pageNum.add(pageNumber);
if(outline.getAllChildren().size() > 0) {
for (PdfOutline child : outline.getAllChildren()){
prepareIndexFile(child,names,pdfDocument,titles,pageNum);
}
}
}
public void splitPdf(String inputFile, final String outputFolder) {
boolean splitSuccess = true;
PdfDocument pdfDoc = null;
try {
PdfReader pdfReaderNew = new PdfReader(inputFile);
pdfDoc = new PdfDocument(pdfReaderNew);
final java.util.List<String> titles = new ArrayList<String>();
java.util.List<Integer> pageNum = new ArrayList<Integer>();
PdfNameTree destsTree = pdfDoc.getCatalog().getNameTree(PdfName.Dests);
Map<String, PdfObject> names = destsTree.getNames();//--------------------------------------Core logic for getting names
PdfOutline root = pdfDoc.getOutlines(false);//--------------------------------------Core logic for getting outlines
walkOutlines(root,names, pdfDoc, titles, pageNum); //------Logic to get bookmarks and pageNumbers
if (titles == null || titles.size()==0) {
splitSuccess = false;
}else { //------Proceed if it has bookmarks
for(int i=0;i<titles.size();i++) {
String title = titles.get(i);
String startPageNmStr =""+pageNum.get(i);
int startPage = Integer.parseInt(startPageNmStr);
int endPage = startPage;
if(i == titles.size() - 1) {
endPage = pdfDoc.getNumberOfPages();
}else {
int nextPage = pageNum.get(i+1);
if(nextPage > startPage) {
endPage = nextPage - 1;
}else {
endPage = nextPage;
}
}
String outFileName = outputFolder + File.separator + title + ".pdf";
PdfWriter pdfWriter = new PdfWriter(outFileName);
PdfDocument newDocument = new PdfDocument(pdfWriter, new DocumentProperties().setEventCountingMetaInfo(null));
pdfDoc.copyPagesTo(startPage, endPage, newDocument);
newDocument.close();
pdfWriter.close();
}
}
}catch(IOException e){
System.out.println(e);
}
}

Correct JSON structure using RestSharp

What is the Correct format for sending JSON using RestSharp:
Example PUT JSON:
{
"properties": [
{
"name": "description",
"value": "A far better description than before"
}
]
}
In C# how to correctly send, I'm attempting with:
request.AddJsonBody(new
{
properties = new[]
{
new{property="name",value="about_us"},
new{property="value",value="My description"}
}
});
Below is the full code:
private void UpdateCompanyProperty(string companyId)
{
var hapikey = "{YOUR_HAPI_KEY_HERE}";
var client = new RestClient("https://api.hubapi.com/");
var request = new RestRequest("companies/v2/companies/{companyId}", Method.PUT);
request.AddUrlSegment("companyId", companyId);
request.AddQueryParameter("hapikey", hapikey);
request.RequestFormat = DataFormat.Json;
request.AddJsonBody(new
{
properties = new[]
{
new{property="name",value="about_us"},
new{property="value",value="My description"}
}
});
IRestResponse response = client.Execute(request);
JObject jObject = JObject.Parse(response.Content);
JToken jvid = jObject["portalId"];
Debug.WriteLine(jvid);
}
No errors but not updating or returning values.
Try my answer here:
https://stackoverflow.com/a/57281157/5478655
request.RequestFormat = DataFormat.Json; // Important
var input = new Dictionary<string, object>();
// props could be an array or real objects too of course
var props = new[]
{
new{property="name",value="about_us"},
new{property="value",value="My description"}
};
input.Add("properties", props);
request.AddBody(input);
Create a class and give it any name
class MyClass
{
public string property {get;set;}
private string value {get;set;}
}
Define your class as an object
List<MyClass> list = new List<MyClass>
{
new MyClass() { property = "name", value = "about_us"},
new MyClass() { property = "value", value = "My Description"},
};
Now using Newtonsoft.Json serialize your object
string result = JsonConvert.SerializeObject(list);
Now add it to an array
var resArray = new object[] { result };
Find your modified code below
class MyClass
{
public string property {get;set;}
private string value {get;set;}
}
using Newtonsoft.Json;
using RestSharp;
private void UpdateCompanyProperty(string companyId)
{
List<MyClass> list = new List<MyClass>
{
new MyClass() { property = "name", value = "about_us"},
new MyClass() { property = "value", value = "My Description"},
};
string result = JsonConvert.SerializeObject(list);
var hapikey = "{YOUR_HAPI_KEY_HERE}";
var client = new RestClient("https://api.hubapi.com/");
var request = new RestRequest("companies/v2/companies/{companyId}", Method.PUT);
request.AddUrlSegment("companyId", companyId);
request.AddQueryParameter("hapikey", hapikey);
request.RequestFormat = DataFormat.Json;
request.AddJsonBody(new
{
properties =result
});
IRestResponse response = client.Execute(request);
JObject jObject = JObject.Parse(response.Content);
JToken jvid = jObject["portalId"];
Debug.WriteLine(jvid);
}

CsvHelper wrap all values with quotes

I am using CsvHelper I need to wrap all values with quotes.
Is that possible?
Data = is a List
using (StreamWriter textWriter = new StreamWriter(path))
{
textWriter.BaseStream.Write(p, 0, p.Length);
// var dt = new DataTable();
var csv = new CsvWriter(textWriter);
csv.WriteRecords(Data);
textWriter.Flush();
textWriter.Close();
}
Thanks
There is a config value called ShouldQuote where you can determine on a field level if it should be quoted.
void Main()
{
var records = new List<Foo>
{
new Foo { Id = 1, Name = "one" },
new Foo { Id = 2, Name = "two" },
};
using (var writer = new StringWriter())
using (var csv = new CsvWriter(writer))
{
csv.Configuration.ShouldQuote = (field, context) => true;
csv.WriteRecords(records);
writer.ToString().Dump();
}
}
public class Foo
{
public int Id { get; set; }
public string Name { get; set; }
}
Output:
"Id","Name"
"1","one"
"2","two"
From version 25.0.0 up to the date, the way of doing it is:
var config = new CsvConfiguration(CultureInfo.InvariantCulture)
{
ShouldQuote = args => true
};
Just need to add a configuration object. like this
CsvHelper.Configuration.CsvConfiguration config = new CsvHelper.Configuration.CsvConfiguration();
config.QuoteAllFields = true;
var csv = new CsvWriter(textWriter, config);

Common class for HttpWebRequests - WP8

For making the http calls I use the functions
private void DoneClicked(object sender, RoutedEventArgs e)
{
string emailText = emailTBox.Text;
string oldPass = oldPasswordPBox.Password;
string newPass = newPasswordPBox.Password;
if (emailText == "" || oldPass == "" || newPass == "")
{
PassDiaTB1.Text = "Oops..";
PassDiaTB2.Text = "Some field is empty";
PassiveDialogs.Visibility = System.Windows.Visibility.Visible;
}
else
{
var data = new { user = new { email = emailText, old_password = oldPass, new_password = newPass } };
jsonStringChild = JsonConvert.SerializeObject(data, Formatting.Indented);
Debug.WriteLine(jsonStringChild);
string uri = CycleManager.HTTP_URI + "change-password";
var request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = CycleManager.HTTP_PUT;
request.ContentType = "application/json";
request.Accept = "application/json";
bool IsNetWork = System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable();
if (!IsNetWork)
{
PassDiaTB1.Text = "Oops..";
PassDiaTB2.Text = "Check your internet connectivity";
PassiveDialogs.Visibility = System.Windows.Visibility.Visible;
}
else
{
request.BeginGetRequestStream(new AsyncCallback(PostCallBack), request);
}
}
}
void PostCallBack(IAsyncResult result)
{
// End the stream request operation
HttpWebRequest request = result.AsyncState as HttpWebRequest;
Stream postStream = request.EndGetRequestStream(result);
byte[] byteArray = Encoding.UTF8.GetBytes(jsonStringChild);
postStream.Write(byteArray, 0, byteArray.Length);
postStream.Close();
request.BeginGetResponse(new AsyncCallback(GetResponseStreamCallBack), request);
}
void GetResponseStreamCallBack(IAsyncResult callBackResult)
{
try
{
HttpWebRequest request = callBackResult.AsyncState as HttpWebRequest;
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(callBackResult);
statusCode = (int)response.StatusCode;
if (statusCode == 200)
{
string result = "";
using (StreamReader httpWebStreamReader = new StreamReader(response.GetResponseStream()))
{
result = httpWebStreamReader.ReadToEnd();
}
string json = result;
Dictionary<string, string> token = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
string email = token["email"];
string auth_token = token["auth_token"];
CycleManager cycMan = CycleManager.Instance;
cycMan.AuthToken = auth_token;
Dispatcher.BeginInvoke(ShowPassiveDialog);
}
}
catch (WebException e)
{
if (e.Response != null)
{
HttpWebResponse aResp = e.Response as HttpWebResponse;
if (aResp != null)
{
statusCode = (int)aResp.StatusCode;
}
if (statusCode == 401)
{
string result = "";
using (StreamReader httpWebStreamReader = new StreamReader(aResp.GetResponseStream()))
{
result = httpWebStreamReader.ReadToEnd();
}
string json = result;
var definition = new { message = "" };
var parsedStrings = JsonConvert.DeserializeAnonymousType(json, definition);
message = parsedStrings.message;
Dispatcher.BeginInvoke(ShowPassiveDialog);
}
if (statusCode == 500)
{
string result = "";
using (StreamReader httpWebStreamReader = new StreamReader(aResp.GetResponseStream()))
{
result = httpWebStreamReader.ReadToEnd();
}
string json = result;
var definition = new { message = "" };
var parsedStrings = JsonConvert.DeserializeAnonymousType(json, definition);
message = parsedStrings.message;
Dispatcher.BeginInvoke(ShowPassiveDialog);
}
}
}
}
The same three calls are made in several pages, changing the parameters and methods. I am trying to create a common class which can be called to make http calls. But these functions have differnt return types and I'm not able generalize all this??
Any help would be appreciated.
May this will guide you. I create a wrapper class for such kind of work, its help me a lot and reduce lots of code and effort.
public class CommanHttpRequest
{
private string ACCEPT="application/json";
private string ContentType ="application/json";
private string POST_METHOD="POST";
private string GET_METHOD="GET";
public string IsException { get; set; }
public HttpWebRequest GetHttpRequest(string url,string header1, string header2)
{
HttpWebRequest getRequest = HttpWebRequest.CreateHttp(url);
getRequest.Accept =this.ACCEPT;
getRequest.ContentType = this.ACCEPT;
getRequest.Headers["Header1"] = header1;
getRequest.Headers["Header2"] = header2;
getRequest.Method = this.POST_METHOD;
return getRequest ;
}
public void GetRequestResponse(Action<your type> callback, IAsyncResult asyncResult, string envelop)
{
try
{
UTF8Encoding encoding = new UTF8Encoding();
HttpWebRequest request = (HttpWebRequest)asyncResult.AsyncState;
Stream body = request.EndGetRequestStream(asyncResult);
//write body if any
byte[] formBytes = encoding.GetBytes(envelop);
body.Write(formBytes, 0, formBytes.Length);
body.Close();
request.BeginGetResponse(result =>
{
try
{
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(result);
using (Stream data = response.GetResponseStream())
{
using (var reader = new StreamReader(data))
{
string jsonString = reader.ReadToEnd();
MemoryStream memoryStream = new MemoryStream(Encoding.Unicode.GetBytes(jsonString));
DataContractJsonSerializer dataContractJsonSerializer = new DataContractJsonSerializer(typeof(your type));
var parseddata = dataContractJsonSerializer.ReadObject(memoryStream) as your type;
callback(parseddata );
}
}
}
catch (WebException ex)
{
IsException = ex.Message;
//I asume your type =List<abc>();
callback(new List<abc>());
}
}, request);
}
catch (Exception ex)
{
IsException = ex.Message;
callback(new List<abc>());
}
}
}
public class abc
{
public void TestRequest()
{
string url="some url";
CommanHttpRequest requestObj = new CommanHttpRequest();
HttpWebRequest testRequest = _requestObj.GetHttpRequest(url, password, email);
//if there some body in request
string envelope = "{\"requestType\":" + requestType + "}";
testRequest .BeginGetRequestStream(result =>
{
requestObj.GetRequestResponse(resultData =>
{
ProcessServiceResponse(resultData);
}, result, envelope);
}, testRequest );
}
public void ProcessServiceResponse(List<abc> abcdata)
{
//abcdata is your data
}
}

How to map poco to JSON using Automapper

In my MVC 2 application I have a typical method that calls a web service, builds a JSON data object and returns it to the view.
Everything works fine, but I was wondering if there is a way to do the mapping with Automapper so I can remove the ugly code from my controller. Thanks in advance
Here is my Action method
public virtual ActionResult AllErrors(string sidx, string sord,
int page=1, int rows=10)
{
var pageSize = rows;
var pageNumber = page;
var orderBy = string.Format("{0} {1}", sidx, sord);
var result = errorService.GetPagedOpenErrors(pageSize, page, orderBy);
var errors = new List<IngestionErrorDataContract>(result.IngestionErrors);
var totalPages = (int) Math.Ceiling(result.TotalRows/(float) pageSize);
int index = 0;
var list = new List<object>();
errors.ForEach(e => list.Add(
new {
i = index++,
cell = new[]
{
e.IngestionErrorId.ToString(),
e.RunId.ToString(),
e.ProcessDate.ToShortDateString(),
e.Status,
e.ErrorDetails
}
}));
var jsonData = new
{
total = totalPages,
page = pageNumber,
records = result.TotalRows,
rows = list.ToArray()
};
return Json(jsonData, JsonRequestBehavior.AllowGet);
}
I solved it using the ConstructUsing method of AutoMapper.
Here is my map
public void CreateMap()
{
Mapper.CreateMap<List<IngestionErrorDataContract>, object[]>()
.ConvertUsing(
errors =>
{
int index = 0;
var list = new List<object>();
errors.ForEach(e => list.Add(
new
{
i = index++,
cell = new[]
{
e.IngestionErrorId.ToString(),
e.RunId.ToString(),
e.ProcessDate.ToShortDateString(),
e.Status,
e.ErrorDetails
}
}));
return list.ToArray();
});
}
and here is my action method now
public virtual ActionResult AllErrors(string sidx, string sord, int page=1, int rows=10)
{
var pageSize = rows;
var pageNumber = page;
var orderBy = string.Format("{0} {1}", sidx, sord);
var result = errorService.GetPagedOpenErrors(pageSize, page, orderBy);
var errors = new List<IngestionErrorDataContract>(result.IngestionErrors);
var totalPages = (int) Math.Ceiling(result.TotalRows/(float) pageSize);
var jsonData = new
{
total = totalPages,
page = pageNumber,
records = result.TotalRows,
rows = mapper.Map<List<IngestionErrorDataContract>,object[]>(errors)
};
return Json(jsonData, JsonRequestBehavior.AllowGet);
}
Much better I think