How to convert camel case format my data? - asp.net-core

I am executiong sql queries from different data sources. And I am getting the results as dynamic objects like following.
private IEnumerable<IDictionary<string, object>> GetDataFromPostgresql()
{
var dataList = new List<IDictionary<string, object>>();
IDictionary<string, object> obj = new ExpandoObject();
obj.Add("first_name", "john");
obj.Add("last_name", "smith");
obj.Add("age", 25);
dataList.Add(new Dictionary<string, object>(obj));
return dataList;
}
private IEnumerable<IDictionary<string, object>> GetDataFromOracle()
{
var dataList = new List<IDictionary<string, object>>();
IDictionary<string, object> obj = new ExpandoObject();
obj.Add("FIRST_NAME", "john");
obj.Add("LAST_NAME", "smith");
obj.Add("AGE", 25);
dataList.Add(new Dictionary<string, object>(obj));
return dataList;
}
private IEnumerable<IDictionary<string, object>> GetDataFromMssql()
{
var dataList = new List<IDictionary<string, object>>();
IDictionary<string, object> obj = new ExpandoObject();
obj.Add("FirstName", "john");
obj.Add("LastName", "smith");
obj.Add("Age", 25);
dataList.Add(new Dictionary<string, object>(obj));
return dataList;
}
I am using these data collections in my asp.net core controller.
[HttpGet]
[Route("")]
public IActionResult Get()
{
var dataList = GetDataFromPostgresql();
return Ok(dataList);
}
But I want to serialize responses a standart camel case format.
{ "firstName": "john", "lastName": "smith", "age": 25 }
So how can I do this?

PascalCase means it has a capitalized first letter, but if this kind of outcome that you are after, { "firstName": "john", "lastName": "smith", "age": 25 }, that's called camelCase.
I am not familiar with nowadays asp.net-core, but I am sure the RegExp would be the same as this JavaScript one.
function toUpperCase(raw, letter) {
return letter.toUpperCase();
}
function asCamelCase(str) {
// put an underscore between camel cases
return str.replace(/([a-z])([A-Z])/g, '$1_$2')
// make the whole string lower case
.toLowerCase()
// capitalize every letter after the underscore
.replace(/_+([^_]|$)/g, toUpperCase);
}
Above example would produce (try by copying and pasting it in your browser console) always firstName, given the following inputs:
asCamelCase("FirstName"); // firstName
asCamelCase("FIRST_NAME"); // firstName
asCamelCase("first_name"); // firstName
I hope this helped 👋

Try to use below code to change the key in Dictionary to CamelCase
[HttpGet]
[Route("")]
public IActionResult Get()
{
var dataList = GetDataFromPostgresql();
var newDataList = new List<IDictionary<string, object>>();
foreach (var data in dataList)
{
var newData = new Dictionary<string, object>();
foreach (var key in data.Keys)
{
var newKey = "";
var value = data[key];
var index = key.IndexOf('_');
if(index < 0)//for GetDataFromMssql()
{
newKey = Char.ToLowerInvariant(key[0]) + key.Substring(1);
}else
{
newKey = key.ToLowerInvariant().Replace("_", string.Empty).Replace(" ", string.Empty);
newKey = newKey.Replace(newKey[index], Char.ToUpperInvariant(newKey[index]));
}
newData.Add(newKey, value);
}
newDataList.Add(newData);
}
return Ok(newDataList);
}
If you have complex value like "first_name_hello_test", you could use below workaround:
[HttpGet]
[Route("")]
public IActionResult Get()
{
var dataList = GetDataFromPostgresql();
var newDataList = new List<IDictionary<string, object>>();
foreach (var data in dataList)
{
var newData = new Dictionary<string, object>();
foreach (var key in data.Keys)
{
var newKey = "";
var value = data[key];
var indexList = new List<int>();
var index = key.IndexOf('_');
if (index < 0)
{
newKey = Char.ToLowerInvariant(key[0]) + key.Substring(1);
}else
{
while (index >= 0)
{
indexList.Add(index);
index = key.IndexOf('_', index + 1);
}
newKey = key.ToLowerInvariant();
foreach(var i in indexList)
{
newKey = newKey.Replace(newKey[i+1], Char.ToUpperInvariant(newKey[i+1]));
}
newKey = newKey.Replace("_", string.Empty).Replace(" ", string.Empty);
}
newData.Add(newKey, value);
}
newDataList.Add(newData);
}
return Ok(newDataList);
}

