Passing Validation exceptions via WCF REST - wcf

I am using WCF and REST, and I have complex types, which are working fine. Now I need to check for validation, I am thinking of using DataAnnotations e.g.
public class Customer
{
[Required]
public string FirstName {get;set;}
}
Now where the issue is how do I pass this validation down to the REST service?
ALso I need to validate the object when it comes back, and throw an exception, if I am to throw an exception then what is the best way of doing this using REST?

I would use the Validation Application Block included in the Microsoft Enterprise Library to validate the data transfer objects being used in the service interface. You can use attributes to decorate the objects' properties with validation rules, much in the same way as with the ASP.NET Data Annotations.
In case validation fails you should return an appropriate HTTP Error Code and include the details of what went wrong in the HTTP response.
Here is an example:
public void PostCustomer(Customer instance)
{
ValidationResults results = Validation.Validate(instance);
if (!results.IsValid)
{
string[] errors = results
.Select(r => r.Message)
.ToArray();
WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.BadRequest;
WebOperationContext.Current.OutgoingResponse.StatusDescription = String.Concat(errors);
}
// Proceed with custom logic
}
If you are using the WCF REST Starter Kit, you should instead throw a WebProtocolException, as described in this article.

I would look into writing a custom IDispatchMessageInspector implementation where, in the AfterReceiveRequest method, you manually invoke the validation architecture.
I won't go into the details of how to call the Data Annotations validation architecture as I'm sure you can find that somewhere online if you don't already know how to do it. That said, once you have your validation results you can enumerate them and then, if there are any failed validations, you can throw a generic validation fault filled with the details from the AfterReceiveRequest implementation.

Related

Accessing Endpoint from ExceptionMapper in Jersey

I'm puzzled on how would I be able to fetch the current request handler (org.glassfish.jersey.server.internal.process.Endpoint) in an ExceptionMapper... Take a look at following code...
public class ValidationExceptionMapper implements ExceptionMapper<ValidationException> {
#Override
public Response toResponse(ValidationException exception) {
// Here I would like to know which endpoint triggered this exception...
}
}
Handling of the exceptions would be based on what kind of annotations were present on the input data that failed validations.
Jersey's Endpoint seems to have all the information that I might need. I would prefer to use any option that JAX-RS conforms to. But at this point, I'm ready to look for any alternatives.
Note: I did look at ConstraintViolation.getRootBean()... It points out at the resource rather than at the method that gets invoked... I'm interested in fetching the endpoint rather than just the resource.
Thanks in advance!

How to use FluentValidation to display UI error for either or fields

I have an MVC 3 app which uses FluentValidation to express validation logic on some ViewModel objects.
One of the objects has two properties as follows:
[DisplayNameAttribute(UiConstants.Telephone)]
public string Telephone { get; set; }
[DisplayNameAttribute(UiConstants.Email)]
public string Email { get; set; }
The rule is that EITHER of these properties must be entered at the UI and I want the UI to display a validation message for at least one of the fields (Email) when the user hits Submit but without doing a PostBack.
I can get the validation to work with the following code in the validator
RuleFor(contact => contact.Email)
.Must((contact, email) => string.IsNullOrWhiteSpace(email) != string.IsNullOrWhiteSpace(contact.Telephone))
.WithMessage(ValidationConstants.EmailOrTelephone);
and this will display my validation error message at the UI, but only after a PostBack.
I have also used a Custom Validator as follows
Custom(contactUs =>
{
return string.IsNullOrWhiteSpace(contactUs.Telephone) && string.IsNullOrWhiteSpace(contactUs.Email)
? new ValidationFailure("Email", ValidationConstants.EmailOrTelephone)
: null;
});
but this behaves in the same way.
Will this not work the way I am hoping?
Is there another way to do the validator to get the error message to display in the UI without doing a PostBack?
I know that I could also use DataAnnotations but I specifically want to do this with FluentValidation.
Many thanks
Brian
You're looking for client-side validation - this isn't specific to FluentValidation or DataAnnotations. Both mechanisms will work server-side automatically (you have to wire FluentValidation up to do this automatically after model binding, or run it manually).
If you want client-side validation with ASP.NET MVC, you'll also have to wire that bit up. This blog entry may help.
One note though - your Custom validator won't work by default (you'd have to replicate that validation in jQuery on the client). Check out this article on FluentValidation; here's an excerpt that shows what validators should "just work" client-side without rewriting your own:
Note that FluentValidation will also work with ASP.NET MVC's
client-side validation, but not all rules are supported. For example,
any rules defined using a condition (with When/Unless), custom
validators, or calls to Must will not run on the client side. The
following validators are supported on the client:
*NotNull/NotEmpty
*Matches (regex)
*InclusiveBetween (range)
*CreditCard
*Email
*EqualTo (cross-property equality comparison)
*Length

