Optional parameters in ASP.NET web service - asp.net

I have a ASP.NET web service. This web service works fine. However, the WSDL lists some parameters as optional (minoccurs = 0) and others as non-optional. Some of the optional parameters are actually not optional, others which are marked as non-optional are actually optional. I would like to fix this, but I can't find the location where this information is coming from.
It seems to me that all primitive types (int, boolean etc.) are non-optional and all other parameters are marked as optional. However, I can't find a location where I can change this. I would like to specify default values for the primitive values if they are missing in the request and specify which non-primitive parameter is actually optional. Where do I do this?

I am assuming that when you say ASP.net web services, you are creating web services with ASMX extension. I think that what happens in this case is that all nullable types become optional and non-nullable become non-optional.
You could perhaps manually edit the generated WSDL file. But then you would have to redo that work if the wsdl was regenerated.
I would suggest that you switch to WCF with basisHttpBinding (except for the name of you service your clients should not notice the difference).
Using WCF you can simply mark the parameter in the data contract as required or not:
[DataMember(IsRequired="false")]

The primitives are not reference types, but rather they are value types. You can make a value type "nullable" a couple ways.
The short-hand is
int? i;
or long-hand here
Nullable<int> i;

Related

oData v4 - ordering outer entity on property in related one-to-many entities

I have an oData model with a couple of one-to-many relationship, say person->addresses and person->driving-licences. I would like to be able to sort the result set based on properties in the address entity and driving licence entity. As there could be more than one address, I would initially select a single item from the addresses set, based on a property called IsPrimary. As there could be more that one driving licence, I would select the 'UK' driving licence. Is this possible?
I was hoping I could do something like:
/people?$expand=addresses($filter=isPrimary eq true),drivinglicences($filter=country eq 'UK')&$orderby=addresses/postcode,drivinglicences/active
Unfortunately I get the following error:
"The query specified in the URI is not valid. The parent value for a property access of a property 'isPrimary' is not a single value. Property access can only be applied to a single value."
Does anyone know if what I'm trying to do is supported by the spec? Or whether it is an issue with my query? Or whether it is an issue with the .NET library.
I'm using:
Microsoft.AspNet.OData - 7.2.3
Many Thanks.
What you see here is by design, or rather not supported by the specification, the error message even highlights the only type of expressions supported:
The query specified in the URI is not valid. The parent value for a property access of a property 'isPrimary' is not a single value. Property access can only be applied to a single value.
So the simplest solution is to modify the API either to include a Function bound to the people collection that applies the $filter or $order directly, or a Function that returns the data in a new shape, one that only has perhaps a singleton PrimaryAddress property. How you include driving license in this result is up to you, it could even be a parameter to the function, perhaps your people controller has a queryable function with this signature:
[EnableQuery]
public IHttpActionResult WithLicences(string countryCode)
However that is out of the scope of OPs question about specific syntax support
Although it seems like an important feature, we must remember that $select (Projection) and $filter are evaluated at different points in time, OData queries follow a similar execution sequence to SQL however the filter criteria and $orderby are evaluated separately, and the projection of the resultset is the last evaluation to be applied.
Due to $filter and $orderby being applied independently, neither concept is even aware of the other and as such neither can reference or assume to be applied before the other.
You can prove this by specifying a field in the $orderby and/or $filter that is not included in the $select, you can even reference singleton navigation fields that are not included in an $expand and the query will evaluate correctly.
The OData spec is similar to a law document, in that to properly understand and apply it we need to understand the original intent of the authors. We can get an initial understanding from the early listing of Addressing Entities
Addressing Entities describes functions that can be bound to collections or entities that return either a single entity or a collection of entities
By allowing special provision of custom functions to be applied the authors are encouraging API designers to provide natural extensions to their resource endpoints that can facilitate the execution of pre-determined queries that may be otherwise complex or problematic to express in pure OData query syntax.
In other words, we are encouraged to customise our APIs to make them easier for the end process to consume, and to guide the consuming developer to make the best use of the API, they shouldn't have to discover everything from first principals.
To achieve OPs type of query in pure SQL would still require either a nested lookup, CTE or self join... advanced syntax. In OData v4, the specification does not provide a syntax for targeting specific items within a collection for path expressions (of which $orderby derives from)
5.1.1.15 Path Expressions
Properties and navigation properties of the entity type of the set of resources that are addressed by the request URL can be used as operands or function parameters, as shown in the preceding examples.
Properties of complex properties can be used via the same syntax as in resource paths, i.e. by specifying the name of a complex property, followed by a forward slash (/) and the name of a property of the complex property, and so on,
Properties and navigation properties of entities related with a target cardinality 0..1 or 1 can be used by specifying the navigation property, followed by a forward slash (/) and the name of a property of the related entity, and so on.
If a complex property is null, or no entity is related (in case of target cardinality 0..1), its value, and the values of its components, are treated as null.
RE: I couldn't find anything explicit in the spec. :)
That is the very thing about the OData specification,the specification does not list what is not supported, only what should be supported. So by omission, if you cannot find a reference to how to do something, then that something is not required to be supported.
Introduction http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part2-url-conventions.html#sec_Introduction ... This specification defines a set of recommended (but not required) rules for constructing URLs to identify the data and metadata exposed by an OData service as well as a set of reserved URL query string operators, which if accepted by an OData service, MUST be implemented as required by this document.
This has been on ongoing discussion held in may threads, recently https://stackoverflow.com/a/55324393/1690217
Many people complain that this is surely a fundamental feature of a data access platform, however it is important to respect the original intent of the OData platform and keep our APIs simple by providing customised endpoints to suit our business domain.

