Hi I have been reading some lecture notes and I cant work out why this method:
[OperationContract]
Student PostStudent (Student student);
Is good.
And this method is bad:
[OperationContract]
void PostStudent (string firstname, string lastname etc..);
Yet my implemented version is this:
[OperationContract]
void PostStudent(Student student);
So Im not sure if my implemented version is bad, Im also unsure how my lecturer got
Student PostStudent (Student student); // ?
Web services are built upon the use of messages. A message in WCF is defined by writing a class, which your Student class is, and (optionally) marking it with the DataContract attribute. This enables versioning and setting various properties on the properties of that class (although the latter effect can also be achieved using the MessageParameter attribute).
So yes, PostStudent (string firstname, string lastname etc..) is bad.
Whether or not to return something from that method is up to you. A void can be perfectly fine, because using for example SOAP you can return a Fault indicating why the user could not be created: no error means the creation went well.
When you want to inpect the created Student, you might as well define a PostStudentResult (or a PostResult<T>) class and return that, containing the properties Student (or T Result) and Status, where the first contains the student as it's created and the latter indicates whether or not the creation was successful.
Return values in Web services are not bad practice in general. So it is about the parameters. Data that belongs together should be wrapped in in Objects.
Further a Post method should not get an return value at all. You post it and in case of an error your will receive an Exception.
If your need to receive some student you should create an method like:
Student GetStudentByName(string name);
If it is a WCF then specifying Action can also be a good practice with Void methods.
Like evryone else said, having too many method parameters is bad practice. Any way I can see only one difference between your signature and the good signature you mentioned. Having the student object as return will give you the ability of having the Id of the student after addition in db for example. Same thing applies for any other calculated properties of the object. Have a void method will force you to load the object again which means an extra trip to server in case you wanted to use the object directly after posting it. Any way having void WCF method is not bad if returning the object is nothing but an extra bandwith.
Related
We have an integration system. We are converting/mapping one object returned by an API to another different object to be used in POST request of another totally separate API. Right now, everything is done in one giant function making debugging really time consuming.
However, it is not as simple as using AutoMapper or a simple custom mapping class. The conversion requires lot of calls in between. A simplified version for example:
Let say following is the JSON returned by a GET API call at url (http://example.com/getCustomer)
{
id:1,
addressId:42
countryid:333,
stateId:666
}
Now, we want to convert this to another object that can be sent in a POST request call to a different API say (http://foo.org/createPatron)
{
name:ABC,
address:123 Random Street
country:Canada
state:Ontario
customerSince: 4/8/2018
customerType: VIP
}
So this conversion requires lots of other API calls in addition to other logic to build right kind of object.
Now, I am in dilemma to where this conversion responsibility should take place.
I have a POCO from one call and POCO from another call. Any design patterns here? Should an api caller object be passed to POCO's so that API calls can be made from it?
**
EDIT 1: Expanding on the problem a bit more and in another way.
Consider this way: I have this DTO
// assume getters and setters
class UserDTO {
long id;
int countryCode;
int stateCode;
}
Now I want to convert this to following entity
// assume getters and setters
class User {
long id;
string countryName;
string stateName;
}
However, to convert countryCode in UserDTO to countryName in User in need to make a call to get all country code to countryName mappings like: http://example.org/getCountryList. After getting this list I have to find the name of the country with the code in DTO. Then have to do same thing for state as well.
As you can imaging this with numerous other properties. Some of which may require some validation and combination before assignment in User.
So I am dependent on other data sources to convert UserDTO to User. Again, where should this responsibility be handled? One way something like(Note we could use constructor and all that but that is not the point):
// assume getters and setters
class User {
long id;
string countryName;
string stateName;
public UserDTO FromUserDTO(ApiCaller apiCallerm,UserDTO userDTO){
var countries = apiCaller.GetCountryList();
this.countryName = countries.First(c => c.countryCode.Equals(userDTO.countryCode));
.
.
.
Now the problem here is that ApiCaller is being passed to Entity or it could be passed to DTO which will in a way violating Single Responsibility principle.
So again my question is: where this conversion responsibility should take place?
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I'm no expert, but I'm trying to understand if there's a flaw in my logic here. I'm pretty sure it won't take long to have it pointed out if so!
Instead of defining several parameters on a common method, why not simply have a structure as the single input parameter? If each parameter is defined separately and another parameter is added or one is removed, this requires maintenance on every piece of code that calls that method. If a structure was used, then none of the calling code would break, surely? If some code in future required an extra parameter but legacy code didn't, I can add that parameter to the existing list and the legacy code remains untroubled.
As an example: I'm looking at a company where there are multiple websites/projects (to clarify from my original post, which said 'products' and could be misinterpreted as physical products) that need to interface with payment gateways. Depending on the customer location, up to five different payment gateways might be called to process the customer payment.
Currently each one of these multiple products has its own implementation of the payment processing, complete with checking of returned parameters from the gateway. I find this confusing and, well, plain wrong and although there isn't really the time or resource at present to rewrite everything from scratch, I think a relatively quick fix would be to create a new "payments" class project which had a defined set of parameters.
As far as I'm concerned, the front end should only do something as simple as call a method that is "make a payment of x in currency y in country z" and expect a success/fail flag & optional message that clarifies any failure in return. This way, every product the company has will share the same payment processing.
Now parameter wise, currently the requirement for input would only be amount, currency & country (no, you can't always infer currency based on customer location before someone suggests it!). And for a return it would only be a Boolean success/fail and a message explaining the reason for failure. However it's possible that extra parameters will be required - both for in and out - in future and without wanting to break the existing calls to the method, it would appear sensible to simply use a simple structure, e.g.:
struct inParams
{
public decimal amount;
public string currency;
public string country;
};
struct outParams
{
public bool success;
public string message;
};
public outParams makePayment(inParams ip)
{
//...code goes here
}
Is this a "Bad Thing" to do code-wise or is it acceptable practice? If anyone thinks that it is better to have the parameters defined in the method signature individually, can you please explain why that would be better than my suggestion to use a simple structure please?
In response to "oɔɯǝɹ"
I don't really see that the issues you've raised are that serious though.
For example a sample call would be something like:
PaymentProcessor pp = new PaymentProcessor();
ppInParams ppIn = new ppInParams();
ppIn.amount = 100;
ppIn.currency = "USD";
ppIn.country = "USA";
ppOutParams ppOut = pp.makePayment(ppIn);
if (!ppOut.success)
{
//check error message, handle error, display message
}
else
{
//display confirmation message to user, update account log
}
Your point: This leads to not very discoverable code is hard to justify in the face of such simplicity as shown above, surely?
Users need to add extra boiler plate code just to instantiate your parameter struct. - well, yes, but it's not a major ballache to add a line of code for each parameter, is it?
You will need to manage heaps of parameter structs. Two for every method.
-How are you even going to name them?
-In case you're thinming, I know, I'll just reuse them, then you've made your problem worse. Whats gonna happen when a single method using a struct need another parameter?
I don't see the problem here either. I have a single "paymentProcessor" class in which I have "ppInParams" and "ppOutParams" and they are contained within the class itself - to me, a perfectly logical place to put them as they relate directly to that class.
Your final point : And in particular, your return type struct smells funny to me. Do you expect that every caller will inspect the boolean result? And what should i do with the message? Log it? show it? Have you not heard of structured exception handling? seems bizarre to me and I don't understand the point you're trying to make. One million percent YES I expect every caller to check the boolean response as that's what tells them if the payment was a success or not! This is the whole point of simplifying the call like this surely? As the error handling is different depending on which web site has called the "makepayment" method, then again it makes perfect sense to me to handle the error back in the calling code.
Products should not include payment processing. Payment processing does not describe an attribute or action of Product it describes an action on a Product. You likely need a Payment object which can be loosely based on your inParams struct:
class Payment {
public decimal Amount { get; set; }
public string Currency { get; set; }
}
The Country property is interesting. If knowing where the order was placed is important the Order came from a single location so Country should belong to Order. However, if knowing which country each payment came from is important then Country should belong to Payment. That is up to you. I included Country in Order.
You will also need an Order object to group the Payment and Products. Notice the Order object accepts an interface IPaymentProcessor as a constructor argument. You can implement different payment processing behavior by passing a different implementation of the IPaymentProcessor interface into the Order object. You can apply your business logic to figure out which concrete implementation should be sent to the Order constructor. The important part of this is you will never need to go alter your Order or Payment classes to change the payment processing behavior.
class Order {
public string Country { get; set; }
public ICollection<Payment> Payments { get; set; }
public ICollection<Product> Products { get; set; }
private IPaymentProcessor paymentProcessor;
public Order(IPaymentProcessor paymentProcessor) {
this.paymentProcessor = paymentProcessor;
}
void MakePayment(Payment payment) {
this.paymentProcessor.ProcessPayment(payment);
}
}
If you will never accept multiple Payments on an Order you can change the ICollection<Payment> Payments to Payment Payment.
IPaymentProcessor interface:
interface IPaymentProcessor {
void ProcessPayment(Payment payment);
}
Remember structs are value types and will be copied when they are passed as a parameter to a method. Classes are references types and only the reference (32 or 64 bit value based on the computer's word size) is passed by value to a method. It looks like a class is better in the situation, especially if you anticipate the object to grow.
UPDATE AFTER COMMENT:
Well that certainly changes how I read your question! I think much of the answer still applies so I will leave it. Using the logic above I would implement an OrderProcessor Service that would accept Order objects and invoke their ProcessPayment method (and whatever other logic is required). You still inject the IPaymentProcessor interface based on the rules of the system (where the order originated). Alternatively, if chunks of the order process are similar then consider making IPaymentProcessor into a base class PaymentProcessor where you can override specific behaviors in the base class when needed. There are lots of ways to implement this but the main idea I am trying to convey is this is an excellent case for polymorphism and this is just an example of how you could construct a basic architecture using that principle.
There can't be strict rules whether to wrap multiple input parameters into some class/structure or pass them individually. Everything depends on your particular situation.
Consider the following example (rather silly, just to show an idea):
public void makePayment(decimal amount, string currency, ILog logger)
{
//...code goes here
}
Looking on the input parameters, it is obvious that amount and currency could have semantic relationship between each other. So, it's reasonable to wrap them into separate class Payment. But ILog is not related to Payment by no means. It's just a logger.
You could refactor your method to be like this:
public void makePayment(Payment payment, ILog logger)
{
//...code goes here
}
The main idea that you should not artificially combine input parameters. You should combine them guided by their semantic. Then there are more chances that you will be able to reuse your classes in other places. Plus, do not forget about readability - it's easier to understand a meaning of your method if you have clear separation of semantically different dependencies.
As for output parameters, there is no much choice - you could return only one parameter (not considering ref/out arguments here). So, sure, it's OK to wrap multiple parameters into a separated class, but it's important to name it according to it's meaning: in your example it could be named, say, PaymentResult.
Breaking changes gonna break;
Consider what happens when you need to update the payment method to add another required parameter. For example, since currency exchange rates can change and you're making international payments, you discover that you need to add a date parameter, to determine the correct exchange rate.
The exchange rate at opening of market is taken as the desired value. This is a mandatory requirement, leaving that out will introduce a whole lot of trouble and bleeds money. So your struct becomes:
struct inParams
{
public decimal amount;
public string currency;
public string country;
public DateTime paymentDate;
};
'Great' you think, since you didn't break change the interface. But since this is a mandatory value, omitting this value, will throw an ArgumentNullException.
Only problem is, all the users of your interface still need to update their code!
Besides my other answer, i think this is a bad practice.
This leads to not very discoverable code. Editors, IDE's and IntilliSense are tuned to regular parameter passing.
Users need to add extra boiler plate code just to instantiate your parameter struct.
You will need to manage heaps of parameter structs. Two for every method.
How are you even going to name them?
In case you're thinming, I know, I'll just reuse them, then you've made your problem worse. Whats gonna happen when a single method using a struct need another parameter?
And in particular, your return type struct smells funny to me. Do you expect that every caller will inspect the boolean result? And what should i do with the message? Log it? show it? Have you not heard of structured exception handling?
TL,DR; You might get a little advantage locally (which i don't see), but it requires a whole lot extra work calling functions like this. Since there are likely more callers of a method, than the method itself, you should make it ia easy as possible to call your method.
I am very new to WCF programmng and having some difficulties.
I have client application which collects student data and then that student data will be stored to the DB through a web services.
So I have student class in client side and when new student comes I create the student object and assigned collected values.
What is the most suitable way to pass this data to the services??
Options that I can follow is;
Option 1
public void InsertStudent(string id, string name, string address)
{
}
I feel this is not good. Because if I have to pass so may data the parameter list will get lengthy.
Option 2
define a data contract on service
public void InsertStudent(WcfStudent obj)
{
}
I feel this is good. But I have some issues with how to send the parameter(WcfStudent).
Do I need to create this WcfStudent object on my client side and pass the object.
WcfStudent obj=new WcfStudent()
obj.name=myStudent.name;
obj.id=myStudent.id;
client.InsertStudent(obj);
is this the correct way to to do this??
Please advice me.
Of course like you said second option is better. In WCF Project you have to create DataContract WcfStudent. In project which have service reference (this is what you call client) you have to just execute method (OperationContract) InsertStudent. How you create this object in theory it doesn't matter but I think it's a good practice to have in your 'client' also an object named for example StudentBO and create mapping between WcfStudent and StudentBO or use some tool for example Automapper.
If you're totally new in WCF please read about DataContract, DataMember.
Good luck!
UPDATE
Speaking about your comment would be better something like:
public WcfStudent(MyStudent myStudent)
{
this.Id= myStudent.Id;
this.Name= myStudent.Name;
}
Your WCF Service will contain the definition of your WcfStudent class, and it will define that class as a Data Contract (if you are not using separate DTOs).
Referencing the WCF Service in your client project, either via a WSDL file or via the Visual Studio interface, gives your client application visibility or knowledge on the public classes, interfaces, and whatnot of the Service. This should include the WcfStudent class. You can then proceed with utilizing this in your code through something like:
MyWcfService.WcfStudent student = new MyWcfService.WcfStudent();
//assign values, etc
Manipulate that student object inside your application as you see fit, and then call your web service when you are ready to persist.
client.InsertStudent (student);
You would typically use data contracts instead of individual parameters, because then you can easily version them; and extend them easily with additional optional parameters and still be backwards compatible.
Personally I like to follow the request/response pattern consistently:
public InsertStudentResponse InsertStudent(InsertStudentRequest request)
{
}
If you don't expect a result, the response type could be void of course.
The request object contains only what you need in order to complete te request. Nothing more, nothing less. For example, if you want to change the address of a student, don't call ModifyStudent while passing all student properties, but call MoveStudent and pass only the new address information; so that you have clearly defined business operations.
Concerning the naming of your operations, InsertStudent is a CRUD-like naming, while I prefer to name them in business terminology, like RegisterNewStudent or something.
Also don't forget about fault contracts: don't throw exceptions, throw faults.
In our MVC project we are attempting to make everything as generic as possible.
Because of this we want to have one authentication class/method which covers all our methods.
As a example: The following code is a MVC class which can be called to from a client
public class Test
{
public void Test()
{
}
public int Test2(int i)
{
return i
}
public void Test3(string i)
{
}
}
A customer of our webservice can use a service reference to get access to Test(), Test2() and Test3().
Now i'm searching for a class, model, interface or anything else which I can use to alter the access to the method (Currently using [PrincipalPermission] attribute) as well as alter the parameter value.
Example:
Customer A calls Test2(150)
The class/method checks whether Customer A has access to Test2. The class/method validates the user but notices that the user does not have access to 150. He only has access to 100.So the class/method sets the parameter to 100 and lets it follow through on it's journey.
Customber B class Test()
The class/method checks whether Customer B has access to Test. After validation it shows that the user does not have access so it throws a SecurityException.
My question:
In what class, interface, attribute or whatever can I best do this?
(ps. As example i've only used authentication and parameter handling, but we plan to do a lot more in this stage.)
Edit
I notice most, if not all, assume I'm using actionResults. So i'd like to state that this is used in a webservice where we provide our customers with information from our database. In no way will we come in contact with a ActionResult during the requests to our webservice. (Atleast, not our customers)
Authentication can also be done through an aspect. The aspect oriented paradigm is designed to honor those so-called cross-cutting concerns. Cross-cutting concerns implemented in the "old-fashioned" oo-way make your business logic harder to read (like in Nick's example above) or even worse to understand, because they don't bring any "direct" benefit to your code:
public ActionResult YourAction(int id) {
if (!CustomerCanAccess(id)) {
return new HttpUnauthorizedResult();
}
/* the rest of your code */
}
The only thing you want here is /* the rest of your code */ and nothing more.
Stuff like logging, exception handling, caching and authorization for example could be implemented as an aspect and thus be maintained at one single point.
PostSharp is an example for an aspect-oriented C# framework. With PostSharp you could create a custom aspect and then annotate your method (like you did with the PrincipalPermissionAttribute). PostSharp will then weave your aspect code into your code during compilation. With the use of PostSharp aspects it would be possible to hook into the method invocation authenticating the calling user, changing method parameters or throw custom exceptions (See this blog post for a brief explanation how this is implemented).
There isn't a built-in attribute that handles this scenario.
I find it's usually best to just do something like this:
public ActionResult YourAction(int id) {
if (!CustomerCanAccess(id)) {
return new HttpUnauthorizedResult();
}
/* the rest of your code */
}
This is as simple as it gets and easy to extend. I think you'll find that in many cases this is all you need. It also keeps your security assertions testable. You can write a unit test that simply calls the method (without any MVC plumbing), and checks whether the caller was authorized or not.
Note that if you are using ASP.Net Forms Authentication, you may also need to add:
Response.SuppressFormsAuthenticationRedirect = true;
if you don't want your users to be redirected to the login page when they attempt to access a resource for which they are not authorized.
Here's how I've made my life simpler.
Never use simple values for action arguments. Always create a class that represents the action arguments. Even if there's only one value. I've found that I usually end up being able to re-use this class.
Make sure that all of teh properties of this class are nullable (this keeps you from running into default values (0 for integers) being automatically filles out) and thatallowable ranges are defined (this makes sure you don't worry about negative numbers)
Once you have a class that represents your arguments, throwing a validator onto a property ends up being trivial.
The thing is that you're not passing a meaningless int. It has a purpose, it could be a product number, an account number, etc. Create a class that has that as a property (e.g An AccountIdentifier class with a single field called 'id). Then all you have to do is create a [CurrentUsedCanAccessAccountId] attribute and place it on that property.
All your controller has to do is check whether or not ModelState.IsValid and you're done.
There are more elegant solutions out there, such as adding an action filter to the methods that would automatically re-direct based on whether or not the user has access to a specific value for the parameter, but this will work rather well
First, just to say it, that your own methods are probably the most appropriate place to handle input values (adjust/discard) - and with the addition of Authorize and custom filter actions you can get most done, and the 'MVC way'. You could also go the 'OO way' and have your ITest interface, dispatcher etc. (you get more compiler support - but it's more coupled). However, let's just presume that you need something more complex...
I'm also assuming that your Test is a controller - and even if it isn't it can be made part of the 'pipeline' (or by mimicking what MVC does), And with MVC in mind...
One obvious solution would be to apply filters, or action filters via
ActionFilterAttribute
Class
(like Authorize etc.) - by creating your own custom attribute and
overriding OnActionExecuting etc.
And while that is fine, it's not going to help much with parameters manipulation as you'd have to specify the code 'out of place' - or somehow inject delegates, lambda expressions for each attribute.
It is basically an interceptor of some sort that you need - which allows you to attach your own processing. I've done something similar - but this guy did a great job explaining and implementing a solution - so instead of me repeating most of that I'd suggest just to read through that.
ASP.NET MVC controller action with Interceptor pattern (by Amar, I think)
What that does is to use existing MVC mechanisms for filters - but it exposes it via a different 'interface' - and I think it's much easier dealing with inputs. Basically, what you'd do is something like...
[ActionInterceptor(InterceptionOrder.Before, typeof(TestController), "Test1")]
public void OnTest1(InterceptorParasDictionary<string, object> paras, object result)
The parameters and changes are propagated, you have a context of a sort so you can terminate further execution - or let both methods do their work etc.
What's also interesting - is the whole pattern - which is IOC of a
sort - you define the intercepting code in another class/controller
all together - so instead of 'decorating' your own Test methods -
attributes and most of the work are placed outside.
And to change your parameters you'd do something like...
// I'd create/wrap my own User and make this w/ more support interfaces etc.
if (paras.Count > 0 && Context.User...)
{
(paras["id"] as int) = 100;
}
And I'm guessing you could further change the implementation for your own case at hand.
That's just a rough design - I don't know if the code there is ready for production (it's for MVC3 but things are similar if not the same), but it's simplistic enough (when explained) and should work fine with some minor adjustments on your side.
I'm not sure if I understood your question, but it looks like a model binder can help.
Your model binder can have an interface injected that is responsible for determining if a user has permissions or not to a method, and in case it is needed it can change the value provided as a parameter.
ValueProviders, that implement the interface IValueProvider, may also be helpful in your case.
I believe the reason you haven't gotten ay good enough answer is because there are a few ambiguities in your question.
First, you say you have an MVC class that is called from a client and yet you say there are no ActionResults. So you would do well to clarify if you are using asp.net mvc framework, web api, wcf service or soap (asmx) web service.
If my assumption is right and you are using asp.net mvc framework, how are you defining web services without using action results and how does your client 'call' this service.
I am not saying it is impossible or that what you may have done is wrong, but a bit more clarity (and code) would help.
My advice if you are using asp.net mvc3 would be to design it so that you use controllers and actions to create your web service. all you would need to do would be to return Json, xml or whatever else your client expects in an action result.
If you did this, then I would suggest you implement your business logic in a class much like the one you have posted in your question. This class should have no knowledge of you authentication or access level requirements and should concentrate solely on implementing the required business logic and producing correct results.
You could then write a custom action filter for your action methods which could inspect the action parameter and determine if the caller is authenticated and authorized to actually access the method. Please see here for how to write a custom action filter.
If you think this sounds like what you want and my assumptions are correct, let me know and I will be happy to post some code to capture what I have described above.
If I have gone off on a tangent, please clarify the questions and we might be one step closer to suggesting a solution.
p.s. An AOP 'way of thinking' is what you need. PostSharp as an AOP tool is great, but I doubt there is anything postsharp will do for you here that you cannot achieve with a slightly different architecture and proper use of the features of asp.net mvc.
first create an attribute by inheriting from ActionFilterAttribute (system.web.mvc)
then override OnActionExecuting method and check if user has permission or not
this the example
public class CheckLoginAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (!Membership.IslogedIn)
{
filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary
{
{ "area",""},
{ "action", "login" },
{ "controller", "user" },
{ "redirecturl",filterContext.RequestContext.HttpContext.Request.RawUrl}
});
}
}
}
and then, use this attribute for every method you need to check user permission
public class Test
{
[ChecklLogin]
public void Test()
{
}
[ChecklLogin]
public int Test2(int i)
{
return i
}
[ChecklLogin]
public void Test3(string i)
{
}
}
This is a question about web api design. Let's say I have an method that returns a city and city properties, like population, FIPS code, and region. There are more properties, often 20+.
In some cases, I'll submit a FIPS code and expect a city name to be returned. Other times, I'll submit a FIPS code and expect a few other properties to be returned (maybe region and population).
My question is, how should I build my controllers and actions for these scenarios? Should I have one controller, named City, and a series of methods to return exactly what I need or should I use multiple controllers?
I'm fairly new to web api design but it feels cleaner to have a single controller. My thoughts are a controller, named City, with appropriately named actions, like GetNameAndPopulationFromFipsCode() or something similar.
The resource is the same so really it would normally be the same controller.
I see 2 natural ways to implement this:
Content-negotiation
client to pass an optional parameter to get a full viewmodel
First is more RESTful but can be a bit of pain, considering current key-based conneg in Web API.
Second is easier to implement:
// almost pseudocode !!
// called by /api/City/123?extended=true
public City Get(int id, bool? extended)
{
ExtendedCity city = GetCity(id);
return extended.HasValue && extended.Value ? MapTo(city) : city;
}
// ----
public class City
{
...
}
public class ExtendedCity : City
{
...
}
UPDATE
As #Darrel pointed out, query string parameter changes the resource. But in terms of resource organisation, it maintains the hierarchy and that is why is the preferred approach.