To Depend on a Parameter or a reference type Property? - software-design

I have designed a class method as follows:
public MatchingSearchRecordsDto SearchForMatchingRecordsWithinAnOrganization(string matchText, int organizationId);
The class that this method belongs to has a Property reference to a large, complex GeneralObjectClass type, which itself contains details from the http request context including a UserID, from which I could query for the organizationId of the organization to which the calling user belongs, instead of asking a front-end developer to provide the extra organizationId parameter.
Basically, I wanted to know from a perspective simplifying code development and maintenance, which would be the preferred way to call the method, and why?
Thank you everyone for your answers.

Related

ViewModel classes VS defining an Exclude Bind list on the domain class

I have a model class named Server, it contains many navigation properties and properties, which I want to prevent users from binding it. So I find two approaches of doing so to avoid over-posting attacks.
The first approach is to go to each model class and define an Exclude Bind list , with all the properties and navigating properties that should not be bind by users , as follow:-
[MetadataType(typeof(TMSServer_Validation))]
[Bind(Exclude = "Technology,IT360SiteID, VirtualMachines, TMSServer1,DataCenter,OperatingSystem,Rack,ServerModel,TechnologyBackUpStatu,TechnologyRole,TechnologyStatu ")]
public partial class Server {
}
}
The second approach is to create a view model class , with only the properties that can be modified by users as follow:-
public class ServerViewModel
{
public int ServerSize { get; set; }
[Required]
public String OperatingSystem { get; set; }
public String Commnet { get; set; }
}
I find that the first approach is faster to implement , as I only need to define the Exclude list, while the second approach will require me to create view-model class for each of the domain classes. So which approach is recommended to use and why ?
Thanks
Over-posting occurs due to the default model binder not knowing which fields you actually included in the form.
It will try to map all values in the request to object. Attackers can use your form to add additional fields to
query strings/form post data and add properties as part of the request. The default model binder won't
know the difference. Your Server class will deactivate once the mapping is complete and the update is processed.
To prevent over-posting, set the annotation to include fields in the binding, or create a ViewModel like you mentioned in your code.
So which approach is recommended to use and why ?
Both annotation and ViewModel allow binding only on specified fields, but when you use ViewModel you will not bind against business objects or entities, and you will only have properties available for the input you expected.
Once the model is validated, you can then move values from the input model to the object you used in the next layer.
k. Soctt Allen has a good article about which approach is better, you can take a look at by the following link:
http://odetocode.com/blogs/scott/archive/2012/03/11/complete-guide-to-mass-assignment-in-asp-net-mvc.aspx
It's difficult to tell without seeing the rest of your code, but in general I'd say using the ViewModel is probably a better approach for the following reasons:
You separate your view from your business logic
It is safer. If in the future someone adds a property on Server and forgets the Bind-exclude, you're exposed to over-binding without knowing it. If you use the ViewModel-approach you have to explicity add new properties
Maybe this question is a little bit ambiguous because the answers are going to be based on opinions or something. But I'll try to answer it the best I can and indeed is kind of my opinion. So this is the way I see it:
First approach (Bind attribute): Is faster to implement because you only need to add on your class the name of the property you don't want to expose, but the problems comes when you want your class to exclude some properties for one feature and other properties for another feature, and you can't add fields and sometimes in MVC, the views need more fields that the ones provided by the model class and then you're gonna need to use ViewBag or something else. This approach is very handy for fast and smalls projects, but I still don't like to use ViewBag (For aesthetics reasons)
Second approach (ViewModels): Is more work, and more time but at the end (again in my opinion) you get a cleaner and ordered code and you don't need to use the ViewBag, because you can have the perfect object to send to the view depending on what this View needs, so if you a have an object with different views, again depending on the needs, they could share the same ViewModel or they could have a ViewModel for each one. If you have a solution or a big web project, this approach is going to be very handy to keep an ordered code.
Let me know.

Why properties request/query/attributes/... are public in Symfony2?

