Get operation name in Message Inspector? - c#

Im using the IClientMessageInspector to log in/out messages but the problem is that I canĀ“t find how to get the operation name from AfterReceivedReply and BeforeSendRequest.
I have tested the following :
if ((action = reply.Headers.Action.Split('/').LastOrDefault()) != null)
{
callInformation.Action = action;
callInformation.Address = reply.Headers.Action.Replace(action, "");
}
This works fine in BeforeSendRequest but in the AfterReveivedReply it returns something different, often with the "Response" on the end?
How do I only get the operation name in those methods?
Say, that my operation is named MyOperation and a OperationContract attribute states the action = "MyOpeation" (wrong spelling). This result of this is that MyOpeation will be extracted in BeforeSendRequest while the AfterReceiveReply will return MyOperationResponse.
So the BeforeSendRequest will extract the stated action in the attribute and the AfterReceiveReply will extract the real operation name but with the add of "Response" on the end?
Its important to be able to match the in/out messages and the only way of doing this as I see it is to match the operation names but if that is not possible then I do not see a good solution to this?
I have seen solution when using OperationContext.Current.IncomingMessageHeaders.Action but the OperationContect.Current is null when doing this on the client side.

From your question I assume you want to match In/Out messages by any means - the framework provides for this:
In the implementation of IClientMessageInspector.BeforeSendRequest you can return a unique correlationState which in turn allows you to relate the reply message in your implementation of IClientMessageInspector.AfterReceiveReply since the Framework will call your implementation with it as the second parameter.
EDIT - as per comments below:
IF you really need to get the name of the operation/method called you could do this is by implementing IClientMessageFormatter.SerializeRequest OR IParameterInspector - this will allow you to to record which method with which parameters have been called and what Message object the framework created for it.

Related

Using POST or GET for a WebAPI Action method that returns a list, but requires params

Currently I have the following standard functions in each of my controllers to handle basic CRUD operations:
GET /api/todo Get all to-do items
GET /api/todo/{id} Get an item by ID
POST /api/todo Add a new item
PUT /api/todo/{id} Update an existing item
DELETE /api/todo/{id} Delete an item
However, the time came where I realized I actually need to pass multiple parameters to get a list of todo items that is filtered at the database level rather than retrieving all of the items and using linq.
For example here is how I decided to go about it:
In my Controller:
// POST: api/todo
[HttpPost]
public IList<TodoItem> Get([FromBody]GetTodoItemsRequest request)
{
return _todoItemManager.GetTodoItems(request.Name, request.CategoryId);
}
As you can see I created a new Model called GetTodoItemsRequest which will have a property for each of my parameters. In this case: Name, CategoryId.
I figured when dealing with multiple parameters and retrieving a list it is best to do POST and create a model specifically for it. Rather than using a GET and passing all kinds of information in the url.
It seems a bit strange to be doing the above... Would msot see it as a perfectly fine solution or is there something I am missing in the WebAPI world?
I believe that is semantically incorrect to use POST method for a simple read operation, even if you need a complex model. You are doing a pure query on your resource called todo, and this should really be a GET operation for many reasons:
It should be cachable: POST request aren't cachable by their nature, and caching is an important constraint in RESTful services.
It should semantically indicate that no side-effect will be raised from the call: GET requests must be idempotent and safe, POST operations, instead, indicate some kind of data manipulation. Your operation (filtering) is both idempotent and safe, so it should be spontaneously represented by a GET request.
The part of the URI after a ? character is called query string for a reason: it represent parameters that further specify the scope of a request. Well, isn't filtering results just an example of this approach?
Apart from that, it seems to me that, if Name and CategoryId are required parameters for your query, your filtering operation could be better represented by another URI in which Name and CategoryId are turned into route parameters:
http://yourhost.com/api/users/{name}/categories/{categoryId}/todos
Assuming a relationship between your name parameter (a user name maybe?) and the categories.
If, instead, your parameters are completely optional, then leaving them as query string parameters is the best choice:
http://yourhost.com/api/todos?name=nameValue&categoryId=categoryIdValue
A side note:
you should really use plural for your resources if they represents a collection of items: e.g. api/todo will return an array of todos, so you should rename it into api/todos.

How to Optionally exclude a class member when serializing to XML

I just took over a fairly large project. One of my tasks is to modify the code that gets rate quotes from FedEx. Currently, in order to get a set of rate quotes for a shipment that includes quotes for each "ServiceType" (Ground, 2-day, overnight, etc.) the code makes one call for each type. FedEx offers a web service that is used to get this information. After doing a little research, it looks like this web service can return multiple ServiceType quotes with a single round-trip. To do this, I'm supposed to "leave the service type out of the request." (Here's the question that pointed me in that direction.)
So I know that I can exclude the service type property from the serialization by decorating the property with, [System.Xml.Serialization.XmlIgnoreAttribute()]. But how can I do that only when I want results for all the ServiceType values and still be able to pass a single service type for the cases where I know what shipping method the user wants?
EDIT: FedEx's documentation indicates that this field is optional. Some basic testing shows that excluding it from the request with the XmlIgnoreAttribute does return data for multiple ServiceTypes.
If you implement a public bool ShouldSerializeXXX() function alongside the XXX property being serialized, XmlSerializer will ignore the corresponding XXX property when the function returns false. You'll have to have some basis for setting this (maybe the XXX property can be null? or you can grab some other state to make the decision.)
So, something along these lines:
public class MyClass
{
public ServiceType? ServiceType { get; set; }
public bool ShouldSerializeServiceType() { return ServiceType.HasValue; }
}