What is the point of #WebInitParam?

#WebInitParam is an annotation that goes at class level.
It defines initialization parameters for the servlet.
I would like to know, what is the difference between doing this and using static variables, and why do it the #WebInitParam way rather than using statics?
What does defining k/v pairs as #WebInitParams allow you to do that you couldn't do if you declared static variables instead?
I have looked and all I can find is a million people saying how to define #WebInitParams. Well yes that's the easy bit. It's what I can do with that that is really what is of interest.
Thanks very much.
From a "raison d'etre" perspective, the annotation exists as a better design and architecture alternative to just peppering a class with static fields. #WebInitParam is a self-documenting approach to the initialization parameters a servlet or filter class needs, available via web.xml as well. It serves this purpose for the end developers as well as the JavaEE platform as a whole.
Think about it this way: in a vanilla project, you have the option of hardcoding a bunch of parameters in the class as static fields, or defining the same parameters in a property file. Which would you pick? Under what circumstances?
From a purely functional angle, apart from the function of using the annotation to override defaults set in web.xml, one other major reason is that you will sometimes need to get a hold of those initialization parameters from another component in your application. Using the annotation essentially increases the visibility of the parameter. In JSF for example, the API allows you to retrieve FacesServlet initialization parameters with:
//get all the parameters
FacesContext.getCurrentInstance().getExternalContext().getInitParameterMap()
//get a specific parameter
FacesContext.getCurrentInstance().getExternalContext().getInitParameter("aParameter");
In JSF-2.3 , it gets even more convenient with the following CDI-enabled injection:
#InitParameterMap Map<String,String> servletParameterMap;
Bear in mind that because it's CDI, it means this facility is available throughout the JavaEE platform, not just in web applications/JSF.
It's going to be a hassle to retrieve init parameters if the only mechanism available is a static field in the servlet class - you'll need to obtain an instance of the filter or servlet to get the static fields in it.
Separately, one could make the argument that maybe one should favour context-params over servlet-params because then, you get even more flexibility that isn't tied to any given servlet. That's a separate matter entirely :)

asp.net membership config specification

I'm looking at the ado.net ef membership provider and notice they have something a little different to register the provider
type="OmidID.Web.Security.EFMembershipProvider`2[
[OmidID.Web.Security.Default.DefaultUser,
OmidID.Web.Security.EFMembershipProvider],
[System.Int64]], OmidID.Web.Security.EFMembershipProvider"
I've never seen the bits in square brackets before and took a look around and can't seem to find what they allude to, I'm guessing its setting the type of user but I'm not sure.
Is this configuration specified somewhere? what does it mean?
The type is Generic, the square brackets indicate what types the generic type should be used with. In this case the EFMembershipProvider class has 2 generic parameters that should have the types OmidID.Web.Security.Default.DefaultUser in the Assembly OmidID.Web.Security.EFMembershipProvider and System.Int64. The EFMembershipProvider class itself is in the Assembly OmidID.Web.Security.EFMembershipProvider.
See the MSDN documentation on GetType for more information on how to express generic type names as strings.

Optional Invalid Query String Variables