Why not getters? And how it combined with encapsulation principe? Does it safe?
Upd:
Yes, I'm about Request. Safety: I mean that anybody in code (by using listener) can do $request->attributes = null;
If you are talking about the Request and Response objects, there was a discussion about this on the Symfony developers mailing list a few days ago. I invite you to take a look at it here.
Why not getters? Not sure if there is a definitive answer to this but I think it is a decision based on personal tastes mainly.
Does it break encapsulation? Not really in my opinion for this particular case. My reasoning is that for now, no special logic is performed on the various objects that are public right now. So in the end, you would end up retrieving the object via a getter and read or modify it directly. There is not much difference with retrieving the object using a public property.
// With Getters
$parameterBag = $request->getQuery();
$parameterBag->get('key');
// With Public Properties
$parameterBag = $request->query;
$parameterBag->get('key');
Encapsulation should be enforced when you need to be sure that a property has a particular value or format. For example, say you have a class with a cost property and this property should never be negative. So if the cost property was public, it could be possible to set it to a negative value by doing something like $receipt->cost = -1;. However, if you make it private and the user of the class is only able to set it via a setter, then you could ensure that the cost is never below 0 by doing some special validation in the setter code.
In our case, we are talking about a collection object, a ParameterBag object to be precise. I don't think there are special requirements on this object but I could be wrong. So for me, it is correct to have access to those properties via public properties.
The main argument I could see in favor of the getters is that it would be more consistent with the other parts of the framework where getters are used. However, the getters could co-exist with the public properties.
To conclude, I think it is safe for this particular case. Public properties should be used only in special cases where it seems to be beneficial and where it is correct to do so.
Do you mean the Request object? Or what properties are you thinking of?
If you're worried about safety, then take a look at the Security component, use Test-Driven-Development, use tested libraries (don't invent your own authentication, cryptography and related solutions) and do code reviews.
What's the point to encapsulate what already's been encapsulated? I mean - each of this properties is a parameterBag instance with it's encapsulation.

Adding and removing items dynamically in one View with Entity Framework and MVC

I've been at this same question in different forms now for a while (see e.g. Entity Framework and MVC 3: The relationship could not be changed because one or more of the foreign-key properties is non-nullable ), and it's still bugging me, so I thought I'd put it a little more generically:
I feel this can't be a very unusual problem:
You have an entity object (using Entity Framework), say User. The User has some simple properties such as FirstName, LastName, etc. But it also has some object property lists, take the proverbial example Emails, to make this simple. Email is often designed as a list of objects so that you can add to that object properties like Address and Type (Home, Work, etc). I'm using this as an example to keep it generic, but it could be anything, the point is, you want the user to be able to add an arbitrary number of these items. You should also be able to delete items (old address, or whatever).
Now, in a normal web page you would expect to be able to add these items in the same View. But MVC as it seems designed only makes it easy to do this if you call up an entirely new View just to add the address. (In the template for an Index View you get the "Create New" link e.g.).
I've come across a couple of examples that do something close to what I mean here:
http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx
and
http://blog.stevensanderson.com/2010/01/28/editing-a-variable-length-list-aspnet-mvc-2-style/
The problem is, although the sample projects on these sites work fine, with mock model objects, and simply lists (not an object with a child list), it's a different thing if you actually want to do something with the posted information - in my case save to database through the Entity Framework model. To adapt these cases to that, all of a sudden I'm in a maze of intricate and definitely not DRY code... Juggling objects with AutoMapper and whatnot, and the Entity Framework won't let you save and so on (see above link if you're interested in the details).
What I want to get at is, is it really possible that this is such an uncommon thing to want to do? Update a child collection in the same View as the parent object (such as the email addresses in this case)? It seems to me it can't be uncommon at all, and there must be a standard way of handling this sort of scenario, and I'm just missing it (and no one here so far has been able to point me to a straighforward solution, perhaps because I made it too abstract with my own application examples).
So if there is a simple solution to what should in my view be a simple problem (since the design is so common), please tell me.
Have you tried updating the project at your link to Steven Anderson's blog to bind to a complex object? Create a class in models called Sack and give it a single property and see if you can get it to work.
public class Sack
{
public IEnumberable<Gift> Gifts { get; set; }
}
It only took me a minute to get it up and running as I think you intend. The improvement I would have made next would be to add an HtmlHelper extension that is essentially the same as Html.EditorFor(m => m.SomeProperty), only call it something more meaningful and have it interface with the prefix scope extensions provided in the project.
public static class HtmlExtensions
{
public static IHtmlString CollectionEditorFor<TModel, TValue>(this HtmlHelper html, Expression<Func<TModel, TValue>> expression)
{
if (/* type of expression value is not a collection */) throw new FailureToFollowTheRulesException("id10t");
// your implementation
}
}