Where to format exception message and how to report it to client

In our ASP.NET MVC 5 DDD application, I can't decide where to format exception message and how to correctly report it to client. I care about separation of concerns, DRY and correct REST implementation. In this case, I'm concerned about 4XX exceptions (not logged).
For example, client (via ajax POST) wants to move two items 'ABC' and 'DEF' to folder 'XYZ'. The request goes from controller through service to DAL and exception is thrown in DAL due to DB constrains (e.g., name 'DEF' already exists in target folder - and this exception must originate in DAL, service layer can't deal with concurrency). At the very end, I want to display html-formatted, localized message, such as "Can't move item DEF to XYZ, name DEF already exists." (or as JSON with appropriate data). As a reply, I'd like to return HTTP status code 409, so this message ends up in jQuery's ajax error function. I really don't want to return 200 OK and end up in ajax success function, since it goes against REST principles (this request didn't succeed).
My problem (and question) consists of two parts:
1) where to format the message,
2) how to correctly relay this error message to ajax error function.
I considered (1a) to create MoveItemsException class and set fully formatted message where the exception was thrown (= in DAL) - but I really feel that DAL shouldn't be responsible for HTML formatting of error message, and also that message property should contain only plain text only. This is related question, FormattedException instead of throw new Exception(string.Format(...)) in .NET, but it doesn't solve the question "where" to format the message.
I also considered (1b) to create MoveItemsException class and add appropriate properties to the exception (e.g., DTO or ID of item(s) that caused this exception), keep exception message property empty and format appropriate text in controller based on exception's content. This seems better, but it's not DRY, I'd have to repeat this in each instance where I'd be dealing with this exception. Anyway, this article reasonably advocates this approach: Should you report the message text of exceptions?
And another option (1c) is to implement formatting to the exception class itself, something like exception.FormatMessage(), but unlike in (1b), FormatMessage() wouldn't have access to broader context.
Then, once I have formatted message, I'd like to correctly deliver this error message to ajax error function. I can use (2a)
var message = ...
return new HttpStatusCodeResult(HttpStatusCode.Conflict, message);
This was suggested e.g. here, How to report error to $.ajax without throwing exception in MVC controller?, it would be simple (since I'd get message as errorThrown parameter), but I don't think that HTML-formatted message (or JSON) is actually status description, that much better place for formatted error message is in response text (2b), e.g.:
var message = ...
Response.StatusCode = 409;
Response.Write(message);
return new EmptyResult();
or in this case, I'd create my own ActionResult with similar functionality.
What do you think is the best approach for forementioned scenario?
EDIT:
For now, my solution is to catch specific 4XX exception (with payload) in controller, map the exception to viewmodel, set status code to corresponding status, e.g. Response.StatusCode = 409; and then return partial view for that specific exception return PartialView("_MoveError", moveErrorViewModel);
I can't decide where to format exception message and how to correctly report it to client.
My Opinion:
Giving the end-user an exception message shouldn't happen ever. An exception in a web context means that code is incorrect. This should be logged for an administrator/developer to handle. I would suggest reading Eric Lippert's blog on Vexing exceptions on the types of exceptions and how to handle them.
This doesn't mean that the client should be not aware that something went wrong however. In most cases, it's enough to tell the end user that something went wrong, the company is aware of it and working to correct it. In exceptional cases, you may want to include an incident number (tracked back to the exception logged identifier) on the page if your company needs to contact the client.
When I need to do a ton of ajax, I wrap every single call through a single global function. You can take a look at it in the question: Return partial view if action is ajax or child action universally . Doing this also means that if the authentication ticket expires, you can STILL return nice ajax that can tell your client side to do whatever you want (popup a login modal, redirect to login page, whatever).

Sharing the same message contract for two actions

My services are supposed to parse a SOAP request for an action ILogging/LogMessage which has 'log-entry' as the root element inside the SOAP body. For that, I have a method LogMessage that expects parameter of type LogMessageRequest.
LogMessageRequest has the MessageContract attribute set with WrapperName as log-entry:
[MessageContract(WrapperName = "log-entry")]
public class LogMessageRequest
{
...
}
I am also expecting another SOAP request for an action ILogging/LogException with 'log-entry' as root element in the SOAP body. For this, there's a method LogException and a param of type LogExceptionRequest.
The difference between both the SOAP actions is that a child element 'message' inside 'log-entry' is different (for LogMessage, 'message' is a string and for exception, it's a complex entity).
The issue:
Since both LogMessageRequest and LogExceptionRequest have the same wrapper names (log-entry), I'm getting an exception originating from LogException saying "log-entry has already been exported by LogMessage".
I tried using the same request class for both and have the 'message' of type object. But that refuses to work.
Any pointers? (there's no scope of changing the SOAP request by the way).
While there might be a way to match the different schemas with a common interface, I suggest a more prudent approach: build an adapter over one of the service interfaces to match the interface of the other.
This way, the ugliness is isolated and the application will only have to work with only one service interface.
I don't believe you can implement this using MessageContract/data contract from your description. You might be able to do it with XmlSerializer attributes, but it sounds like you will need to use the Message class in the operation contract and peek at the message xml to figure out which one it is. Can you post the relevant bits of the WSDL/SOAP definitions?

WCF contract for Field level update

I'm developing an application that does some CRUD operations through a WCF service. The read method returns a complete entity, the update is performed through a legacy system, and only the changed values should be updated.
What is the best way to design the data contract for this scenario without simply sending a dictionary of key-value pairs?
The only other thing I can think of is to make your component durable - i.e. persist its state to a file or database. That way, on the update you can compare the previous state to the state being passed in. I'm not sure that's a good way to go since it will introduce more overhead than just passing in the key-value pairs.
From the outside it might look more CRUDy or whatever, but from a practical standpoint you may be better off just passing some indication as to which values changed.
In case it helps, not sure exactly what you're looking for though ...
In the update request, only act upon fields that are not null.
In addition wrap any non-nullable types in a nullable structure.
As an example ...
Update( Nullable<int> orderNumber,
Nullable<DateTime> orderDate,
Nullable<bool> isComplete )
{
if( orderNumber != null )
databaseRecord.OrderNumber = orderNumber;
if( orderDate != null )
databaseRecord.OrderDate = orderDate;
if( isComplete != null )
databaseRecord.IsComplete = isComplete;
}
the best way to do this is with property dictionary, just represent your entities as dictionary of property name and value.
save all changes in some list and pass a partial dictionary with all changed properties.
i think this is best design,
if u wanna avoid this design, send entire entity with some list of changed properties.
(to save transport u can put null on other properties)
if u don't wanna change the service contract signature u can push the names of modified properties on the header
I had two ideas of how to achieve this;
Have the client send both the original entity, and the changed entity in full, the service would then figure out what properties were changed.
Use a pattern similar to Nullable, lets call it Modified with an IsModified flag and a NewValue property of type T. Each property of the DataContract would be of this type, the service can check the IsModified flag when performing the update.
The legacy sytem we use has an api that accepts String.Empty to identify unmodified fields, a '?' character is used to indicate an update to an empty string. I really don't like this, the user of the api is forced to read the documentation, and if you actually want to store a '?' you can't. I want our webservice api to be more explicit.
You can use DataSet to keep your changes. Call your record as DataSet then assign some values to the record. DataSet.Tables[0].GetChanges() will give you the columns which were changed.
You could leave the data contract alone and update your service contract. Just represent the required fields for the method as properties within the service contract. Any consuming application using the service will have to be updated if the service contact changes, but the consuming application will know what is required to successfully update the data.
There are positives and negatives to this method, but I use it when a method I am writing doesn't require the full data contract.
--Edited for a spelling error--
Looking at your requirements and statements, i've made a few assumptions before starting to write my vision on a possible solution:
You are using the same class for retrieving (return value type of "read" operation) and updating an item (input parameter type of "update" operation) in your WCF service.
Your current problem of implementation is how to use the original class (not a dictionary) AND still be able to determine 'what has changed compared to the read' when you get the "Update" operation called on your WCF service
You are writing both the server and client. Both are written using the MS .Net framework.
If this is true, the problem lies in the Update method missing information. The information required is 'has changed' which could be inferred if a 2nd state is present to compare against or should already be present along side the state to update in the back-end.
Since you only have the 'back-end state' (without flags) when the client posts its data to the WCF service, how should we determine what did change? Obviously, we want to prevent another 'read' roundtrip to get the current server state and start comparing.
Sending the original & changed state from the client to the server is a possible but heavy solution. Next to that, the client isn't interrested in this information, the server is.
Adding this all up makes my guess is that changing the type of the 'Update' operation input parameter is the easiest way to go. Create a decorator class that adds 'dirty bit' behavior to the original entity. Use this new class as input parameter for your "Update" operation. You then will have the availability in the server to check this dirty bit next to the full state send by the client. The major change on the client side is that the object needed for the 'Update' operation is no longer the same as the one provided by the 'Read' method. To eleviate this pain, i would probably create a decorator class which added the required 'dirty bit' handling. This only requires the object instanciation to change, while maintaining the interface signature for the client (very little code changes).

Categories

Resources