Better Practice for Error handling from WCF

I have a class library that communicates with my WCF service. The class library can then be used in any of my applications. I am curious as to what would be the best practice in handling the errors. I have thought of two scenarios but wanted to get some feedback from the community. The idea is not only to make sure it's appropriate for .NET solutions, but any other language that might not use the dll but rather call the service directly via a SOAP style call.
Option #1
Create a result object which will return to the caller API. Such as.
Public abstract BaseResponse
{
[DataMember]
Public bool IsSuccess { get; set;}
[DataMember]
Public string ErrorMsg { get ;set ;}
}
Public GetProductResponse : BaseResponse
{
[DataMember]
Public Product p { get;set;}
}
Option #2 : Throw a SOA Fault and allow the end user handle it however they choose. I could handle it in my API - however a direct call to the service would require that end user to code against the fault and handle it correctly.
Typically what I end up doing is having a business layer that will throw application specific exceptions. In the event that I want to expose this as a web service, I'll put a very thin layer on top of that that exposes those business services as WCF services. This layer will do nothing more than pass calls down to the business layer and return results as DataContract or MessageContract objects. In this very thin WCF layer, I'll catch exceptions from the business layer and map them to SOAP faults. This allows any .Net application to consume the business layer directly and catch exceptions as well as .Net or non-.Net applications to consume the web service and catch SOAP faults.
I usually use Option 2 (soap faults, WCF FaultContracts) then I am doing an internal service, where I know the client is also WCF, and I can make sure FaultExceptions are handled correctly.
When I am making an external/customer-facing service, I usually use option 1, splitting up my message into a "header" and a "body" and have the header contain an error message. I find this easier for other people to understand when telling them how to use your web service, and easier for non-WCF users to implement.
Both ways are fine really, as any decent SOAP tool for whatever language should handle SOAP faults, but you never know...
If you are building a restful webservice yo could use the http status code. And regardless of the service flavour the error handlers in WCF makes the code substantially more readable since it allows a single try/catch definition for methods.
There is a simple example here http://bit.ly/sCybDO
I would use option #2 every time. Faults are a standardised part of the SOAP specification, so any compliant framework should handle them appropriately. If a client is using a framework that doesn't have built in handling, then they will have to write custom code to do it, but that is the case with option #1 anyway, since they will have to understand your custom error semantics.
Unless there is a really good reason, I would always used the standardised approach - it give you the best chance of interoperability.

WCF - Catching faults on the server and returning custom types instead