Keep a history of values for specific properties of EF entities

I have a requirement to keep a history of values of some fields in an EF4 ASP.NET MVC3 application. This just needs to be a log file of sorts, log the user, datetime, tablename, fieldname, oldvalue, newvalue.
Although it would be pretty easy to code this in various save routines, I'm wondering if I can get global coverage by wiring it into some sort of dataannotation, so that I can perhaps declare
[KeepHistory()]
public string Surname { get; set; }
in my partial class (I'm using POCO but generated from a T4 template).
So Questions
1) Is this a bad idea ? I'm basically proposing to side-effect changes to an entity, not directly referenced by the code, as a result of an annotation.
2) Can it be done ? Will I have access to the right context to tie up with my unit of work so that changes get saved or dropped with the context save?
3) Is there a better way?
4) If you suggest I do this, any pointers would be appreciated - everything I've read is for validation, which may not be the best starting point.
Actually, validation might be a good starting point. Since an attribute does not know about which property or class it was assigned to, but a validation-attribute gets called by the validation framework with all the necessary informátion. If you implement the System.ComponentModel.DataAnnotations.ValidationAttribute class you can override the IsValid(object, ValidationContext) method, which gives you the actual value of the property, the name of the property and the container.
This might take a lot of work, since you need to get to the currently logged-in user etc. I'm guessing that the .NET implementation provides some sort of caching for the specific attributes on an entity type, which would be a pain to implement by yourself.
Another way, would be to use the ObjectStateManager exposed by your EF ObjectContext, which can provide you with the ObjectStateEntry-objects for all entities of a given state. See the
ObjectStateManager.GetObjectStateEntries(EntityState) method, for more information about how to call it (and when). The ObjectStateEntry actually contains a record of the original and current-values, which can be compared to find any changes made within the lifetime of the current ObjectContext.
You might consider using the ObjectStateManager to inject your custom logging behavior, while this behavior decides based on property-attributes which change should be logged.

asp.net MVC: Pass query string as a string, or individual parameters?

In asp.net MVC I have a search action in my controller and I am trying to decide If I should pass the query to my repository as a string
public ActionResult Search(string query)
{
return View(_repository.ListPeople(query));
}
or as individual parameters:
public ActionResult Search(string FirstName, string LastName, System.Nullable<byte> Education)
{
return View(_repository.ListPeople(FirstName, LastName, Education));
}
A lot of examples I have seen online use the query string method, but to me it doesn't feel as "safe", even though it's a little easier to deal with when you have a bunch of parameters to pass in. Is there a general consensus as to the better way to do this?
I would favour model binding. That way if you decide to add extra search options you have no changes to make apart from the model class.
Info here and here
Personally, I prefer to not have the repository take on the responsibility of parsing a query string. Looking at it from a separation of concerns point of view, I feel that the repository should remain implementation-agnostic. Having to create query strings for unit testing, for example, is more cumbersome than calling the method directly with parameters.
That being said, I also prefer to have controllers interface with well-defined services, as well, as it helps to keep the controllers lighter, in my experience. I try to let the service act as a gateway to the repository, although there is no requirement to do so. There are two things that I will pass into a repository (or more likely, service), depending upon what the purpose of the call is - either a set of parameters, like you give in your second example, or as a constructed domain object, if applicable.
I would most definitely suggest going with the second route. There's no need to couple your controller with your repository. Let your repository be in charge of getting data, it shouldn't have to do any kind of parsing of a query string. That's not its job. Let the controller deal with that.

Resources