ASP.Net Web API Help Pages: Ignore certain properties - asp.net-web-api

Is it possible to have the Help Page sample generator ignore certain properties of a particular type?
For example, we use the same DTO for object Request and Response messages, for both POST and PUT requests. When user is POSTing a model (creating a new record) they don't need to provide the ID field.
But once its created and we serialize the new record into the response body, the ID field is included and returned to the client.
So in the POST request sample, I don't want the ID field to be displayed because for post request it doesn't make sense.
But the POST response sample, I do want the ID field displayed...
I am aware that there is the ApiExplorerSettings attribute which can be applied to a Class or Method...but is there anything similar for a Property?
Something like this would be great:
public class MyDTO
{
[ApiExplorerSettings(IgnoreForRequestApi = true, IgnoreForResponseApi = false)]
public int Id { get; set; }
// Other properties omitted for brevity...
}

Using the following annotation I've successfully hidden a property from the generation!
[ApiExplorerSettings(IgnoreApi = true)]

No, there isn't a similar option for a property. HelpPage uses formatter instances configured on the application to serialize the samples and as you can imagine the formatters must not have this knowledge within themselves.
Regarding workarounds:
a. You could explicitly set the raw sample for a particular action's requestsample via the SetSampleRequest extension of HttpRequestMessage. You should be able to see some examples about this in the file at *Areas\HelpPage\App_Start\HelpPageConfig.cs*.
b. In the file Areas\HelpPage\SampleGeneration\HelpPageSampleGenerator.cs, there is a method called WriteSampleObjectUsingFormatter which uses the application's formatter instances to write the samples. Here you would need to create new formatter instances having similar settings as your normal application has(so that they reflect the exact serialization/deserialization semantics that your application would normally react to when actual requests are made) and then try to hide the properties which you want to. We want to create new instances because we do not want to disturb the normal functioning of the application.
Example: In case of Json, you could create a new Json formatter instance and provide a ContractResolver which can hide the properties. Check this link: http://james.newtonking.com/projects/json/help/html/ConditionalProperties.htm
In case of Xml, I am not sure how we can hide properties without using the IgnoreDataMember attribute and also being non-intrusive.
Currently I would prefer option 'a' as its comparatively a simple workaround than 'b'.

ASP.NET WEB API uses Json.NET for JSON and DataContarctSerailizer for XML formatting so if you add [JsonIgnore] annotations over properties that you do not want included in your serialization should work just fine.

Related

Veracode issue CWE 915

I'm having a POST method in my ASP.NET core web API which takes a model as a parameter (binding POST content directly to model). The model contains all the parameters as optional parameters. While scanning the web service using Veracode, I get flaw-1 with CSE 915 (Insufficient input validation for ErrorReporter Service reasons.) which is the possible scenario for MVC EF application.
I have gone through the article. It is saying to use Bind attribute with Include and Exclude properties. But in my case, I don't have any parameter which is mandatory to pass in the model.
Is there any alternative to resolve this or any attribute using which I can remove the Veracode scan for this specific method in the code itself.
Insufficient Input Validation is caused by using the user input directly to take decisions and it can be overcome by sanitizing the taken input.
var userInput = new Sanitize(userInput).Value;
This Sanitize method could be put in appropriate class of your project
public Sanitize(dynamic input)
{
string inputValue = Convert.ToString(input);
Value = inputValue.Replace("<", "").Replace(">", "");
}

How to know what InputParameters values are possible in Dynamics CRM Plugin context?

