I am using the SimpleMembership provider and adding additional fields to be saved on registration.
To save additional fields on registration I use the method used everywhere e.g. Seed Users and Roles with MVC 4, SimpleMembershipProvider, SimpleRoleProvider, Entity Framework 5 CodeFirst, and Custom User Properties.
I use the following SimpleMembership provider method called in my HttpPost ActionResult Register method.
WebSecurity.CreateUserAndAccount(registerModel.UserName, registerModel.Password,
new { FirstName = registerModel.FirstName, LastName = registerModel.LastName, CompanyName = registerModel.CompanyName});
Additional fields get added by a by value method parameter of type object. The description for this is "A dictionary that contains additional user attributes"
This works, but I have JetBrains ReSharper 8 installed and for the property names I get "redundant explicit property name" warnings.
To remove the warnings I changed my code to:
WebSecurity.CreateUserAndAccount(registerModel.UserName, registerModel.Password,
new { registerModel.FirstName, registerModel.LastName, registerModel.CompanyName});
My questions are:
1) for this anonymous object parameter where I now remove the property names so I don't get the Resharper warnings anymore, how does it know what the property names will be use to match to the db property class, since they are passed by value?
2) what is best practice having the property names in or not. Having them not in is not very readable and in code samples they are specified, so I would imagine having them in is better for readability rather than removing it.
My question are 1) for this anonymous object parameter where I now remove the property names so I don't get the Resharper warnings anymore, how does it know what the property names are since they are passed by value?
The names are inferred (by the compiler) from the expressions. This only works when you're using a field or property (not a literal or a method for example). This is in section 7.6.10 of the C# language specification.
2) what is best practice having the property names in or not. Having them not in is not very readable and in code samples they are specified so I would imagine having them in is better rather than removing it
If it's more readable for you and your team to always include the name, then go ahead and do so. For other people, it may feel a little redundant. Just adjust your R# settings to fit your local conventions.
Your argument that "in code samples they are specified" is specious though - there are some examples where they're specified and some where they're not. I suspect you'll find a mixture even within particular example providers (e.g. in MSDN).
When you set up your propertyNames object you're creating an instance of an anonymous Type - when you do that you can leave out the property name if it's the same as the property from which you're assigning the value. That's why ReSharper says the names are redundant.
Explicitly stating property names when you don't have to is personal preference; once you're familiar with the above convention I don't think it harms readability.
how does it know what the property names will be use to match to the db property class since they are passed by value
In a nutshell anonymous types are created on compile time. So the compiler resolves property names using expressions passed and in the result we have an anonymous class with declared readonly properties. You can check your IL in order to see that the assembly contains this type and properties are set explicitly.
what is best practice having the property names in or not
It depends on each person. I would recommend to choose a single way for your team and use the same ReSharper settings on each developer machine.
Related
I wrote a method in c# which takes the input parameter of type List and i kept the parameter variable name as cardIDList.
And from code review feedback, they asked me to change the parameter variable name from cardIDList to cardIDs saying that appending list is not a right naming convention from Microsoft standard.
I tried to find the truthiness of that feedback in google, but I couldn't find like that anywhere. I need the help on this.
From :
public void DoSomething(List<long> cardIDList)
To :
public void DoSomething(List<long> cardIDs)
Common naming conventions can be found here https://github.com/ktaranov/naming-convention/blob/master/C%23%20Coding%20Standards%20and%20Naming%20Conventions.md
and here:
https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/naming-guidelines
https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/naming-parameters says:
CONSIDER using names based on a parameter’s meaning rather than the
parameter’s type.
First of all - why do you take List as a parameter? You should allow the parameter to be as generic as possible - if you only need collection of elements and their count, use ICollection. Even better IEnumerable if you want to only iterate through the list or IReadOnlyCollection if you want to avoid accidental item change. It will be much easier to write unit tests for this method or override it in the future.
As you can see, type of parameter can be changed in the future and it shouldn't affect the naming. Putting "list" in the parameter name is redundant because we already know the type of that parameter. Now what should you do if you want for example to change the type to IEnumerable? Change it to cardIDEnumerable?
I'm using web api. I've been a bit lazy and decided to return a value tuple from my controller.
[HttpGet]
[Route(AuthAPIRoutes.GET_MFA_DEVICES)]
public (string Type, string Value)[] GetMultiFactoryMethods()
{
return GlobalFactory<IPaystreamMFASecurityService>.Instance.GetMultiFactorMethods();
}
The JSON response doesn't seem to be using the appropriate naming is this being optimized away?
{
"item1": "Phone",
"item2": "1-512-555-0550"
}
NOTE: I'm aware I can explicitly make a model to avoid this problem. I would like to understand what is occurring and why aren't my value tuple names being respected in the response?
What is occurring is that ValueTuple as a type (a group of generic types, actually) is actually very static, and has properties named things like Item1, Item2, etc.
The nice syntax you get from C# where you can declare a name and have it used elsewhere in your code is simply a feature of the C# language. The compiled code referencing those values by name ends up calling into those static properties (Item1, e.g.). And in fact, you can still access those properties by their "Item" names in your own C# code.
From the compiled code's perspective, the only clue about the names of the fields on those tuples is an attribute that gets associated with the method, so unless ASP.NET passed contextual information about the action method into the serializer, there would be no way for the serializer to know what names those properties were supposed to have.
See this article for an in-depth look at what ValueTuples are doing under the hood.
I have a anonymous class:
var someAnonymousClass = new
{
SomeInt = 25,
SomeString = "Hello anonymous Classes!",
SomeDate = DateTime.Now
};
Is there anyway to attach Attributes to this class? Reflection, other? I was really hoping for something like this:
var someAnonymousClass = new
{
[MyAttribute()]
SomeInt = 25,
SomeString = "Hello anonymous Classes!",
SomeDate = DateTime.Now
};
You're actually creating what is called an anonymous type here, not a dynamic one.
Unfortunately no there is no way to achieve what you are trying to do. Anonymous types are meant to be a very simple immutable type consisting of name / value pairs.
The C# version of anonymous type only allows you to customize the set of name / value pairs on the underlying type. Nothing else. VB.Net allows slightly more customization in that the pairs can be mutable or immutable. Neither allow you to augment the type with attributes though.
If you want to add attributes you'll need to create a full type.
EDIT OP asked if the attributes could be added via reflection.
No this cannot be done. Reflection is a way of inspecting metadata not mutating it. Hence it cannot be used to add attributes.
Additionally, type definitions in an assembly, and in general, are immutable and cannot be mutated at runtime [1]. This includes the adding of attributes to a method. So other reflection like technologies cannot be used here either.
[1] The one exception to this is ENC operation
First of all, this is an anonymous type. The word "dynamic" might lead people to think you're talking about a C# 4.0 class implementing dynamic semantics, which you aren't.
Secondly, no, you're not able to do what you ask.
If you need to specify attributes for your properties, you're back to a named type, ie. a normal class or struct.
It is possible to add attributes to an anonymous instance using TypeDescriptor.AddAttributes. You can then later access the attributes using TypeDescriptor.GetAttributes.
This will not add them to the Type instance for the object. So it may not be useful in your case if you do not control the code that retrieves and applies the attributes.
I need to loop over a List<dynamic> objects.
The list's objects all have values, but for some reason, I am not able to access any of the dynamic object fields. Below is a screenshot of my debug window:
There you can see the object contains fields (such Alias, Id, Name, etc).
I tried both casting it to a IDictionary<string, object> and ExpandoObject, to no avail. I did not face such a thing before: failing to access existing fields in a dynamic object when they exist.
What is wrong here?
The code is throwing a Microsoft.CSharp.RuntimeBinder.RuntimeBinderException with a message stating {"'object' does not contain a definition for 'Name'"}.
The list was created adding anonymously-typed objects, like this:
return new List<dynamic>(fields.Select(field => new
{
Id = field.Id,
Alias = field.Alias,
Name = field.Name,
Type = field.Type,
Value = field.Value,
SortOrder = field.SortOrder
}));
where fields is an ICollection<Field>, a strongly-typed collection.
The telling part is the exception:
{"'object' does not contain a definition for 'Name'"}.
This indicates that the runtime binder was not actually capable of accessing the type you're passing in dynamic (since dynamic does actually enforce visibility rules).
The most likely cause of this is that you're creating the anonymous type in a different assembly from the one where you're subsequently reading it - since anonymous types are declared internal, the consuming assembly cannot access it, causing the error message above.
Contrast with the usual case of runtime binder exceptions:
'<>f__AnonymousType0< string >' does not contain a definition for 'Name'
EDIT:
A possible solution to the problem is to use the InternalsVisibleToAttribute on the assembly containing the anonymous type. However, this is code smell - just like any other use of InternalsVisibleToAttribute or internal itself.
A better way would be to make sure you don't actually pass anonymous types over assembly boundaries - after all, they shouldn't even be used outside of the method they originated from; the fact that they are is basically an implementation detail of .NET - they didn't have another way to do the same thing. This could change in future versions, making the InternalsVisibleToAttribute solution doubly unreliable.
The way your code is using dynamic suggests that your team has flawed assumptions about how dynamic works and how it's supposed to be used. Note how the actual runtime type of List<dynamic> is actually List<object>. The same goes for arguments of type dynamic (which are again just object, albeit marked with DynamicAttribute). And in fact, that really is what dynamic is - it's a way to handle runtime dynamic dispatch - it's not a property of the type or anything, it's just the way you actually invoke whatever you're trying to invoke. For C#, dynamic allows you to skip most of the compiler checks when working with those dynamic types, and it generates some code to handle the dispatch for you automatically, but all of that only happens inside the method where you actually use the dynamic keyword - if you used List<object>, the end result would be exactly the same.
In your code, there's no reason not to use simple static types. Dynamic typing doesn't really give you any benefits, apart from the effort to code the types themselves. If your co-workers don't like that, well, they should present a better solution - the problem is quite obvious, and it's something you need to deal with.
Much worse, it explicitly hides all context, all the type information. That's not something you want in an API, internal or not! If you want to hide the concrete types being used, why not - but you should still expose an interface instead. I suspect this is the reason why anonymous types can't implement interfaces - it would encourage you to go entirely the wrong way.
I got something strange into VB.NET, never notice before...
I have a class in VB.NET having a property with parameter and I want to use that property in other C# Class by making object of VB.NET class but class object not showing that property, could any one tell me whether I can access that property into C# or not.
If yes, how?
If no, what does CLR mean?
Here is my code...
Public Property AsString(ByVal name As String) As String
Get
//Some code
End Get
Set(ByVal value As String)
//Some code
End Set
End Property
Note: I can not change VB.NET code as it is compiled DLL.
Thanks in Advance
Parameterised Properties are converted to get_ and set_ methods.
string name = "Foo";
string value = "Bar";
MyObject.set_AsString(name, value);
string fooValue = MyObject.get_AsString(name);
C# doesn't support indexed properties that don't have the Default keyword. You simple use get_AsString() to call the property getter and set_AsString() to call the setter. Methods, not properties. They should readily show up in the IntelliSense list.
Also note that set_AsString() requires two arguments even though you made the property setter non-indexed. Pass anything, null will do.
Fwiw, this is perhaps illustrative of why the C# team decided to not support indexed properties in the general case. The mismatch between the getter and the setter is painful. The vb.net team had no choice, Visual Basic had them long before .NET came around. It did make a partial comeback in C# version 4 though, indexed properties are supported on COM interfaces. COM interop programming is too painful without them. Particularly in the Office object model.
If u have noticed actually there are two parameters in your property one is your's name and other is the default value so u have to give two parameter value when u work with that