I am working on ASP.NET MVC4.0.
My string is posting like this from view :-
[{"name":"AddressNumber","value":"1"},{"name":"OrganizationProd","value":""},{"name":"ClientId","value":""},{"name":"ProductId","value":""},{"name":"TaxId1","value":""},{"name":"TaxId2","value":""},{"name":"LaborID","value":"0"}]
And below is my controller's action method for that,which is receiving the input :-
[AllowAnonymous]
[HttpPost]
public ActionResult UpdateProducts(string ModelString){
}
And below is the string which i am getting in action(in ModelString variable):-
[{"name":"AddressNumber","value":"1"},{"name":"OrganizationProd","value":""},{"name":"ClientId","value":""},{"name":"ProductId","value":""},{"name":"TaxId1","value":""},{"name":"TaxId2","value":""},{"name":"LaborID","value":"0"}]
And after that i am deserializing the string like that :-
var sear = new JavaScriptSerializer();
var dictDynamic = sear.Deserialize<dynamic>(ModelString);
And i am getting the dynamic array in dictDynamic variable.And now i want to get the properties by its name not by indexing from dictDynamic object.
Currently i am getting the properties by indexing like this :-
dictDynamic[0]["value"]
dictDynamic[1]["value"]
But i want to parse it by properties name like this :-
dictDynamic["Name"]["value"]
dictDynamic["Description"]["value"]
Can anyone help me out on this ?
You could use ViewModel on server side, not sending model string.
You create ViewModel like this:
class ProductViewModel {
public int AddressNumber { get; set; }
public int ProductId { get; set; }
...
}
Then change your controller method:
[AllowAnonymous]
[HttpPost]
public ActionResult UpdateProducts(ProductViewModel vm){
...
}
And from your View you'll send json object like this:
{
"AddressNumber":"10",
"OrganizationProd":"1",
"ClientId":"1",
"ProductId":"1",
"TaxId1":"23",
"TaxId2":"23",
"LaborID":"10"
}
This will automaticaly bind your values from View to ViewModel on controller, and you can than use ViewModel object in your code, and you then have strongly typed entity.
Instead of this:
dictDynamic["AddressNumber"]
dictDynamic["OrganizationProd"]
now you can write this:
vm.AddressNumber
vm.OrganizationProd
You need to pass a JavaScript object to your function instead of an array. Array is not the correct data structure to use in this case. Objects have keys and values. The keys will be AddressNumber, OrganizationProd, ClientId, ProductId, TaxId1 etc. Their values will be 1, "", "0" etc.
For instance, for your example, this will be your object:
{
"AddressNumber":1,
"OrganizationProd":"",
"ClientId":"",
"ProductId":"",
"TaxId1":"",
"TaxId2":"",
"LaborID":0
}
You deserialize it like you do now:
var s = "{\"AddressNumber\":1, \"OrganizationProd\":\"\", \"ClientId\":\"\", \"ProductId\":\"\", \"TaxId1\":\"\", \"TaxId2\":\"\", \"LaborID\":0}";
var sear = new JavaScriptSerializer();
var dictDynamic = sear.Deserialize<dynamic>(s);
Once you deserialize, you will be able to reference the values like this:
dictDynamic["AddressNumber"]
dictDynamic["OrganizationProd"]
Related
Below is my code for entity and a function where I need to map entity TblEmployee from a key value pair.
In foreach loop I am getting values based on keys, what should be the best approach to do it?
public class TblEmployee
{
public int EmployeeId { get; set; }
public string Name { get; set; }
}
public int Create()
{
tblEmployee employee = new tblEmployee();
using (var ctx = new theparkeee_testEntities())
{
foreach (string key in HttpContext.Current.Request.Form.AllKeys)
{
string value = HttpContext.Current.Request.Form[key];
//how to map value from key value pair to entity employee.
}
}
}
You can use System.Reflection to get the Properties of an object by their name with Type.GetProperty(string name). After you got the PropertyInfo, you can use SetValue to assign a value to it.
foreach (string key in HttpContext.Current.Request.Form.AllKeys) {
// note that "value" is a reserved word, do not use it as variable name
string val = HttpContext.Current.Request.Form[key];
var propertyInfo = typeof(TblEmployee).GetProperty(key); // can maybe be moved outside of the loop
if (propertyInfo != null) {
propertyInfo.SetValue(employee, val);
}
}
This will work for string properties. If the property is of another type, you have to find the correct type (again, using reflection) and cast the string value before assigning it.
Note that this is not the correct approach to store data in MVC. You should not work with the Request.Form directly, instead your POST action should accept a ViewModel that can be mapped (e.g. using Automapper) to the DB entity. I.e. let the ASP ModelBinder do its work, instead of reinventing the wheel!
[HttpPost]
public ActionResult Submit(MyViewModel postData) {
var employee = Mapper.Map<TblEmployee>(postData);
_ctx.Employees.Add(employee);
_ctx.SaveChanges();
return new HttpStatusCodeResult((int)HttpStatusCode.OK);
}
This has baffled me for a while now and I cannot seem to get the grasp of it. I'm using Cell Value Factory to populate a simple one column table and it does not populate in the table.
It does and I click the rows that are populated but I do not see any values in them- in this case String values. [I just edited this to make it clearer]
I have a different project under which it works under the same kind of data model. What am I doing wrong?
Here's the code. The commented code at the end seems to work though. I've checked to see if the usual mistakes- creating a new column instance or a new tableview instance, are there. Nothing. Please help!
//Simple Data Model
Stock.java
public class Stock {
private SimpleStringProperty stockTicker;
public Stock(String stockTicker) {
this.stockTicker = new SimpleStringProperty(stockTicker);
}
public String getstockTicker() {
return stockTicker.get();
}
public void setstockTicker(String stockticker) {
stockTicker.set(stockticker);
}
}
//Controller class
MainGuiController.java
private ObservableList<Stock> data;
#FXML
private TableView<Stock> stockTableView;// = new TableView<>(data);
#FXML
private TableColumn<Stock, String> tickerCol;
private void setTickersToCol() {
try {
Statement stmt = conn.createStatement();//conn is defined and works
ResultSet rsltset = stmt.executeQuery("SELECT ticker FROM tickerlist order by ticker");
data = FXCollections.observableArrayList();
Stock stockInstance;
while (rsltset.next()) {
stockInstance = new Stock(rsltset.getString(1).toUpperCase());
data.add(stockInstance);
}
} catch (SQLException ex) {
Logger.getLogger(WriteToFile.class.getName()).log(Level.SEVERE, null, ex);
System.out.println("Connection Failed! Check output console");
}
tickerCol.setCellValueFactory(new PropertyValueFactory<Stock,String>("stockTicker"));
stockTableView.setItems(data);
}
/*THIS, ON THE OTHER HAND, WORKS*/
/*Callback<CellDataFeatures<Stock, String>, ObservableValue<String>> cellDataFeat =
new Callback<CellDataFeatures<Stock, String>, ObservableValue<String>>() {
#Override
public ObservableValue<String> call(CellDataFeatures<Stock, String> p) {
return new SimpleStringProperty(p.getValue().getstockTicker());
}
};*/
Suggested solution (use a Lambda, not a PropertyValueFactory)
Instead of:
aColumn.setCellValueFactory(new PropertyValueFactory<Appointment,LocalDate>("date"));
Write:
aColumn.setCellValueFactory(cellData -> cellData.getValue().dateProperty());
For more information, see this answer:
Java: setCellValuefactory; Lambda vs. PropertyValueFactory; advantages/disadvantages
Solution using PropertyValueFactory
The lambda solution outlined above is preferred, but if you wish to use PropertyValueFactory, this alternate solution provides information on that.
How to Fix It
The case of your getter and setter methods are wrong.
getstockTicker should be getStockTicker
setstockTicker should be setStockTicker
Some Background Information
Your PropertyValueFactory remains the same with:
new PropertyValueFactory<Stock,String>("stockTicker")
The naming convention will seem more obvious when you also add a property accessor to your Stock class:
public class Stock {
private SimpleStringProperty stockTicker;
public Stock(String stockTicker) {
this.stockTicker = new SimpleStringProperty(stockTicker);
}
public String getStockTicker() {
return stockTicker.get();
}
public void setStockTicker(String stockticker) {
stockTicker.set(stockticker);
}
public StringProperty stockTickerProperty() {
return stockTicker;
}
}
The PropertyValueFactory uses reflection to find the relevant accessors (these should be public). First, it will try to use the stockTickerProperty accessor and, if that is not present fall back to getters and setters. Providing a property accessor is recommended as then you will automatically enable your table to observe the property in the underlying model, dynamically updating its data as the underlying model changes.
put the Getter and Setter method in you data class for all the elements.
I am scratching my head here. I have a bootstrap modal that has a field for entering in a sql query. The query I pass uses an AJAX call to a controller and executes the sql query using the code below and returns a JSON object. Something like this:
context.Database.SqlQuery(typeof(object), query);
But all I get are empty objects. I can't pass a type when I don't know the columns. For instance I could do something like this:
public class CusType {
public CusType(){}
public int Id { get; set; }
public string Name { get; set; }
}
and then do something like this:
context.Database.SqlQuery(typeof(CusType), query);
But that won't help me when I don't know or can't know the columns. I even tried an idea using ExpandoObjects. Example:
List<string> columns = new List<string>();
string tmpCol = query;
string[] seperator = new string[] { "from" };
tmpCol = query.ToLower()
.Replace(#"\s+", "")
.Replace("select", "");
tmpCol = tmpCol.Split(seperator, 1, StringSplitOptions.RemoveEmptyEntries)[0];
for (int i = 0; i < tmpCol.Split(',').Length; i++)
{
columns.Add(tmpCol.Split(',')[i]);
}
dynamic data = new ExpandoObject();
IDictionary<string, object> props = (IDictionary<string, object>)data;
foreach (var column in columns)
{
props.Add(column.ToString(), column.ToString());
}
return context.Database.SqlQuery(data.GetType(), query);
But what do I do when I want to execute the query?
context.Database.SqlQuery(data.GetType()??, query);
Even when I do put in the data.GetType() it returns empty objects.
In both examples (using typeof(object) and typeof(data.GetType()) I get this JSON object returned:
[{},{},{},{},{},{},{},{},{},{},{},{},{}]
Any ideas/suggestions?
Entity Framework populates a model based on the type specified. You'll need to use something else or go old school with a DataReader.
For example, I will send an object Fruits to server side.
The code like this:
public static <T> T call(String url, String ns, String method, Fruits fruits, Class<T> clz) throws AxisFault
{
RPCServiceClient client = new RPCServiceClient();
Options option = client.getOptions();
EndpointReference erf = new EndpointReference(url);
option.setTo(erf);
QName name = new QName(ns, method);
Object[] object = new Object[]{fruits};
Class[] returnTypes = new Class[]{clz};
Object[] reto = client.invokeBlocking(name, object, returnTypes);
T t = (T)reto[0];
return t;
}
The object like this:
public class Fruits implements Serializable
{
private int pear;
private int banana;
private int apple;
public int setPear(int pear){this.pear=pear;}
public int getPear(){return this.pear;}
...
}
The xml part should be this:
...
<fruits>
<pear>10</pear>
<banana>20</banana>
<apple>60</apple>
</fruits>
...
But in fact like this:
...
<fruits>
<apple>60</apple>
<banana>20</banana>
<pear>10</pear>
</fruits>
...
Axis2 makes object's property alphabetical order, but the server doesn't accept. I can't modify the serverside, it is ESB.
The only way to do a success request is to use the Axis2 generated code, I used to use WSDL2Java, but too many redundant code and difficult to maintain. So I want refactor.
I have also tried to use CXF, but it also makes object's property alphabetical order, not followed with WSDL/XSD or DTO defined style.
I've find the reason why CXF makes the ordering, it uses java.beans.BeanInfo to get properties of object, such as:
...
BeanInfo beanInfo = Introspector.getBeanInfo(Fruits.class);
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
...
The property in the array has already alphabetical order.
Who knows how to let Axis2 to serialize the Fruits' property to be correct ordering.
Thank you, the first!
Not sure on Axis2, but if you are using CXF with the JAXB databinding, you can add an annotation like:
#XmlType(name = "fruits", propOrder = { "apple", "banana", "pear" }})
to the Fruits class to tell JAXB what order you need/want them output.
I was trying to parse this using System.Json but I'm a bit confused how to use LINQ on this. The JSON string returned was something like:
{"SearchResults":[{"PageCount":"1"},
{"SEARCHVAL":"Result","CATEGORY":"Category1","X":"1","Y":"2"},
{"SEARCHVAL":"AnotherResult","CATEGORY":"Category1","X":"2","Y":"2"}]}
My code starts out as:
WebClient client = new WebClient();
client.OpenReadCompleted +=
new OpenReadCompletedEventHandler(client_OpenReadCompleted);
client.OpenReadAsync(uri);
then proceeds to the event handler where the result is stored in a Stream. Any example how to get just the SEARCHVALs, CATEGORYs, Xs and Ys from the stream using LINQ?
The DataContractJSonSerializer is one way to do it but the presence of the "PageCount" object makes its use awkard. It looks to me as though someone has goofed on the server end, it would make much more sense to have the page count a property of the outer object and therefore leave the search results array to contain an homogeneous set of objects.
The System.Json namespace is handy for this sort of JSON since its very flexible.
JsonObject searchResults = (JsonObject)JsonValue.Load(e.Result);
Now you could use some Linq to get a set of objects out of this but first so we need to create a DTO type for it:-
public class SearchResult
{
public string SearchValue {get; set;}
public string Category {get; set;}
public string X {get; set;}
public string Y {get; set;}
}
So now the results query is:-
var resultList = ((JsonArray)searchResults["SearchResults"])
.OfType<JsonObject>()
.Where(o => o.ContainsKey("SEARCHVAL"))
.Select(o => new SearchResult() {
SearchValue = o["SEARCHVALUE"],
Category = o["CATEGORY"].
X = o["X"],
Y = o["Y"]
}).ToList();
The resultList is List<SearchResult> which you can now bind into some Xaml for display.