While i build the Project, It have a error like this:
Server Error in '/' Application.
The model item passed into the dictionary is of type
'System.Data.DataTable', but this dictionary requires a model item of
type 'System.Collections.Generic.IList`1[TLayout.Models.DemoTable]'.
This is my Controller
public ActionResult Index()
{
var dm = new DemoTable();
string connstring = "Server=localhost;Port=5432;User Id=postgres;Password=123456;Database=test";
NpgsqlConnection conn = new NpgsqlConnection(connstring);
conn.Open();
string sql = "select * from demo";
NpgsqlDataAdapter da = new NpgsqlDataAdapter(sql, conn);
ds.Reset();
da.Fill(ds);
dt = ds.Tables[0];
var demoid = dm.demoid.ToString();
var demoname = dm.demoname;
for (int i = 0; i < dt.Rows.Count; i++)
{
List<DataTable> dtb = new List<DataTable>();
demoid = dt.Rows[i]["demoid"].ToString();
demoname = dt.Rows[i]["demoname"].ToString();
dtb.Add(dt);
}
return View(dt);
}
This is my View, to show data to layout:
foreach (var item in Model)
{
fields.Add(Html.X().ModelField().Mapping(#item.demoid.ToString()).Name("grid-alarm"));
fields.Add(Html.X().ModelField().Mapping(#item.demoname.ToString()).Name("grid-check"));
}
var list = dt.AsEnumerable()
.Where(row => (int)row["demoid"] > 5)
.Select(row => new
{
demoid = Convert.ToInt32(row["demoid"]),
demoname = row["demoname"] != null ?
row["demoname"].ToString() :
String.Empty
}).ToList();
Or you can define class:
public class myClass
{
public int demoid;
public string demoname;
}
and then:
List<myClass> list = dt.AsEnumerable()
.Where(row => (int)row["demoid"] > 5)
.Select(row => new myClass
{
demoid = Convert.ToInt32(row["demoid"]),
demoname = row["demoname"] != null ?
row["demoname"].ToString() :
String.Empty
}).ToList<myClass>();
Related
I'm looking to add records to an Umbraco v8 form. I know I need the form guid. Is this how I'd do it? Something like this?
public void PostFormData()
{
Guid FormGuid = new Guid("8494a8f0-94da-490e-bd61-7e658c226142");
var form = _formService.Get(FormGuid);
//place for field data into fieldDic
var fieldDic = new Dictionary<Guid, RecordField>();
var firstName = form.AllFields.First(f => f.Alias == "firstName");
var firstNameRecord = new RecordField(firstName);
firstNameRecord.Values = new List<object>() { "Mad Max" };
fieldDic.Add(firstName.Id, firstNameRecord);
var record = new Record()
{
Created = DateTime.Now,
Form = form.Id,
RecordFields = fieldDic,
State = FormState.Submitted,
};
record.RecordData = record.GenerateRecordDataAsJson();
_recordStorage.InsertRecord(record, form);
}
Here's how I do it. Note, I'm hard-coding the Record.UmbracoPageId to -1 while you might want to actually pass in the correct page ID.
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using Umbraco.Core;
using Umbraco.Core.Composing;
using Umbraco.Core.Logging;
using Umbraco.Forms.Core.Data.Storage;
using Umbraco.Forms.Core.Models;
using Umbraco.Forms.Core.Persistence.Dtos;
using Umbraco.Forms.Core.Services;
namespace myProject.Services
{
public class FormServiceComposer : IUserComposer
{
public void Compose(Composition composition)
{
composition.Register<IFormService, FormService>(Lifetime.Request);
}
}
public interface IFormService
{
void InsertFormData(Guid formGuid, object formModel, string ipAddress);
}
public class FormService : IFormService
{
private readonly ILogger _logger;
private readonly Umbraco.Forms.Core.Services.IFormService _formService;
private readonly IRecordStorage _recordStorage;
private readonly IRecordFieldStorage _recordFieldStorage;
private readonly IWorkflowService _workflowService;
public FormService(ILogger logger, Umbraco.Forms.Core.Services.IFormService formService, IRecordStorage recordStorage, IRecordFieldStorage recordFieldStorage, IWorkflowService workflowService)
{
_logger = logger;
_formService = formService;
_recordStorage = recordStorage;
_recordFieldStorage = recordFieldStorage;
_workflowService = workflowService;
}
#region IFormService
public void InsertFormData(Guid formGuid, object formModel, string ipAddress)
{
try
{
Form form = _formService.GetForm(formGuid);
Record record = new Record();
foreach (Field field in form.AllFields)
{
string caption = CleanCaption(field.Caption);
if (formModel.GetType().GetProperty(caption) == null) continue;
var propertyValue = formModel.GetType().GetProperty(caption).GetValue(formModel, null);
if (propertyValue != null)
{
List<object> values = ExtractValues(propertyValue);
RecordField recordField = new RecordField
{
Alias = field.Alias,
FieldId = field.Id,
Field = field,
Key = Guid.NewGuid(),
Record = record.Id,
Values = values
};
_recordFieldStorage.InsertRecordField(recordField);
record.RecordFields.Add(recordField.Key, recordField);
}
}
record.Form = formGuid;
record.IP = ipAddress;
record.UmbracoPageId = -1;
record.State = Umbraco.Forms.Core.Enums.FormState.Approved;
record.RecordData = record.GenerateRecordDataAsJson();
_recordStorage.InsertRecord(record, form);
_recordStorage.DisposeIfDisposable();
}
catch (Exception ex)
{
_logger.Error<FormService>(ex, "Failed inserting Umbraco Forms data for {formGuid}");
}
}
#endregion IFormService
#region Private
private string CleanCaption(string caption)
{
Regex rgx = new Regex("[^a-zA-Z0-9 -]");
return rgx.Replace(caption.Trim().Replace(" ", ""), "");
}
private List<object> ExtractValues(object propertyValue)
{
List<object> result = new List<object>();
if (propertyValue is string == false && propertyValue.GetType().GetGenericTypeDefinition() == typeof(List<>))
{
IEnumerable<object> _propertyValue = (IEnumerable<object>)propertyValue;
if (_propertyValue.Any())
{
if (_propertyValue.First().GetType().GetProperties().Count() > 1)
{
JArray _properties = JArray.Parse(JsonConvert.SerializeObject(propertyValue));
foreach (JToken item in _properties)
{
string _value = string.Empty;
foreach (var _property in _propertyValue.First().GetType().GetProperties())
{
string _key = _property.Name;
_value = _value + (_value == "" ? "" : " - ") + item[_key].ToString();
}
result.Add(_value);
}
}
else
{
string _key = _propertyValue.First().GetType().GetProperties().First().Name;
JArray _properties = JArray.Parse(JsonConvert.SerializeObject(propertyValue));
foreach (JToken item in _properties)
{
result.Add(item[_key].ToString());
}
}
}
}
else
{
result.Add(propertyValue);
}
return result;
}
#endregion Private
}
}
Here's my old code.
public override Task ExecuteAsync(string generator, WebHookHandlerContext context)
{
DatawarehouseEntities db = new DatawarehouseEntities();
// Get JSON from WebHook
JObject data = context.GetDataOrDefault<JObject>();
var tableName = data["Table_Name"].ToString();
var columnNames = db.Database.SqlQuery<string>(String.Format("SELECT name FROM sys.columns WHERE object_id = OBJECT_ID('{0}'); ", tableName)).ToList();
var table = db.GetType().GetProperty(tableName).GetValue(db, null);
var assembly = AppDomain.CurrentDomain.GetAssemblies()
.SingleOrDefault(a => a.GetName().Name == "DSI.Data");
var type = assembly.GetTypes().FirstOrDefault(t => t.Name == tableName);
var dbset = Activator.CreateInstance(type);
//var dbset = db.Set(type);
var jsonParams = data.Properties().Select(x => x.Name).ToList();
var selectedColumnNames = columnNames.Intersect(jsonParams);
foreach (var columnName in selectedColumnNames)
{
var property = dbset.GetType().GetProperties().FirstOrDefault(x => x.Name == columnName);
property.SetValue(dbset, data[columnName].ToString(), null);
}
db.Set(type).Add(dbset);
db.SaveChanges();
return Task.FromResult(true);
}
Here's what I try to post http://localhost:port/api/webhooks/incoming/genericjson?code=secret&Table_Name=Table_Name. The type always comes back null. How can I select a table using the string that I pass in?
To make this easier, faster and less error-prone enumerate your entity types and add them to a lookup. EG
public static Dictionary<string, Type> EntityTypesByName { get; } = new Dictionary<string, Type>();
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
foreach (var et in modelBuilder.Model.GetEntityTypes())
{
EntityTypesByName.Add(et.Name, et.ClrType);
}
}
This is what finally worked for me.
public override Task ExecuteAsync(string generator, WebHookHandlerContext context)
{
DatawarehouseEntities db = new DatawarehouseEntities();
// Get JSON from WebHook
JObject data = context.GetDataOrDefault<JObject>();
var tableName = data["Table_Name"].ToString();
var columnNames = db.Database.SqlQuery<string>(String.Format("SELECT name FROM sys.columns WHERE object_id = OBJECT_ID('{0}'); ", tableName)).ToList();
var table = db.GetType().GetProperty(tableName).GetValue(db, null);
var assembly = AppDomain.CurrentDomain.GetAssemblies()
.SingleOrDefault(a => a.GetName().Name == "DSI.Data");
var type = assembly.GetTypes().FirstOrDefault(t => t.Name == tableName);
var dbset = Activator.CreateInstance(type);
var jsonParams = data.Properties().Select(x => x.Name).ToList();
var selectedColumnNames = columnNames.Intersect(jsonParams);
foreach (var columnName in selectedColumnNames)
{
var property = dbset.GetType().GetProperties().FirstOrDefault(x => x.Name == columnName);
property.SetValue(dbset, data[columnName].ToString(), null);
}
db.Set(type).Add(dbset);
db.SaveChanges();
return Task.FromResult(true);
}
Hi Im using kendo ui grid in my project.
This is my code to insert records in database.
public static void Insert(StudentViewModel student)
{
student.StudentId = All().OrderByDescending(p => p.StudentId).First().StudentId + 1;
//All().Insert(0, student);
UniRegEntities uniRegEntities = new UniRegEntities();
Student stu =new Student();
stu.FName = student.FirstName;
stu.LName = student.LastName;
stu.Gender = uniRegEntities.Genders.Where(x => x.Title == student.Gender).FirstOrDefault();
stu.Id = student.StudentId;
uniRegEntities.Students.Add(stu);
uniRegEntities.SaveChanges();
}
And this is my update statement.
public static void Update(StudentViewModel student)
{
UniRegEntities context = new UniRegEntities();
var studentToUpdate = context.Students.Where(x => x.Id == student.StudentId).FirstOrDefault();
studentToUpdate.FName = student.FirstName;
studentToUpdate.LName = student.LastName;
studentToUpdate.Gender = context.Genders.Where(x => x.Title == student.Gender).FirstOrDefault();
context.SaveChanges();
}
Anyone can suggest me the delete method?
You can either get an entity from the DB and then delete it or create one and then delete it.
So:
var e = // Get
ctx.DeleteObject(e);
ctx.SaveChanges();
or
var e = new Foo() { FooId = id };
ctx.Entity.Attach(e);
ctx.DeleteObject(e);
ctx.SaveChanges();
Applied to your situation:
You are getting a record so you want to use DeleteObject()
public static void Update(StudentViewModel student)
{
UniRegEntities context = new UniRegEntities();
var studentToDelete = context.Students.Where(x => x.Id == student.StudentId).FirstOrDefault();
context.Students.DeleteObject(studentToUpdate);
context.SaveChanges();
}
context.Students.Remove(context.students.Single(x=>x.Id==student.Id));
Can you please try with below code snippet?
using (var db= new AppContext(ConnectionStr))
{
try
{
con.Configuration.AutoDetectChangesEnabled = false;
var o = new Student { StudentId = student.StudentId };
db.Students.Attach(o);
db.Students.Remove(o);
db.SaveChanges();
}
catch (Exception ex)
{
throw new Exception(ex.InnerException.Message);
}
finally
{
con.Configuration.AutoDetectChangesEnabled = true;
}
}
I have one view that used to display the result of my search item. This is its controller :
[HttpPost]
public ActionResult EvaluatingReport(FormCollection frm)
{
string empType = frm["empType"].ToString();
int totalMonth = 3;
int mon = DateTime.Now.Month;
int yr = DateTime.Now.Year;
string Curdate = mon + "/" + yr;
DateTime date = new DateTime();
var result = (from e in context.tblEmployees
join p in context.tblEmployee_Position on e.PositionIDF equals p.PositionID
select new EvaluateEmployee
{
ID = e.Code,
IDCard = e.IDCard,
Name = e.NameEng,
DOB = e.DOB,
Position = p.Position,
Sex = e.Sex,
StartDate = e.StartDate
}).ToList();
result = result.Where(((s => mon - int.Parse(s.StartDate.Substring(3, 2).ToString()) == totalMonth && yr -int.Parse(s.StartDate.Substring(6, 4).ToString()) == totalYear))).ToList();
ViewData["EmployeeType"] = result;
return View();
}
I displayed the content in the view by looping ViewData["EmployeeType"] and I also included one Print label :
<script language="javascript" type="text/javascript">
function printChart() {
var URL = "EvaluatingReport";
var W = window.open(URL);
W.window.print();
}
function printPage(sURL) {
var oHiddFrame = document.createElement("iframe");
oHiddFrame.src = sURL;
oHiddFrame.style.visibility = "hidden";
oHiddFrame.style.position = "fixed";
oHiddFrame.style.right = "0";
oHiddFrame.style.bottom = "0";
document.body.appendChild(oHiddFrame);
oHiddFrame.contentWindow.onload = oHiddFrame.contentWindow.print;
oHiddFrame.contentWindow.onafterprint = function () {
document.body.removeChild(oHiddFrame); };
}
</script>
<span onclick="printPage('/Report/PrintEvaluatingReport');" style="cursor:pointer;text-decoration:none;color:#0000ff;">
<img src="../../Content/images/Print.png" width="35px;" alt="print" style="position:relative;top:6px;"/>
Print Report
</span>
I used function printPage('/Report/PrintEvaluatingReport') to load the print dialog with the action PrintEvaluatingReport. So I want to take the object that I have in EvaluatingReport to the action PrintEvaluatingReport.
Could anyone tell me how could I do that?
Thanks in advanced.
You could use TempData["EmployeeType"]
[HttpPost]
public ActionResult EvaluatingReport(FormCollection frm)
{
string empType = frm["empType"].ToString();
int totalMonth = 3;
int mon = DateTime.Now.Month;
int yr = DateTime.Now.Year;
string Curdate = mon + "/" + yr;
DateTime date = new DateTime();
var result = (from e in context.tblEmployees
join p in context.tblEmployee_Position on e.PositionIDF equals p.PositionID
select new EvaluateEmployee
{
ID = e.Code,
IDCard = e.IDCard,
Name = e.NameEng,
DOB = e.DOB,
Position = p.Position,
Sex = e.Sex,
StartDate = e.StartDate
}).ToList();
result = result.Where(((s => mon - int.Parse(s.StartDate.Substring(3, 2).ToString()) == totalMonth && yr -int.Parse(s.StartDate.Substring(6, 4).ToString()) == totalYear))).ToList();
ViewData["EmployeeType"] = result;
// Store in TempData to be read by PrintEvaluatingReport
TempData["EmployeeType"] = result;
return View();
}
public ActionResult PrintEvaluatingReport()
{
var employeeType = TempData["EmployeeType"] as EmployeeType;
// do stuff
return View();
}
You can use a session variable for that !!
private EmployeeType Result
{
get { return (EmployeeType)this.Session["Result"]; }
set
{
this.Session["Result"] = value;
}
}
[HttpPost]
public ActionResult EvaluatingReport(FormCollection frm)
{
.
.
.
// Store in Session
this.Result = result;
return View();
}
public ActionResult PrintEvaluatingReport()
{
var employeeType = this.Result;
.
.
.
}
In an ASP.NET MVC3 application, if I wanted to model bind my form post data to an ExpandoObject (or my own object derived from DynamicObject where I implement my own Try... members) would I need to write my own custom model binder?
If I do:
public ActionResult Save(ExpandoObject form)
{
....
}
The value of form is null.
Or if I have:
public class MyDynamicThing : DynamicObject
{
public int Id { get; set; }
public override bool TrySetMember(SetMemberBinder binder, object value)
{
// Set breakpoint here but doesn't get hit when model binding
return base.TrySetMember(binder, value);
}
}
...and in my controller:
public ActionResult Save(MyDynamicThing form)
{
....
}
In the above example Id is set to the value from the form. However if I set a breakpoint in TrySetMember this doesn't get hit.
Are there any magical incantations I can invoke to coerce the built-in model binder to work with ExpandoObjects or my own classes derived from DynamicObject?
I could resort to picking up the raw form post collection but I have to serialise this data to JSON which would mean an extra and untidy step to harvest those values.
No, this is not possible with the built-in model binder. You could of course write a custom model binder. The only property that the built-in model binder is capable of binding is the one that it seems from the MyDynamicThing type and that's why it can only set the Id property. It has no knowledge of other properties.
Try this:
public class ExpandoObjectBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
if (bindingContext == null)
throw new ArgumentNullException("bindingContext");
IDictionary<string, object> model = new ExpandoObject();
string modelName = bindingContext.ModelName;
var form = controllerContext.HttpContext.Request.Unvalidated.Form;
var keys = form.AllKeys.Where(k => k.StartsWith(modelName + "."));
Debug.Write("ExpandoObjectBinder keys count is " + keys.Count());
foreach (var key in keys)
{
var propName = key.Replace(model + ".", "");
model.Add(propName, form[key]);
}
if (model.Count == 0)
throw new Exception("Data is empty.");
return model;
}
}
Register the binder mvc initialization :
ModelBinders.Binders.Add(typeof(ExpandoObject), new ExpandoObjectBinder());
Type support added (int, byte, long, decimal, string, array and subobjects):
public class ExpandoObjectBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
if (bindingContext == null)
throw new ArgumentNullException("bindingContext");
string modelName = bindingContext.ModelName;
var form = controllerContext.HttpContext.Request.Unvalidated.Form;
var model = ParseProperties(modelName, form);
return model;
}
public object ParseProperties(string modelName, NameValueCollection form)
{
var keys = form.AllKeys.Where(k => k.StartsWith(modelName + "."));
Debug.WriteLine("ExpandoObjectBinder keys count is " + keys.Count() + " for " + modelName);
IDictionary<string, object> model = new ExpandoObject();
List<string> subModelNames = new List<string>();
List<string> arrModelNames = new List<string>();
//ModelName: Dialog.Attributes[0].Options
foreach (var key in keys)
{
//Dialog.Attributes[0].Options.Byte
//Dialog.Attributes[0].Options.Inner.Byte
//Dialog.Attributes[0].Options.Inner.Integer
//Dialog.Attributes[0].Options.SimpleArray[0]
//Dialog.Attributes[0].Options.SimpleArray[1]
var propName = key.Replace(modelName + ".", "");
//Byte
//Inner.Byte
//Inner.Integer
//SimpleArray[0]
//SimpleArray[1]
if (!(propName.Contains('[') || propName.Contains('.')))
{
model.Add(propName, GetValue(form, key));
}
//array (can allow sub objects)
if (propName.Contains('['))
{
var names = propName.Split('[');
var arrModelName = names[0];
if (!arrModelNames.Contains(arrModelName))
arrModelNames.Add(arrModelName);
}
//not array but can has sub objects
if (!propName.Contains('[') && propName.Contains('.'))
{
var names = propName.Split('.');
var subModelName = names[0];
if (!subModelNames.Contains(subModelName))
subModelNames.Add(subModelName);
}
}
foreach (var subModelName in subModelNames)
{
var key = modelName + "." + subModelName;
object val = form[key];
val = ParseProperties(key, form);
model.Add(subModelName, val);
}
foreach (var arrModelName in arrModelNames)
{
//Dialog.Attributes[0].Options.SimpleArray[
var key = modelName + "." + arrModelName + "[";
var arrKeys = form.AllKeys.Where(k => k.StartsWith(key));
var isComplexArray = false;
int length = 0;
foreach (var arrKey in arrKeys)
{
var aKey = arrKey.Replace(key, "");
if (aKey.Contains("."))
isComplexArray = true;
var parsed = aKey.Split(']');
var num = int.Parse(parsed[0]);
if (num > length)
length = num;
}
List<object> vals = new List<object>();
if (isComplexArray)
{
for (int i = 0; i < length + 1; i++)
{
var arrKey = key + i + "]";
object val = ParseProperties(arrKey, form);
vals.Add(val);
}
}
else
{
for (int i = 0; i < length + 1; i++)
{
var arrKey = key + i + "]";
vals.Add(GetValue(form, arrKey));
}
}
model.Add(arrModelName, vals);
}
return model;
}
object GetValue(NameValueCollection form, string key)
{
object val = form[key];
if (decimal.TryParse(form[key], out decimal decimalVal))
val = decimalVal;
if (long.TryParse(form[key], out long longVal))
val = longVal;
if (int.TryParse(form[key], out int intVal))
val = intVal;
if (byte.TryParse(form[key], out byte byteVal))
val = byteVal;
if (bool.TryParse(form[key], out bool boolVal))
val = boolVal;
return val;
}
}