Related

Deleting one object from CartItems in razor pages

i have some products in my Cart via cookies, now i want to select and delete them from cart,
public class CartModel : PageModel
{
public List<CartItem> CartItems;
public const string CookieName = "cart-items";
public void OnGet()
{
var serializer = new JavaScriptSerializer();
var value = Request.Cookies[CookieName];
CartItems = serializer.Deserialize<List<CartItem>>(value); //error accurred in this line
foreach (var item in CartItems)
item.TotalItemPrice = item.UnitPrice * item.Count;
}
public IActionResult OnGetRemoveFromCart(long id)
{
var serializer = new JavaScriptSerializer();
var value = Request.Cookies[CookieName];
Response.Cookies.Delete(CookieName);
var cartItems = serializer.Deserialize<List<CartItem>>(value);
var itemToRemove = cartItems.FirstOrDefault(x => x.Id == id);
cartItems.Remove(itemToRemove);
var options = new CookieOptions { Expires = DateTime.Now.AddDays(2) };
Response.Cookies.Append(CookieName, serializer.Serialize(cartItems), options);
return RedirectToPage("/Cart");
}
until i don't click on the delete button, everything is ok, i don't have any error in OnGet on Cart Razor page. but when i click on the delete button and OnGetRemoveFromCart's handler is executed,CartItems is null on OnGet!
the errorr: 'Object reference not set to an instance of an object.CartItems was null.'
Response.Cookies.Delete(CookieName);
You delete the cookie in the OnGetRemoveFromCart handler, so value becomes null in the OnGet handler. You should always check for null before accessing cookie values:
public void OnGet()
{
var serializer = new JavaScriptSerializer();
var value = Request.Cookies[CookieName];
if(value is not null)
{
CartItems = serializer.Deserialize<List<CartItem>>(value);
foreach (var item in CartItems)
{
item.TotalItemPrice = item.UnitPrice * item.Count;
}
}
}

PDFbox how to enable all fields in pdf form

I have a PDFForm created in Livecycle Designer. I would like import it, fill up some fields and write also like a new pdf form with enabled field. At this moment I can just fill up the fields but after export there are disabled. I also get an information: you cannot use the extended faction of pdf... How to save file with this extended pdf functions.
FileInputStream in = new FileInputStream("form.pdf");
FileOutputStream out = new FileOutputStream("test.pdf");
PDDocument document = PDDocument.loadNonSeq(in,null);
document.setAllSecurityToBeRemoved(false);
Map<String, String> values = new HashMap<String, String>();
values.put("imiePracownika", "Grzegorz K.");
setFields(document, values);
PDAcroForm form = document.getDocumentCatalog().getAcroForm();
Document documentXML = form.getXFA().getDocument();
NodeList dataElements = documentXML.getElementsByTagName("xfa:data");
if (dataElements != null) {
for (int i = 0; i < dataElements.getLength(); i++) {
setXFAFields(dataElements.item(i), values);
}
}
RandomAccessBuffer r = new RandomAccessBuffer();
COSStream cosout = new COSStream(r);
TransformerFactory.newInstance().newTransformer().transform(new DOMSource(documentXML), new StreamResult(cosout.createUnfilteredStream()));
form.setXFA(new PDXFA(cosout));
document.save(out);
document.close();
private void setFields(PDField field, Map<String, String> values) throws IOException {
List<COSObjectable> kids = field.getKids();
if (kids != null) {
for (COSObjectable pdfObj : kids) {
if (pdfObj instanceof PDField) {
setFields((PDField) pdfObj, values);
}
}
} else {
// remove the [0] from the name to match values in our map
String partialName = field.getPartialName().replaceAll("\\[\\d\\]", "");
if (!(field instanceof PDSignatureField) && values.containsKey(partialName)) {
field.setValue(values.get(partialName));
}
}
}
public void setFields(PDDocument pdfDocument, Map<String, String> values) throws IOException {
#SuppressWarnings("unchecked")
List<PDField> fields = pdfDocument.getDocumentCatalog().getAcroForm().getFields();
for (PDField pdField : fields) {
setFields(pdField, values);
}
}
public void setXFAFields(Node pNode, Map<String, String> values) throws IOException {
if (values.containsKey(pNode.getNodeName())) {
pNode.setTextContent(values.get(pNode.getNodeName()));
} else {
NodeList childNodes = pNode.getChildNodes();
if (childNodes != null) {
for (int i = 0; i < childNodes.getLength(); i++) {
setXFAFields(childNodes.item(i), values);
}
}
}
}

Passing list of object to Web API using RestSharp Client

I'm trying to send list of objects from MVC to WEBAPI using below methods. API is able to able receive the list from controller but, value of each item in the list is either empty/null on API side.
Can anyone please help me to fix this?
Controller Method:
private List<FCM.Models.Facility> GetFacilityDetails()
{
var url = "http://localhost:64664/";
var facilies = new List<Facility>();
facilies.Add( new Facility{ FCLT_ID = 100, FCLT_NM = "Facility 100" });
facilies.Add( new Facility{ FCLT_ID = 200, FCLT_NM = "Facility 200" });
facilies.Add( new Facility{ FCLT_ID = 300, FCLT_NM = "Facility 300" });
var json = JsonConvert.SerializeObject(facilies);
var _client = new RestClient(url);
var request = new RestRequest("api/facility/details", Method.GET) { RequestFormat = DataFormat.Json };
facilies.ForEach(fclt =>
request.AddParameter("facilites", fclt, ParameterType.GetOrPost));
var response = _client.Execute<List<FCM.Models.Facility>>(request);
if (response.Data == null)
{
throw new Exception(response.ErrorMessage);
}
return response.Data;
}
WebAPI method:
[Route("api/facility/details")]
public IEnumerable<Facility> GetFullAddress([FromUri] IEnumerable<Facility> facilities)
{
return null;
}
Like the comment suggested you maybe want to issue a POST request instead, but if you would like to send an array with a GETrequest you could do it like this (with System.Net.Http.HttpClient):
Add a Format method to you Facility class:
public class Facility
{
public int FCLT_ID { get; set; }
public string FCLT_NM { get; set; }
public string Format(int index)
{
return $"[{index}].FCLT_ID={FCLT_ID}&[{index}].FCLT_NM={FCLT_NM}";
}
}
Define a class which can format the array values:
public class FacilityList : List<Facility>
{
public string Format()
{
var builder = new StringBuilder();
for (var i = 0; i < Count; i++)
{
builder.Append(this[i].Format(i));
if(i != Count -1)
{
builder.Append("&");
}
}
return builder.ToString();
}
}
And then issue the request:
var client = new HttpClient()
{
BaseAddress = new Uri("http://localhost:64664/"),
DefaultRequestHeaders = {Accept = {new MediaTypeWithQualityHeaderValue("application/json")}}
};
var facilities = new FacilityList
{
new Facility {FCLT_ID = 100, FCLT_NM = "Facility 100"},
new Facility {FCLT_ID = 200, FCLT_NM = "Facility 200"},
new Facility {FCLT_ID = 300, FCLT_NM = "Facility 300"}
};
var format = facilities.Format();
var response = client.GetAsync("api/facility/details?" + format).GetAwaiter().GetResult();
var result = JsonConvert.DeserializeObject<IEnumerable<Facility>>(response.Content.ReadAsStringAsync().GetAwaiter().GetResult());
This will bind to your controller action:
[Route("api/facility/details")]
public IHttpActionResult Get([FromUri] IEnumerable<Facility> facilities)
{
// Do stuff..
return Ok(facilities);
}

RavenDB: Can't retrieve individual Ranged Facets

I have some Ranged Facets defined in a FacetSetup document. I like having the ability to retrieve individual Facets from a FacetSetup (by specifying them instead of the Id of the FacetSetup in my call to ToFacets()), so I tried to do that with these Ranged Facets but have been unsuccessful so far.
Here is my failing test. Any tips?
using Raven.Abstractions.Data;
using Raven.Abstractions.Indexing;
using Raven.Client;
using Raven.Client.Embedded;
using Raven.Tests.Helpers;
using System.Collections.Generic;
using System.Linq;
using Xunit;
namespace RavenDBTests
{
public class RangedFacetTests : RavenTestBase
{
[Fact]
public void RangedFacetTest()
{
using (EmbeddableDocumentStore documentStore = NewDocumentStore())
{
// create and store an index
Dictionary<string, string> analyzers = new Dictionary<string, string>();
analyzers.Add("MyProperty", "");
Dictionary<string, SortOptions> sortOptions = new Dictionary<string, SortOptions>();
sortOptions.Add("MyProperty", SortOptions.Long);
IndexDefinition indexDefinition = new IndexDefinition()
{
Analyzers = analyzers,
SortOptions = sortOptions,
Map = #"from d in docs
select new
{
MyProperty = d.MyProperty
}",
};
documentStore.DatabaseCommands.PutIndex("MyIndex", indexDefinition);
using (IDocumentSession documentSession = documentStore.OpenSession())
{
// store some sample documents
documentSession.Store(new { MyProperty = 10 });
documentSession.Store(new { MyProperty = 25 });
documentSession.Store(new { MyProperty = 100 });
// store a facetsetup with one ranged facet
documentSession.Store(new FacetSetup
{
Id = "facets/MyFacetSetup",
Facets = new List<Facet>()
{
new Facet()
{
Mode = FacetMode.Ranges,
Name = "MyProperty_Range",
Ranges = new List<string>()
{
"[0x0000000000000001 TO 0x0000000000000032]"
}
}
}
}, "facets/MyFacetSetup");
documentSession.SaveChanges();
}
// let that process
WaitForIndexing(documentStore);
using (IDocumentSession documentSession = documentStore.OpenSession())
{
// retrieve ALL facets
FacetResults facetResults1 = documentSession.Query<dynamic>("MyIndex").ToFacets("facets/MyFacetSetup");
Xunit.Assert.True(facetResults1.Results.Values.First().Values.First().Hits > 0);
// retrieve SPECIFIED facets
FacetResults facetResults2 = documentSession.Query<dynamic>("MyIndex").ToFacets(new List<Facet>()
{
new Facet()
{
Mode = FacetMode.Ranges,
Name = "MyProperty_Range"
}
},
0,
null);
// this fails: why can't I specify the ranged facet?
Xunit.Assert.True(facetResults2.Results.Values.First().Values.First().Hits > 0);
}
}
}
}
}
You don't specify what the actual ranges are in the code.
In RavenDB, you have two ways to create facets. One is to specify the facet doc id, and the second is to actually pass the facets.
In this case, you are passing a range facets without any ranges, so it returns no results.
Use this code:
FacetResults facetResults2 = documentSession.Query<dynamic>("MyIndex").ToFacets(new List<Facet>()
{
new Facet()
{
Mode = FacetMode.Ranges,
Name = "MyProperty_Range",
Ranges = new List<string>()
{
"[0x0000000000000001 TO 0x0000000000000032]"
}
}
},
0,
null);

Worklight Security WorkLightAuthLoginModule

I'm using the WorkLightAuthenticator to validate User login.
But I need to return some parameters like userName, organozationID, among others. What would be the correct way to return this data?
I believe that would be the method createIdentity as exemple down. And to retrieve the data on the client?
/*Worklight Adapter*/
public class LoginModule implements WorkLightAuthLoginModule {
private String USERNAME;
private String PASSWORD;
public void init(Map<String, String> options) throws MissingConfigurationOptionException {
}
#SuppressWarnings("unchecked")
public boolean login(Map<String, Object> authenticationData) {
USERNAME = (String) authenticationData.get("username");
PASSWORD = (String) authenticationData.get("password");
InvocationResult invocationResult = callLoginAdapter(USERNAME, PASSWORD);
JSONObject jsonObject = invocationResult.toJSON();
HashMap<String, String> result = (HashMap<String, String>) jsonObject.get("result");
if(result != null){
return true;
} else {
HashMap<String, String> fault = (HashMap<String, String>) jsonObject.get("Fault");
String detail = fault.get("Detail");
throw new RuntimeException(detail);
}
}
public UserIdentity createIdentity(String loginModule) {
HashMap<String, Object> customAttributes = new HashMap<String, Object>();
customAttributes.put("AuthenticationDate", new Date());
customAttributes.put("userName", userExample);
customAttributes.put("organizationID", 1);
UserIdentity identity = new UserIdentity(loginModule, USERNAME, null, null, customAttributes, PASSWORD);
return identity;
}
public void logout() {
USERNAME = null;
PASSWORD = null;
}
public void abort() {
USERNAME = null;
PASSWORD = null;
}
#Override
public LoginModule clone() throws CloneNotSupportedException {
return (LoginModule) super.clone();
}
public InvocationResult callLoginAdapter(String user, String password){
DataAccessService service = WorklightBundles.getInstance().getDataAccessService();
String parameters = "['"+user+"','"+password+"']";
ProcedureQName procedureQName = new ProcedureQName("LoginAdapter", "getUserByLogin");
return service.invokeProcedure(procedureQName, parameters);
}
}
And AuthenticatorRealmChallengeHandler in client-side
/*AuthenticatorRealmChallengeHandler.js*/
var customAuthenticatorRealmChallengeHandler = WL.Client.createChallengeHandler("AuthenticatorRealm");
customAuthenticatorRealmChallengeHandler.isCustomResponse = function(response) {
console.log("**********************");
console.log(response.responseJSON);
if (!response || !response.responseJSON) {
return false;
}
if (response.responseJSON.authStatus)
return true;
else
return false;
};
customAuthenticatorRealmChallengeHandler.handleChallenge = function(response){
var authStatus = response.responseJSON.authStatus;
if (authStatus == "required"){
if (response.responseJSON.errorMessage){
currentPage.loginFail(response.responseJSON.errorMessage);
}
} else if (authStatus == "complete"){
currentPage.loadMaster();
customAuthenticatorRealmChallengeHandler.submitSuccess();
}
};
customAuthenticatorRealmChallengeHandler.submitLoginFormCallback = function(response) {
var isLoginFormResponse = customAuthenticatorRealmChallengeHandler.isCustomResponse(response);
if (isLoginFormResponse){
customAuthenticatorRealmChallengeHandler.handleChallenge(response);
}
};
$('#loginButton').bind('click', function () {
var reqURL = '/auth_request_url';
var options = {};
options.parameters = {
username : $('#userTextField').val(),
password : $('#passwordTextField').val()
};
options.headers = {};
customAuthenticatorRealmChallengeHandler.submitLoginForm(reqURL, options, customAuthenticatorRealmChallengeHandler.submitLoginFormCallback);
});
var attributes = WL.Client.getUserInfo("AuthenticatorRealm", "attributes");