This is a somewhat philosophical issue. I have a .net (but could be any platform) based helper library that parses query string values. Take for example a variable that returns an Int32: my framework has an option that specifies whether this value is required or optional. If it is required but not provided, the framework throws an exception. If it is optional and not specified, it returns a null.
Now an edge case has come up based on users hacking (in a good way) our urls. If they specify a variable with either an invalidly formatted Int32 ("&ID=abc") or provide the variable but not specify a value ("&id="), should the framework throw an exception or should it return a null?
Part of me feels that invalid variables or formats should return a null. It might be valid to argue that even if the parameter is optional, an invalidly formatted query string or value should still throw an exception.
Thoughts?
Since this is philophical ...
On something like an ID, I would agree with Shawn that it is a 404, especially if you are thinking in terms of state. There is no object, so not found. But, ID may not tie directly to a resource in all cases.
If the item is truly optional, a null is okay. But optional should mean "if present it makes the call more specific" in this case and there should always be a fallback. I don't see this in ID, unless the ID is keyed to an optional part of the page.
In the long run, I think you should look at the business reason for the page and what each variable means.
I believe that if a variable is optionaly, providing the variable but not specifying the value is equivalent to ommitting the variable itself. In this case, returning null seems OK.
However, providing an invalidly formatted value ought to cause an Exception, since the intent was to provide a value. In this case the user ought to be notified through some sort of validation mechanism.
A HttpException of 404 (Not Found). Your web application framework should know how to catch these errors and redirect to the proper page.
This is actually a not found error because the resources that the ID is pointing to does not exist.
I suspect there's no "right" answer to your question. If I were a developer using your library, I would expect/hope that the public API would include in its code comments, a description of how the function behaves when the URL param includes bad (wrong type) data.
You might also be able to craft your public API to get the best of both worlds: .NET seems to have adopted the "Parse" / "TryParse" approach in many places. If I'm the caller and I want the function to throw if given invalid data, I call Parse(). If I don't want it to throw, I call TryParse(). In my opinion, that is a nice pattern to follow with your API as well.

Accessing resource strings with CultureInfo in .NET

Another simple questions.
I have website with different languages. If I want to access a string from the resource file I would use it like this
Resources.MyResourceFile.MyStringIdentifier
Very easy. That way I know during compile time, that the resource string exists.
Now, this works only if I want to use the current Culture. Sometimes I need to specify a specific culture (let's say that the current user uses German as a language, but his action triggers messages to be sent to other users which will be in the recipient's language). Now, I see two options:
Resources.MyResourceFile.ResourceManager.GetString("MyStringIdentifier", neededCulturInfo)
The other would be to change the current thread's culture info which I would need to do several times.
Is there a third way? Something which tells me at compile time that the resources exist but without the need to change the thread's culture all the time?
(For your scenario) the idea of the ResourceManager is to provide culture specific informations at runtime not at compile time (aka side-by-side with fallback).
So the answer is "NO", there isn't a buildin way to determinate the existance of those resource files at compile time - to do so you would require a kind of "hard coding" for all strings in every single langauge and also code to access to those. The side by side idea is exactly the opposite of hardcoding ;)
What you could do, is writng a unit test for the resources, that itterates your langauges and checks if the default or a localized value was used. Further if you are using a source control system that provides check-in policies (e.g. TFS) you could this unit test as part of the check-in policy.
Have you tryied :
public static Object GetLocalResourceObject (
string virtualPath,
string resourceKey,
CultureInfo culture)
Try this link Click here
You can also try:
public static Object GetGlobalResourceObject (
string classKey,
string resourceKey,
CultureInfo culture)
Try this link Click here
ResourceSet has a method
public virtual IDictionaryEnumerator GetEnumerator()
that gives access to key-value pairs of the resource file.
E.g. (assuming we deal only with strings - N.B. the key-value pairs are of type object):
while (set.MoveNext())
{
string key = (string)set.Key;
// string value = (string)set.Value;
string value = ResourceManager.GetString(key, neededCulturInfo);
}
This is not what you should do, because things become complicated - just to point it out.
You could create different resource files for different cultures and use a switch code block in a method that has a CultureInfo as parameter.
You construct a class that looks inside the resource or use the Enumerator solution,look for the value and if it does not exist, make it use the value in the default language.
But in compile time, it cannot be verified.
The easiest option is a try-catch and return the value in the general language in the catch.
Nevertheless, if we are using resources, all the keys must always be present in all the related files, even if you copy them with the general language values.
My solution is what it should be, all the resources should be consistent, if not we are using this great tool badly.
The generated Resources.MyResourceFile class has a static Culture property, which you can set to neededCultureInfo to override the current thread's CurrentUICulture.
1) At the start maybe could be useful to store the UICulture into a session, in order to change it when you want, at the begin you can change it from there.
2) You can override the UICulture in preRender and set it from there and than storing it into session.
You can store it in a cookie as well but is not the best solution for it.
You can use WorkItems to send the messages asynchronously. Since you're now running on a different Thread, you should be able to modify the CurrentUICulture as needed.
P.S.: this is a good example why static dependencies are bad and everything should be interfaces & instances.

Resources