Passing string list to F# asp.Net api - asp.net

I actually solved my problem before posting, but I wonder if there are any better solutions?
Also if there is somewhere where there is a way to use list as-is?
I am writing a simple get endpoint if F# which needs to accept a list of strings as an argument.
I take that list as the input to a query that runs as expected, I am not worried about that part.
The problem I am facing is as follows (minimal implmenetation):
When I define the endpoint as:
[<HttpGet>]
member _.Get() =
processStrings [ "test"; "test2" ]
it returns as expected.
When I change it to:
[<HttpGet>]
member _.Get([<FromQuery>] stringList: string list) = processStrings stringList
I get an error:
InvalidOperationException: Could not create an instance of type 'Microsoft.FSharp.Collections.FSharpList`1[[System.String, System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]'. Model bound complex types must not be abstract or value types and must have a parameterless constructor. Record types must have a single primary constructor. Alternatively, give the 'stringList' parameter a non-null default value.
Which doesn't make much sense to me, as I am using a list of strings, which in C# at least defaults to an empty list.
So I assume this comes down to how C# and F# interpret these signatures, but I am not sure how to resolve it.
I tried this signature and received the same error as above....
member _.Get( [<Optional; DefaultParameterValue([||]); FromQuery>] stringList: string list) = processStrings stringList
In the end using the following did solve the problem.
member _.Get( [<Optional; DefaultParameterValue([||]); FromQuery>] stringList: string seq) = processStrings stringList
I assume it was solved because seq is just IEnumerable, and then presumable list isn't just List from C# (mutable vs immutable). But is there a way to use an F# list in [FromQuery] parameters? Would [FromBody] have just worked? (No is the tested answer) Is there a way to add a type provider for an endpoint like this?
Is there something else I am missing here? Mine works now, but I am curious to the implications of the above.

I have not tested this, but I would assume that ASP.NET does not support F# lists as arguments. I would guess that taking the argument as an array would be much more likely to work:
[<HttpGet>]
member _.Get([<FromQuery>] stringList: string[]) =
processStrings (List.ofArray stringList)

Related

Why does FreeMarkers built-in "?is_string" return true for an Object?

If I pass an Object into the model and test it with the "?is_string" built-in, it will falsely return a true value.
Is it possible (without checking the class name) to have a proper type checks on Objects?
FreeMarker: 2.3.28
Code to reproduce:
public class Test {}
// In Test Controller
ModelAndView mv = new ModelAndView("test");
mv.addObject("test", new Test());
// In test.ftl
<#if test?is_string>
${test} - is a string!
</#if>
// Result
Test#455b31c - is a string
The problem is that that approach isn't really supported by FreeMarker. The Java objects are mapped to some template language values via Configuration.objectWrapper, and the template only sees the result of that mapping. Furthermore the template language has a different type system than Java, a simplistic one, without classes. (It was a design goal back then that the data-model is just some simple tree, and the templates will work no mater what objects are behind, as far as it still gives the same tree.) ?is_... doesn't check the Java type, but the type according the template language. As with the usual ObjectWrapper-s a "generic" object (means, nothing recognized like List, Map, Date, etc.) can be used as a strings whose value is whatever toString() returns, it's a string as far as the template language is concerned. It's kind of duck typed...
A workaround I can think of is that first check the value with ?is_hash, as that will catch the said generic objects (as they support ., they are hashes as well, not just strings). Or instead just check the property you expect to be present in a Test. Then on the "else" branch you can continue with ?is_string.

ASP.Net QueryString Sort Parameter with Dojo JsonRest Memory Store

I have made a gridx grid that uses a JsonRest Memory store from the dojo framework
http://dojotoolkit.org/reference-guide/1.10/dojo/store/JsonRest.html
the issue is I do not know how to pull out the sort parameter from the query string.
The url being formatted from the JsonRest call is
/admin/sales?sort(+DealershipName)
using the following statement gives me a null error
String sort = Request.QueryString["sort"].ToString();
Looking at the debugger I see the following (I need more rep to post images :( )
ok I can see that the following variables hold this value.
Request.QueryString = {sort(+DealershipName)}
type : System.Collections.Specialized.NameValueCollection
{System.Web.HttpValueCollection}
but the array is null.
I'm thinking I can do two thing. Parse the string myself or overload the dojo JsonRest Memory store. Parsing the string seems easier but if anyone has any idea or knows any libraries that can help me out. I would greatly appreciate it.
dojo/store/JsonRest has a sortParam property that you can set to the name of a standard query parameter to use instead of sort(...) (which it uses by default to avoid colliding with any standard query parameters).
For example, adding sortParam: 'sort' to the properties passed to the JsonRest constructor will result in the query string including sort=+DealershipName instead.
http://dojotoolkit.org/reference-guide/1.10/dojo/store/JsonRest.html#sorting
If the + also presents a problem, you can also override ascendingPrefix to be an empty string (''). Note that descending sort will still be indicated by a leading - (controllable via descendingPrefix).

What is main advantage of Tuple?

Can anyone tell me what is the main advantage of using tuple? In what scenarios do I need to use these?
I assume that you're talking about the Tuple<> type and not anonymous tuple classes.
Like an anonymous type, Tuple<> allows you to avoid declaring a new class just to group a few objects. Unlike anonymous types, tuple types have known names and thus can be used as method return and parameter values, etc.
Personally, I try to avoid heavy use of Tuple<> because it can make for difficult to understand code, expecially when used with primitive types (e. g. if you see a Tuple it's not obvious what each field represents).
One place I have found tuples to be very useful is as dictionary keys. Because Tuples implement Equals() and GetHashCode() (not ==, though!), they are perfect for things like private dictionaries that cache information based on a compound key.
It's used mostly to avoid declaring a class / struct with a few properties only for the sake of passing a group of objects around, where only one object can be passed.
Lets say I have a list of urls to go through and if i get an error (4xx or 5xx) I want to build a list and then either later display it to the user or just look at it in my debugger.
I'd catch the web exception and have a Tuple<string, int> (url, http error code) instead of creating a struct for one or two functions to use. Heck it might even be a foreach loop with a breakpoint on if the list has more then 0 items. Thats when it is useful.

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.

EF4: The closed type 'xxxx' does not have a corresponding element settable property

I'm using this guide to call stored procedure in my projet which using EF4 EDMX through WCFDataservice.
I have mapped a complex type to return items from the stored procedure. If I call the method by http, the XML'result is perfect, but when I call with this code:
public void Test()
{
Uri methodUri = new Uri(entities.BaseUri + "/GetCase");
List<CaseFiltered> result = entities.Execute<CaseFiltered>(methodUri).ToList();
}
I get this exception The closed type CaseFiltered does not have a corresponding element settable property.
I had try this solution but it doesn't work for me.
Have you a solution?
Thank you!
Ok I find the solution according this article
Actually, you did everything
right...However, our client library
does not support materialization of a
collection of complex types directly
(yet). If you look at the output of
the service op, you would see a list
of tag, rather than an Atom
Feed.
My workaround: I'm using Case entities, not the CaseFiltered complex type

Resources