I just developing a personal project and actually I'm using EF Code First from database and I'm facing a little problem.
The problem simply is I want to define an attribute called Download and this attribute may contain multiple download links for example :
Attribute Name : Download
=>Values :
link1.com
link2.com
link3.com
How to define this in my model an attribute that can hold many values and how can I show them in my view one by one like foreach or something to fetch the attribute values and split them
Thanks and I hope someone help me with that!
You can either use a single string with a separator, or create another table linked to this one:
class Download
{
...
public string Link {get;set;}
}
class ParentClass
{
...
public virtual ICollection<Download> Links {get;set;}
}
Then in your view, you can iterate over the list of Links.
Related
How would one go about validating a nested List of Objects in an MVC Model?
I have an "Item" object which has an attached List of Revenue Entries:
public class ItemModel
{
public int ItemID { get; set; }
public virtual List<RevenueEntryModel> Revenues { get; set;}
}
This list can be edited on the page dynamically, and each item is validated individually using it's own model - "RevenueEntryModel". However, I want to be able to restrict users from entering Items without any Revenues.
Is it possible to validate whether this Revenues list is empty using Data Annotations? I'm already using Foolproof but I'm pretty sure it doesn't include this functionality.
There's a previous answer that will help you here. It's a thorough answer, but basically you need to use custom validation attributes:
You can apply your own logic that checks the number of items in the Revenues collection.
Apply a class level validation attribute to the ItemModel class. You could use System.ComponentModel.DataAnnotations.CustomValidationAttribute for this.
This points to a custom method you would create.
The attribute construct would look something like this:
[CustomValidation(typeof (MyClassWhereMethodIsLocated), "MyStaticMethodName")]
Checkout this blog for additional details
I was wondering if it is possible to group properties of a c# class.
Something like the following:
public class Computer
{
//First Group
public string Name{get;set;}
public string IPAddress{get;set;}
//Second Group
public string Driver1Name {get;set;}
public string Driver1Port{get;set;}
}
The model I have returns 70 columns or so (i.e. the model has ~ 70 properties) and I would like to return all of these to display to the user. Clearly, 70 properties is too much display on one page, and so the contents of this page will be tabbed based on the groupings of these properties (using jquery).
My initial thought was to use attributes, and group by the attributes. But I would like to open this up for other suggestions. Please let me know your thoughts on how I could achieve this.
Cheers!
You could use attributes. Either use your own, or the existing attributes that are used by the object browser:
System.ComponentModel.CategoryAttribute.
In my MonoDevelop project I have an iPhone app. I have two different views. Each view contains a UITable. For view 1 I have class 1 hooked to the UITable as Datasource 1. For View 2 I have a class 2 hooked up as Datasource 2. Both classes (i.e. Datasources) feed the tables with data. View 2 also has a custom cell and because of this loads asynchronous.
I get the data from 2 XML files using linq to XML. Everything works and the data loads great. What I need to do know is to load data in Datasource 2 based on the selection made in View 1. To do this I need to pass an ID from view 1 to Class(Datasource) 2. Problem.
I have tried just about everything I know but I just can't get it right.
The correct solution according to me:
I have created another class called SelectedRound with two properties. Code:
using System;
namespace xxxxx
{
public class SelectedRound
{
public string RoundID { get; set; }
public string Date { get; set; }
}
}
When I set RoundID in class 1 then I can access it in class 1. Trying to access it in class 2 however, returns nothing or null. Why would this happen? Could it be because Class(Datasource) 2 is loading asynchronously? Should I instantiate the SelectedRound class in some global way? If so how? AppDelegate maybe? (I am struggling to do that as well).
It seems pointless to me that setting and getting a simple string variable is difficult.
This feels like it is all about how you are passing the SelectedRound instance from the first view to the second.
As a very quick and dirty solution you could just use a singleton or could just use a static class:
public static class SelectedRound
{
public static string RoundID {get;set;}
public static string Date {get;set;}
}
For a more sophisticated pattern, then try overriding the constructors of one or both of your two view controllers in order to pass them a shared instance of your non-static class.
The view controllers may feel foreign to you right now - but they are just c# classes - so feel free to extend them by writing overrides, new methods and properties.
Many tutorials say that when i have to pass data from controller to view the best way is to create a flattern viewMoldel.
This solution came to solve also other problems (like the eager loading problem).
My concern is that when i create a flatten viewModel I lose all the informations that I store in the entities via annotation.
Suppose that i have a model composed by
class product{
[DisplayName("Name")]
public String Name{get;set;}
[DisplayName("Image")]
public String Image{get;set;}
[DisplayName("Description")]
public String Description{get;set;}
public String CategoryId{get;set;}
}
class category{
[DisplayName("Code")]
Public String Id{get;set;}
[DisplayName("Category name")]
public String Name{get;set;}
}
To render a grid that show product informations many tutorials say that the best way is to provide a flatten viewModel like this:
class productGridViewModel{
Public String ProductName{get;set}
Public String ProductImage{get;set}
Public String ProductDescription{get;set}
Public String CategoryName{get;set}
}
My concern is that I need to write again all the DisplayName annotations in the viewModel.
If you are flattening your model entities into ViewModels, shouldn't the attributes be removed from the model entity classes and placed on the ViewModels? Your model entities will not be used for display, so they should not have those attributes.
One simple solution is to have read-only properties in the viewModel which read the meta-data of the underlying Model object. Then you can bind this meta-data with the appropriate control in the View.
As below:
class productGridViewModel{
Public String ProductName{get;set}
Public String ProductImage{get;set}
Public String ProductDescription{get;set}
Public String CategoryName{get;set}
public string ProductDisplayName
{
get
{
//Please dont mind this code.. I am sure you can write it in much better way.
return typeof(Producy).GetProperty("Name").GetCustomAttributes(typeof(DisplayName))[0].ToString();
}
}
}
Your view model is your data consumption use case. If you need metadata then the view model flattened or otherwise will need to support it. May be you need to add it dynamically? Or if that's too onerous, then you need to encode it at compile time.
Edit.
You can use T4 transformations to ensure that dependent code it kept up to date. In fact we use this allow users to customise the DB and thus allow express the customisations in the view models.
What you do is put the source of the truth in one assembly, and then use a T4 transform file to create other representations from this assembly using reflection in another assembly.
The way to do it would be by implementing a custom AssociatedMetadataProvider. This isn't as much work as you'd think, and you could implement one to generate metadata from an xml file, database, convention, or even buddy types like the current one does.
The only thing you'd need to do differently to the current implementation is allow buddy types to contain field/properties which don't exist on the model they apply to, because that is the only thing currently preventing you from creating a buddy type which you could apply to all view/editor models of your particula model.
Its a bit of work and depends how much time it would save you but don't forget most of the MVC source code is available and you wouldn't have to change very much
Martin
Our system complexity has risen to the point that we need to make permission names tied to the client from the database more specific. In the client, permissions are referenced from a static class since a lot of client functionality is dependent on the permissions each user has and the roles have a ton of variety. I've referenced this post as an example, but I'm looking for a more specific use case. Take for instance this reference, where PermissionAlpha would be a const string:
return HasPermission(PermissionNames.PermissionAlpha);
Which is great, except now that things are growing more complex the classes are being structured like this:
public static class PermissionNames
{
public static class PermissionAlpha
{
public const string SubPermission = "PermissionAlpha.SubPermission";
}
}
I'm trying to find an easy way to reference PermissionAlpha in this new setup that will act similar to the first declaration above. Would the only way to do this be to resort to pulling the value of the class name like in the example below? I'm trying to keep all the names in one place that can be reference anywhere in the application.
public static class PermissionAlpha
{
public static string Name { get { return typeof(PermissionAlpha).Name; } }
}
** Edit ** - Added missing permission name.
Maybe this would be too big of a change for you with the size of your project, but we have all of our business objects split into partial classes. One is for manual changes and one gets generated. During code-generation, we write the permission keys into the generated side of the partial classes from our "single source of truth". We're using a set of classes as our source of truth and CodeDom to generate, but you could also use a database as your source and use T4, CodeSmith, or others to generate.
Why not create reflectable attribute(s) on the classes in question? That way one can add all the extra information required. I provide a way of divining attributes on my blog article entitled:
C# Using Extended Attribute Information on Objects
HTH