I'm trying to understand the plug-in sample from here.
There's this condition:
// The InputParameters collection contains all the data passed in the message request.
if (context.InputParameters.Contains("Target") &&
context.InputParameters["Target"] is Entity)
Speaking generally, not just with regard to this sample, on what prior knowledge should I base my decision to access a specific property? How could I have known to test whether the InputParameters contains a "Target" key (I assume I'm not supposed to guess it)?
And on what basis could I have known to ask whether the "Target" mapped value is of Entity type, and not some other type?
I found this post from 2 years ago, and I've found this webpage, saying (emphasis is mine):
Within a plugin, the values in context.InputParameters and
context.OutputParameters depend on the message and the stage that you
register the plugin on. For example, "Target" is present in
InputParameters for the Create and Update messages, but not the
SetState message. Also, OutputParameters only exist in a Post stage,
and not in a Pre stage. There is no single source of documentation
that provides the complete set of InputParameters and OutputParameters
by message and stage.
From my searchings, a single source still doesn't exist, but maybe the possible values can be found using the Dynamics Online platform, somewhere deep down the Settings menu, maybe? Any source would be great.
I know this is an "old" question that already has been answered, but I think this can be helpful. I've built a small web page that contains all the messages with all the Input/Output parameters. You can access it from here:
The best practice for doing this is to use a strongly typed approach. If, for example, you want to know which propertes are available on a CreateRequest, you would do:
var createReq = new CreateRequest() { Parameters = context.InputParameters };
createReq.Target; // Has type Entity
Take a look at the full blog post explaining this approach: Tip: Proper handling of Plugin InputParameters
Original answer:
It depends on which request we are talking about. See Understand the data context passed to a plug-in on MSDN.
As an example, take a look at CreateRequest. One property of
CreateRequest is named Target, which is of type Entity. This is the
entity currently being operated upon by the platform. To access the
data of the entity you would use the name “Target” as the key in the
input parameter collection. You also need to cast the returned
instance.
Note that not all requests contain a Target property that is of type
Entity, so you have to look at each request or response. For example,
DeleteRequest has a Target property, but its type is EntityReference.
In summary: Look at the actual request, e.g the CreateRequest.
In 2011 someone actually generated typed properties based on the message type. Kind of neat: https://xrmpalmer.wordpress.com/2013/05/27/crm2011-plugin-inputparameter-and-outputparameter-helper/
It would show you want parameters are possible per message.

Set default WebAPI formatter

We are using WebAPI to mimic the handling of a legacy system. As a result, we would like the default response formatter to be the XmlFormatter and not the JsonFormatter. The reason is that some of the existing calls to the service do not supply the Accept: HTTP header field.
I can achieve this by removing the JsonFormatter from the Formatters collection and then re-adding it, forcing it to be at the end of the chain.
This then result in the default format response using the XmlFormatter. Although it works, it just doesn't feel correct, and although I am moving Json to the back of the collection, there is no guarantee that the XmlFormatter is at the front of the collection.
Ideas/thoughts?
Just add formatters in the right order. If ASP.NET Web API finds two formatters for the same content type, it will pick the first one, so it is very important to add formatters in the right order.
//somewhere in Web Api config
config.Formatters.Clear();
config.Formatters.Add(new XmlMediaTypeFormatter());
config.Formatters.Add(new JsonMediaTypeFormatter());
So the default will be XML, the first formatter, but the API still supports JSON if the request asks for it (with appropriate HTTP header).
Finally, another different approach, is to use a custom IContentNegotiator. It will allow you to select the most appropriate MediaTypeFormatter for a given request.
//somewhere in Web Api config
config.Services.Replace(typeof(IContentNegotiator), new MyCustomContentNegotiator());
An example is available here.
This is returned to automatically serialise and return json when content type is json.
var json = config.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
config.Formatters.Remove(config.Formatters.XmlFormatter);
((DefaultContractResolver)config.Formatters.JsonFormatter.SerializerSettings.ContractResolver).IgnoreSerializableAttribute = true;

input validation not working on asp.net mvc 4 model sent as JSON

I have a model and a form in the view. I have a simple field of string which is called description. I'm able to insert scripts like: <script>alert('xss')</script> to that field.
I can see that in other actions on my site with other models I can't
I do not have an AllowHtml or anything like that.
the only difference is that for this model I use a post with a json object and content-type of application/json
the ModelState.IsValid is returning true. even though there is a description property with an xss script on it...
and for the other actions I make a simple ajax post.
why isn't the validation input work on this kind of JSON ajax posts?
how can I prevent xss across the entire site for this kind of ajax requests?
thanks
It is because ValidateInput is only for FormValueProvider. As for JsonValueProvider, you need to roll out your own mechanism.
Steps
1) Create a marker attribute CustomAntiXssAttribute
2) Create a custom model binder by sub-classing DefaultModelBinder
3) Overrides BindProperty method -> get the attempted value for the underlying property, sanitize it and assign it to the view model property.
Check this out.
Edited:
Replace the line var valueResult = bindingContext.ValueProvider.GetValue(propertyDescriptor.Name); with var valueResult = bindingContext.ValueProvider.GetValue((string.IsNullOrWhiteSpace(bindingContext.ModelName) ? string.Empty : bindingContext.ModelName + ".") + propertyDescriptor.Name); in order to support nested ViewModel.
try using AntiXssLibrary from Nuget, and by using getSafeHtmlContent. you can get the safe content while you're saving your records to db.
Another approach is to use a Sanitizer library like this one, you can choose which HTML tags you want to be filtered out.

CakePHP and reusable approach

I would develop my CakePHP application in the most reusable way. I'd like to treat it as webservices, so I don't want to strictly bind controller with view. My idea is: controller just returns json info, the view calls the controller and get the json and make html output.
How can I realize that? Could be a good approch, developing pages rather than views, and inside that pages call the webservices previously developed.
You can even forget about creating view files, using $this->set('_serialize', array('people')); in your PeopleController::show()
Well Cake is kinda' works like this "out of the box". You can use Router::parseExtensions(); to define what type of data you would like to serve. For example in app/Config/routes.php:
Router::parseExtensions('xml','json');
This will make it possible to detect what kind of request is incoming. For example if someone requests:
www.example.com/people/list.json or www.example.com/people/list.xml, in your PeopleController's list() method you'd be able to detect what kind of resource is being requested - json or xml, or of course any other
extension you define. This is what the RequestHandlerComponent is used for. You can check if it is xml for example:
if($this->RequestHandler->isXml()) {
//Some code
}
The different extensions are only different representation of the data, so it shouldn't matter what exactly you're serving. From v2.1 Cake will automatically switch the view class when it sees a JSON or XML request, which takes us to the new JSON and XML views.
All you will have to do is provide the views in the appropriate places.
In View/People (as for this example) you would have:
..View/People/
list.ctp
xml/
list.ctp - XML view
json/
list.ctp - JSON view

Resources