We are trying to figure out a way to modify WCF service behavior to catch all exceptions and instead of returning faults to the client, it will populate a custom return object with exception data and return that. So far, we haven't had much luck. I found this example: Catching custom faults
However, it doesn't return custom types as we would like it to. What other options are there?
Thanks!
If you want to have an interoperable and "by-the-standard" service, you should always return FaultException<T> SOAP faults from your service to the client.
Since that type takes a generic <T>, you can basically put anything into that type there to report back your errors. That type needs to be decorated with a [DataContract], and its members that need to be passed back with [DataMember] attributes.
[DataContract]
public class MyErrorInfo
{
[DataMember]
public int ErrorCode { get; set; }
[DataMember]
public string ErrorMessage { get; set; }
}
When you catch those execptions on the service side and return a FaultException<MyErrorInfo> (or whatever you'll end up calling your error class), you also need to decorate your operations with a
[FaultContract(typeof(MyErrorInfo))]
[OperationContract]
public SomeType SomeMethodCall(SomeType parameter);
so that your clients will be able to catch the FaultException<MyErrorInfo> and handle it.
I referred to this article in another answer, but it may help you as well..
WCF Exception Handling
the article is Simplifying WCF: Using Exceptions as Faults
I wrote a blog post on this exact topic after we encountered this in our own project. Basically, we chose to return the same object type so we can attach a single listener delegate to all events to globally handle certain errors (like a user losing the permissions to an org.)
I hadn't thought of using FaultException but I will examine how we might do that. This design was WCF Service (.NET 3.5) running inside SharePoint 2007 and consumed by Silverlight 4.

Flowing WCF Role-Based Security through to UI

I am looking for some best practices on how to handle the following scenario - flowing permissions from WCF service layer through to UI:
I have WCF services with methods that have been decorated with the PrincipalPermission attribute. I would like a means to allow a client to check if they have the required permissions before invoking the method.
A basic example of this could be checking whether a user can perform a specific function (say submitting an order), which can then be used to enable/disable a button within the UI.
Possible options are to add "chatty" operations like bool CanSubmitOrder() to the service, or instead have a single method OrderServicePermissions GetPermissions() which returns a message with a property CanSubmitOrder? I can then set the enabled state of a "Submit Order" button to the result.
So does anybody know of a better approach, or even a best practice?
Thanks in advance!
The whole point of having PrincipalPermission attributes on your service calls is that you don't have to check ahead of time whether or not the caller has the rights to call - if he doesn't, the WCF runtime will throw an exception.
Why not just rely on this built-in mechanism? Why not just put your service calls in a try..catch block and handle the exceptions if they do actually occur? It should be the "exceptional" case anyway, right?
I don't see any other "magic" way besides what you described. But the generally accepted practice would be to call and handle any exceptions if they occur.
Marc
Well, if you are able to evolve your applications to use Windows Identity Foundation (WIF) to secure your services you could achieve this using the DisplayToken property of the RequestSecurityTokenResponse.
http://msdn.microsoft.com/en-us/library/microsoft.identitymodel.protocols.wstrust.requestsecuritytokenresponse.requesteddisplaytoken.aspx
Assuming your security token service supported it, the display token could contain a claim set that would allow you to flow your permissions into the UI, say to disable controls that are bound to services the user cannot call. The display token is an extension to WS-Trust that was implemented for CardSpace so it it not likely to be very widely supported outside of the Windows world.
Be aware though, that some people think the display token is bad news and violates the 1st law of identity:
http://www.francisshanahan.com
While other people think it is a reasonable and pragmatic solution to a common problem:
http://blogs.msdn.com/b/vbertocci/archive/2007/10/31/on-displaytoken.aspx
There are two general type to implement checking logic:
Share library. Example is "RIA Services + Silverlight".
Pluses: simple to implement.
Minuses: no interoperability (only .NET); required client update for every library changing.
Implement common method validation in service part.
Pluses: interoperability, no need for client update if checking logic changed
Minuses: may be to complex because it is only on you
If we use SOA it is better to use second choice, if only you are not using applications only in your company where .NET is everywhere.
Example
Let us consider common example. We have a windows/wpf form. And there are two fields: "surname" of type string, "age" of type int; and a button "Save". We need to implement some check on client side
1) for some users button "Save" is disabled;
2) surname cannot be empty and max length is 256;
3) age cannot be less than 0;
Invoking method to save is
void Save(string surname, int age);
Create second method in the service, which return object type of PermissonAnswerDTO with validation information;
PermissonAnswerDTO SaveValidate(string surname, int age);
and main validation method
// If arguments are wrong
[FaultContract(typeof(NotSupportedException))]
// If the user have permisson to invoke this method
[FaultContract(typeof(CustomNotEnoughPermission))]
PermissonAnswerDTO Validate(string methodName, object[] methodParams);
Validation.
Invoke Validate("SaveValidate", null) on window loading. If exception of type CustomNotEnoughPermission is throwed then we block "Save" button.
If user can save then invoke user's data Validate("SaveValidate", object[2]{"Surname", "-60"};. -60 is not valid so we get answer object of type PermissonAnswerDTO with information:
ParameterName: "age",
ExceptionMessage: "age cannot be less then null".
And we can gracefully show this information to user.
My thought on this is that some day Microsoft will implement this and call as new technology as it always does. Mostly Microsoft's technologies really are not so revolutionary as it is advertised. Examples are Windows Identity Foundation and Reactive Extensions.
Full example
[DataContract]
public class ParameterExceptionExplanaitonDTO
{
[DataMember]
public string ParameterName;
[DataMember]
public string ExceptionMessage;
}
[DataContract]
public class PermissonAnswerDTO
{
[DataMember]
public bool IsValid;
[DataMember]
public ParameterExceptionExplanaitonDTO[] ParameterExceptions;
}
public class Service1 : WcfContracts.IService1
{
// If arguments are wrong
[FaultContract(typeof(NotSupportedException))]
// If the user have permisson to invoke this method
[FaultContract(typeof(CustomNotEnoughPermission))]
public PermissonAnswerDTO Validate(string methodName, object[] methodParams)
{
//1) Using Reflection find the method with name = <methodName + Validate>
//2) Using Reflection cast each object in "object[] methodParams" to the required type
//3) Invoke method
}
private PermissonAnswerDTO GetUserNameValidate(int id)
{
//logic to check param
}
public string GetUserName(int id)
{
// if the user calls method we need validate parameter
GetUserNameValidate(id);
//some logic to retreive name
}
}