XAML loading error using contentProperty - wpf

I am reading up more on XAML and I have created an XML file and want to load it. It all works but when I use the ContentProperty attribute and more importantly I remove the Company.Employees tags from the XML file, I get the error "cannot add to Company" when loading the xml file.
The code is :
<?xml version="1.0" encoding="utf-8" ?>
<Company Name="BBC" xmlns="clr-namespace:XamlLoading;assembly=XamlLoading">
<Company.Owner>
<Person Name="John" Age="49"/>
</Company.Owner>
<!--<Company.Employees>
<Person Name="Dave" Age="66" />
<Person Name="Paul" Age="45"/>
</Company.Employees>-->
<Person Name="Dave" Age="66" />
<Person Name="Paul" Age="45"/>
</Company>
[ContentProperty("Employees")]
public class Company
{
public Company()
{
Employees = new List<Person>();
}
public Person Owner { get; set; }
public string Name { get; set; }
public List<Person> Employees { get; set; }
}
static void Main(string[] args)
{
using (FileStream fs = File.OpenRead(#"..\..\company.xml"))
{
Company c = (Company)XamlReader.Load(fs); * ERROR HERE
Console.WriteLine(c.Name);
Console.WriteLine(c.Owner);
foreach (var item in c.Employees)
{
Console.WriteLine("{0} : ", item);
}
Console.ReadLine();
}
}

I would suggest that you update to the latest version of .NET. Your code works great for me.
This is a very interesting case study for XAML. I have never seen it used this way before. Typically XAML is used like HTML markup for declaratively defining a user interface. Blend is a WYSIWYG editor for creating user interfaces by generating XAML.
You have demonstrated some interesting potential for realizing data from xml using the XamlReader.

Related

Getting most basic MetaDataType to work

In addition to my original post I guess I need to mention that I am using Prism 6.3. Apparently, the compiler doesn't like stuff added to the metadata class that's not in the original partial. Not sure how to resolve this.
Thanks again ... Ed
Ok, I give, UNCLE!
I am trying to add data annotations to my wpf entity framework app. I've tried 6 ways to Sunday with no luck. I put together what is what I consider the most simple example possible and followed all the instructions ... nothing works.
Here goes.
I have a class that is generated by EF (db first).
namespace junk.DataModels
{
public partial class MyClass
{
public string SomeText { get; set; }
}
}
I have another file with the following partial class:
namespace junk.DataModels
{
[MetadataType(typeof(MyClassMetaData))]
public partial class MyClass
{
}
public partial class MyClassMetaData
{
private string _someText;
[Required(ErrorMessage = "Required")]
public string SomeText
{
get { return _someText; }
set { SetProperty(ref _someText, value); }
}
}
}
In my ViewModel I define:
private MyClass _mc;
public MyClass MC
{
get { return _mc; }
set
{
SetProperty(ref _mc, value);
}
}
And in the constructor:
MC = new MC();
MC.SomeText = "Hello World.";
Lastly, in my xaml:
I have a single bound control:
<TextBox x:Name="txt" Text="{Binding MC.SomeText,
ValidatesOnDataErrors=True,
ValidatesOnExceptions=True,
ValidatesOnNotifyDataErrors=True,
UpdateSourceTrigger=PropertyChanged }"
/>
According to everything I've read, if I run this and clear the textbox, I should get a validation error. I have tried all combinations of "ValidatesOn" it doesn't seem to make a difference. Can someone take pity on me and share the secret sauce? I must be missing something simple. If I bind to the metadataclass it works but that is kinda defeating the purpose.
Any help would be great!
Try adding the following static constructor to your buddy class "MyClass". It will register the metadata against your EF class so the Validator can find the Data Annotations:
static MyClass()
{
// Register the metadata against our EF data object.
// This will ensure the Validator find the annotations
TypeDescriptor.AddProviderTransparent(
new AssociatedMetadataTypeTypeDescriptionProvider(
typeof(MyClass),
typeof(MyClassMetaData)),
typeof(MyClass)
);
}
You could also try running a unit test to confirm whether the Validator has used your annotation, before adding the complexity of the GUI:
[TestMethod]
public void TestAnnotations()
{
MyClass c = new MyClass();
// Manually validate the MyClass object
List<ValidationResult> validationResults = new List<ValidationResult>();
ValidationContext context = new ValidationContext(c, serviceProvider: null, items: null);
bool isValid = Validator.TryValidateObject(c, context, validationResults, validateAllProperties: true);
Assert.IsFalse(isValid, "Validation should fail because we didn't set SomeText");
}

How to save Images to database using ASP.NET Core?

I am working on a small blog using ASP.NET Core(MVC 6) EF Visual Studio. I have trouble finding how to save images to a database. I have read about IFormfile but I do not really understand how to go about it, I am stuck. I am new to this and would love to have a little help.
I want to save the image to the post I am creating(In the same form). I, therefore, want to save it to postID. Then I need to be able to display the image, how do I do that?
You may find this useful if u need to save to database. This was a modification of https://www.mikesdotnetting.com/article/259/asp-net-mvc-5-with-ef-6-working-with-files and lots of input from k7Boys answer here MVC 6 HttpPostedFileBase?
<input type="file" name="Image" id="Imageinput">
Blog Modal Class should have Img field like;
public int BlogId{ get; set; }
...
public byte[] Img{ get; set; }
Controller;
public async Task<IActionResult> Create([Bind("BlogId,...Img")] Blog blog t, IFormFile Image)
if (ModelState.IsValid)
{
if (Image!= null)
{
if (Image.Length > 0)
//Convert Image to byte and save to database
{
byte[] p1 = null;
using (var fs1 = Image.OpenReadStream())
using (var ms1 = new MemoryStream())
{
fs1.CopyTo(ms1);
p1 = ms1.ToArray();
}
Blog.Img= p1;
}
}
_context.Add(client);
await _context.SaveChangesAsync();
return RedirectToAction("Index");
}
Took me a couple of hours to get here. Now working on viewing the images in a view, am sure this will not be complex. Enjoy
Try this its working fine
controller
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("Id,PostMode,Message,Image,AccountId,Created,Status")] Post post, IFormFile Image)
{
if (ModelState.IsValid)
{
using (var ms = new MemoryStream())
{
Image.CopyTo(ms);
post.Image = ms.ToArray();
}
_context.Add(post);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View(post);
}
Display Image
#foreach (var item in Model)
{
<img class="img-responsive full-width" src="data:image/jpeg;base64,#Convert.ToBase64String(item.Image)" />
}
You can use IFormFile to save image posted from view. Below is the sample code.
public class UserProfileViewModel
{
public string UserName { get; set; }
public IFormFile UploadedImage { get; set; }
public string ImageUrl { get; set; }
}
In view simply bind it with IFormFile property like:
<img src="#Model.ImageUrl" alt="User Logo" asp-append-version="true" />
<input type="file" asp-for="UploadedImage" />
In your controller you just need to save file on server like:
var filename = ContentDispositionHeaderValue
.Parse(user.UploadedImage.ContentDisposition)
.FileName
.Trim('"');
filename = Path.Combine(webRoot, "/Content/UserProfile/", $#"\{filename}");
if (Directory.Exists(webRoot + "/Content/UserProfile/"))
{
using (FileStream fs = System.IO.File.Create(filename))
{
user.UploadedImage.CopyTo(fs);
fs.Flush();
}
}
model.ImageURL = "~/Content/Brands/" + user.UploadedImage.FileName;

Dapper Rainbow - How to specify table name in another schema

I am pretty new to Dapper Rainbow so I may be missing something obvious. Is it possible to specify the table name and if so how?
I have tried the following with no luck.
public class DashboardContext : Database<DashboardContext>
{
public DashboardContext()
{
this.DashboardResults = new Table<DashboardResult>(this, "Monitor.DashboardResult");
}
public Table<DashboardResult> DashboardResults { get; set; }
}
I had the same problem but it seems an error in the code. I´ve just commented the lines where is setting the constructor for tables (Database.cs) and it works.
internal void InitDatabase(DbConnection connection, int commandTimeout)
{
this.connection = connection;
//this.commandTimeout = commandTimeout;
//if (tableConstructor == null)
//{
// tableConstructor = CreateTableConstructorForTable();
//}
//tableConstructor(this as TDatabase);
}
I guess this is not the best solution...
You need to hack the rainbow source to get it to work.
Find the CreateTableConstructor method in the file of DataBase.cs.
Just add some code as following:
...
var setters = GetType().GetProperties()
.Where(p => p.GetValue(this, null) == null
&& p.PropertyType.IsGenericType
&& p.PropertyType.GetGenericTypeDefinition() == tableType)
.Select...
For anyone else stumpeling over this post like I did this is now fixed in Dapper.Rainbow version 0.1.3.
It is still in beta at this time (0.1.3-beta1) so if you want to use schema you can clone/fork the repository and run the build script. The binary output can then be used directly or packaged.
As for the table setup you need to define the table name with the name of the schema for for that particular table so for example looking at this example without schema
public class MyDatabase : Database<MyDatabase>
{
public Table<Order> Order{ get; set; }
public Table<Customer> Customer { get; set; }
public Table<Item> Item { get; set; }
}
Which works if you are only using dbo. but if you are for instance using say Product schema for Item you would have to define it using a constructor
public class MyDatabase : Database<MyDatabase>
{
public Table<Order> Order{ get; set; }
public Table<Customer> Customer{ get; set; }
public Table<Item> Item;
public MyDatabase()
{
Item = new Table<Item>(this, "Product.Item");
}
}
The rest should be as before
using (var connection = DbConnections.Create())
{
connection.Open();
var db = MyDatabase.Init((DbConnection)connection, commandTimeout: 2);
var insert = db.Customer.Insert(
// .
//..... your object
// .
);
var insertId = insert.Value;
}
Based on #Acorax answer, it wasn't enough for me, I needed to add brackets to the schema and table name to solve this.
So this solved me the schema problem:
public class MyDatabase : Database<MyDatabase>
{
public Table<Item> Items;
public HamenasDbSchema()
{
Items = new Table<User>(this, "[Schema].[Items]");
}
}

EF 4.1 Codefirst WPF Eager Loading Data Binding

I am having problems databinding to EF code first. I need to be using Eager Loading, but I am running into some issues with databinding. I have the following classes:
public class Context : DbContext
{
DbSet<A> As;
DbSet<B> Bs;
DbSet<C> Cs;
}
public class A
{
public ICollection<B> Bs { get; set; }
public string Name { get; set; }
}
public class B
{
public ICollection<C> Cs { get; set; }
public string Name { get; set; }
}
public class C
{
public string Name { get; set; }
}
I am data binding Context.As to a Treeview, using the below code:
Context.As.Load();
tvItems.ItemsSource = Context.As.Local;
This works as expected, however, it does not automatically load the child properties, Bs, and subsequently, Cs. So, I found that lazy loading can help with this, like so:
Context.As.Load();
tvItems.ItemsSource = Context.As.Include(u=>u.Bs);
From my reading, this should automatically load at least the first level of child properties. However, this will not data bind, as I did not use .Local
.Include() returns IQueryable, which does not support .Local. I can use .ToList(), but this will not automatically update when I add items.
So, how the hell am I supposed to be doing this?
You could try this:
Context.As.Include(a => a.Bs).Load();
tvItems.ItemsSource = Context.As.Local;

Collection declared in XAML hangs Silverlight

I have been playing around with declaring objects in XAML. I have these classes in my Silverlight assembly:
public class TextItem
{
public string TheValue { get; set; }
}
public class TextItemCollection
{
public ObservableCollection<TextItem> TextItems { get; set; }
}
Then, I have this in my XAML:
<UserControl.Resources>
<app:TextItemCollection x:Key="TextItemsResource">
<app:TextItemCollection.TextItems>
<app:TextItem TheValue="Hello world I am one of the text values"/>
<app:TextItem TheValue="And I am another one of those text items"/>
<app:TextItem TheValue="And I am yet a third!"/>
</app:TextItemCollection.TextItems>
</app:TextItemCollection>
</UserControl.Resources>
For some reason if I include that node when I try to debug the application, Silverlight hangs (I just see the spinning blue loading circle thingy). If I comment out that node, it runs immediately.
Any ideas?
By code review: Your TextItems property is null. That can't help the XAML parser.
By experimental results: I get an exception when running the app in the debugger (I'm using Silverlight 4):
System.Windows.Markup.XamlParseException occurred
Message=Collection property '__implicit_items' is null. [Line: 12 Position: 40]
LineNumber=12
LinePosition=40
StackTrace:
at System.Windows.Application.LoadComponent(Object component, Uri resourceLocator)
InnerException:
You should initialize TextItems. You should also make the setter private so others can't mess you up. Try this, you should find it works fine:
public class TextItemCollection
{
public TextItemCollection()
{
TextItems = new ObservableCollection<TextItem>();
}
public ObservableCollection<TextItem> TextItems { get; private set; }
}

Resources