I set to member of class attibute DataMember.
[DataMember]
internal protected string _FirstName="";
[DataMember]
public string FirstName { get { return _FirstName; }
internal protected set { _FirstName=(value!=null?value:""); } }
Next I want to search class members which have this attribute. But when I type:
Type.GetType("classType").GetProperty("FirstName").Attributes
I get null.
Any idea why this attribute was not found by reflection ?
You need to call GetCustomAttributes, not use the Attributes property.
var attributes = Type.GetType("ClassType").GetProperty("FirstName")
.GetCustomAttributes(typeof(DataMemberAttribute), true);
Related
**public class Ticket : BaseEntity
{
public TicketType TicketType { get; set; }
}
public class TicketType : AuxiliaryInfoBaseEntity
{
public string Description { get; set; }
}**
In Ticket Entity i need one property of TicketType and type of column should be byte in Ticket.
Resulting table will look like.Table-Ticket:column TicketType(tinyint,not null).
When i trying to migrate, i am getting this exception.
System.InvalidOperationException: 'The property 'Ticket.TicketType' is of type 'TicketType' which is not supported by current database provider. Either change the property CLR type or ignore the property using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.
Please help me with some soluntion thanks.
this is the class:
public class Category
{
public guid id,
public string name,
public Category Parent
}
i am using Json.net to serialize a collection of it, but i don't want the Parent object to be serialized, just need the id:
what i expecte:
[
{'name':'cate1','id':1000,'parent':999}
{'name':'cate2','id':1001,'parent':998}
]
i have read about the Serialization Attributes but don't get a solution.
The easiest way to do this would be to add a get-only property for the parent id (private or public as you prefer), and serialize that, ignoring the actual Parent property:
public class Category
{
public int id;
public string name;
[JsonIgnore]
public Category Parent;
[JsonProperty("parent", NullValueHandling = NullValueHandling.Ignore)]
int? ParentId { get { return Parent == null ? (int?)null : Parent.id; } }
}
Greetings StackOverflow,
TL;DR
In a field template control's OnLoad method how can I find the Data Control of other fields in a FormView by property or column name.
END TL;DR.
I'm trying to add a some logic to the Boolean_Edit field template so that if the property bound to it has a new attribute I made the template will inject JavaScript. The JavaScript is intended to disable all of the data controls of the column/property names listed in the attribute's ControlledFieldNames property.
This is sort of confusing so I'll share some code.
Here is the attribute class I made for this:
/// <summary>
/// Attribute used to insert javascript into an ASP.NET web page that uses Dynamic Controls so that if the field's value changes it disables (or enables)
/// other web controls on the page which correspond to the other bound property names.
/// </summary>
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, Inherited = false, AllowMultiple = true)]
public sealed class InputRestrictorFieldAttribute : Attribute
{
public Boolean TargetEnabledState { get; set; }
public String[] ControlledFieldNames { get; set; }
public InputRestrictorFieldAttribute(Boolean targetEnabledState, params String[] controlledFieldNames)
{
this.TargetEnabledState = targetEnabledState;
this.ControlledFieldNames = controlledFieldNames;
}
}
So I might have a property in some scaffolded class like so:
[ScaffoledTable(true)]
public class Person
{
/* Other properties... */
[InputRestrictorFieldAttribute(false, new String[]
{
"StreetAddress",
"City",
"State",
"Zip"
})]
public Boolean AddressUnknown { get; set; }
public String SteetAddress { get; set; }
public String City { get; set; }
public String State { get; set; }
public String Zip { get; set; }
/* some more code */
}
Now in the Boolean_Edit.ascx.cs file I am trying to check if the currently scaffold property has the InputRestrictorFieldAttribute and if so inject JavaScript onto the page such that when the AddressUnknown CheckBox control is check is disabled the TextBox controls for StreetAddress, City, State, and Zip.
Below is what I have tried most recently.
protected override void OnLoad(EventArgs e)
{
var attributes = this.Column.Attributes;
foreach (Attribute attr in attributes)
{
if (attr is InputRestrictorFieldAttribute)
{
InputRestrictorFieldAttribute restrictor = (InputRestrictorFieldAttribute)attr;
String restrictorScriptFunctionName = String.Format(RESTRICTOR_SCRIPT_FUNCTION_NAME, ClientID);
String restrictorScript = String.Format(RESTRICTOR_SCRIPT_TEMPLATE_ONCLICK,
restrictorScriptFunctionName,
restrictor.BoundFieldNames.Aggregate("", (aggr, item) =>
{
var bc = this.NamingContainer.BindingContainer;
var ctrl = bc.FindFieldTemplate(item);
return aggr + String.Format(RESTRICTOR_SCRIPT_TEMPLATE_ELEMENT, ctrl.ClientID);
}));
Page.ClientScript.RegisterStartupScript(Page.GetType(), "restrictorScript_" + ClientID, restrictorScript, true);
CheckBox1.Attributes.Add("onchange", restrictorScriptFunctionName + "(this);");
}
}
base.OnLoad(e);
}
Now I know doing things like getting the this.NamingContainer.BindingContainer many not (or probably wont) work in other pages but for now (in the context of the Insert.aspx page template) works. this.NamingContainer.BindingContainer is the FormView1 control of the Insert.aspx page. But everything I've tried so far to get the various data dontrols or field templates, or dynamic controls by their property name it always returns null or throws an exception.
Lastly, the aggregate method is just concatenating pieces of JavaScript together so that all of the controls are deactivated using just one JavaScript function. The contents of those script are not important to this question.
there is an extension method called FindFieldTemplate see see it here
Is it possible to specify an object as a parameter in MVC with default values in some way?
E.g.
public virtual ViewResult Index(RequirementFilters requirementFilters)
I'd like to initialize the values of a couple of parameters on RequirementFilters?
At the moment I am doing
public virtual ViewResult Index(int status=1, bool required =false)
I wanted to create a Filter Object so I could re-use it but I can't figure out way of setting defaults for the object in the Action Parameters.
Thanks
Graeme
You could create a custom ActionFilter attribute and create an instance of your Filter Object there. You can provide some properties through the custom attribute.
Here's an example:
public class DefaultQuerySettingsAttribute : ActionFilterAttribute
{
public string ParameterName { get; set; }
public Type SettingsType { get; set; }
public int Rows { get; set; }
public string SortColumn { get; set; }
public string SortOrder { get; set; }
public bool PagingEnabled { get; set; }
public DefaultQuerySettingsAttribute()
{
this.ParameterName = "settings";
var defaultSettings = new QuerySettings();
this.Rows = defaultSettings.Rows;
this.SortColumn = defaultSettings.SortColumn;
this.SortOrder = defaultSettings.SortOrder;
this.PagingEnabled = defaultSettings.PagingEnabled;
}
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
if (filterContext.ActionParameters.ContainsKey(this.ParameterName))
{
var querySettings = filterContext.ActionParameters[this.ParameterName] as QuerySettings;
if (querySettings == null || string.IsNullOrWhiteSpace(querySettings.SortColumn))
filterContext.ActionParameters[this.ParameterName] = this.GetQuerySettings();
}
}
private QuerySettings GetQuerySettings()
{
var querySettings = (QuerySettings)Activator.CreateInstance(SettingsType ?? typeof(QuerySettings));
querySettings.Rows = Rows;
querySettings.SortColumn = SortColumn;
querySettings.SortOrder = SortOrder;
querySettings.PagingEnabled = PagingEnabled;
return querySettings;
}
}
ParameterName is the name of the argument in the action method (requirementFilters in your case).
You can also specify actual type that will be instantiated by providing SettingsType.
Users sometimes prefer to see the defaults on screen, rather than allowing the system to hide the defaults internally.
A better way of having defaults will be to actually show the defaults on int UI, in the HTML by rendering it with together with the defaults. That way when someone posts the page, the defaults which you pre-rendered is also posted and binded to the model.
So try and see if you can render with defaults whatever for you are rendering and posted to the Index action.
Finally, if you can't do it that way, what is preventing you from initializing the properties with default values in the no-arg constructor while creating the object?
EDIT
Or you can use the C# language feature the null coalescent operator to implement defaults. Look here to read about it.
As long as you don't need to change the defaults per action, you can set them in the default constructor of the Model.
I am trying to create a custom attribute in mvc to use it's parameters in a view as breadCrumb.
well, this is the code of the attribute
[AttributeUsage(AttributeTargets.All, AllowMultiple = true)]
public class BreadCrumbAttribute : Attribute {
public BreadCrumbAttribute(string title, string parent, string url) {
this._title = title;
this._parent = parent;
this._url = url;
}
#region named parameters properties
private string _title;
public string Title {
get { return _title; }
}
private string _url;
public string Url {
get { return _url; }
}
private string _parent;
public string Parent {
get { return _parent; }
}
#endregion
#region positional parameters properties
public string Comments { get; set; }
#endregion
}
this is the call of the attribute
[BreadCrumbAttribute("tile", "parent name", "url")]
public ActionResult Index() {
//code goes here
}
this is a way of how I'd like to get the values. (this is a partial view)
System.Reflection.MemberInfo inf = typeof(ProductsController);
object[] attributes;
attributes = inf.GetCustomAttributes(typeof(BreadCrumbAttribute), false);
foreach (Object attribute in attributes) {
var bca = (BreadCrumbAttribute)attribute;
Response.Write(string.Format("{0}><a href={1}>{2}</a>", bca.Parent, bca.Url, bca.Title));
}
Unfortunately, the attribute didn't get call with the way I implement it. Although, If I add the attribute in Class instead of an Action method it worked.
How could I make it work?
Thanks
The problem is that you are using reflection to get the attributes for the class, so naturally it does not include attributes defined on the action method.
To get those, you should define an ActionFilterAttribute, and in the OnActionExecuting or OnActionExecuted method, you can use filterContext.ActionDescriptor.GetCustomAttributes() method (MSDN description here).
Note that with this solution, you will likely have two different types of attributes: The first one is the one you wrote, to define the breadcrumbs. The second is the one that looks at the attributes on the executing action and builds up the breadcrumb (and presumably adds it to the ViewModel or sticks it in HttpContext.Items or something).