I am trying to send an array of items, whether that's a model[] of varying types or a string[]. From what I've looked at so far it doesn't seem possible, although we send arrays of models to the API controllers already using AJAX calls, this however needs to be sent from an App.
Currently I am sending one at a time to the server, I have tried using the [HtmlPost] tag as well as sending things via List, item[] and serialised as a string object (winds up too large easily).
//App Code
var data = MyListOfModels[];
var result = api.APIController.MyMethod(data);
//API Code
[Route("API/APIController/MyMethod")]
public bool MyMethod(Model[] modelList)
{
return service.DoSomethingWithModels(ModelList);
}
I'm expecting to be able to send an array to the method which can do something with that array of data.
The connections between the web API and Xamarin are built using Swagger.
Related
I have an angular client and want to execute a get request to my web api backend to get a list of items from the underlying Dapper Db Wrapper. Dapper allows me to pass in parameters as an anonymous object which would in csharp look like this:
connection.GetList<T>(new {myParam1:"a", myParam2: true});
What I want to achieve is, to create this parameter object in my angular frontend and pass it in a post request to the server which would then pass it on to the GetList function. The problem here is that the web api does not deserialize it as an (anonymous) object, but rather and IEnumerable of JTokens?
My web api signature is this:
public async Task<IHttpActionResult> MyFunction([FromBody]dynamic whereCond)
I have also tried to pass the object as string wrapped in an outer object like so (angular client):
this.migController.MigrationGetMigrationReports({whereCond: JSON.stringify({NotMigrated: true, MissingTargetFiles: 0})})
and then on the server I manually deserialize it as JObject:
string obj = whereCond.whereCond;
dynamic pObj = JObject.Parse(obj);
But this results in the exact same result: pObj is an IEnumerable and therefore I get an error message from the GetList call:
An enumerable sequence of parameters (arrays, lists, etc) is not allowed in this context
can anybody help?
The answer to my question turned out rather simple:
dynamic pObj = JObject.Parse(obj).ToObject<ExpandoObject>();
I had to cast it as ExpandoObject not just dynamic.
#Tsahi: this is not a design problem. My intention was to provide the server with parameters (filter) which is a quite common task for a client to reduce the dataset to be transferred. We could debate a standard way how to provide these parameters, however. In my special case the most practical way is the anonymous object.
I'm attempting to make a controller method:
public String CreateGasolineBlend(List<Guid> enumerableTransferIDs)
{
//Details
}
Accept a list of GUIDs. However, the list is always null when I'm using postman.
I tried using this article to find out how to format the request:
Is it possible to send an array with the Postman Chrome extension?
But I'm unsure if MVC even is capable of accepting a List of objects using a Post Method, or if perhaps I am incorrectly formatting the POST request in Postman.
(I am using what the previous stack overflow question states, arr[0], arr[1] or arr[], arr[] with Guids as values.)
Is my problem with the way I'm receiving the values in the controller, or is it a problem with how I'm using Postman?
MVC is capable of accepting a list objects and map it to the action method parameter.
You need to make sure you are using the correct Content-Type header value when send the data. "application/json" should work.
I just updated your action method to return the posted data along with the item count in a json structure to verify this.
[HttpPost]
public ActionResult CreateGasolineBlend(List<Guid> enumerableTransferIDs)
{
return Json(new { ItemCount= enumerableTransferIDs.Count(),
Items= enumerableTransferIDs});
}
You can see the response came back with the data we posted.
Here's my situation: I have an MVC3 app that has some very complex C# objects, and those get rendered to a views in this application. However, I have a new requirement: a console application (that I am also writing) will run under a scheduler, and it needs to pull these objects from this MVC3 app, and then do something else with these complex objects.
Since I have control over both apps, I can share a library of the complex objects between them. All of these objects are marked [Serializable]. However, I cannot figure out an easy way to serialize these objects and send them from the MVC3 app to the Console app.
I tried simple JavaScriptSerializer and using the HttpClient to read the string, then deserialize it on the console-app end of things, but unfortunately it doesn't deserialize the data correctly. Everything is null. I can inspect the string on a breakpoint when it arrives at the console app, and all the data is there, in the string, but it just doesn't get de-serialized correctly.
Is there an easier way to do this? I don't care what the serialization method is. The data doesn't have to be passed as JSON and no other application but mine is going to consume these objects. But so far I can't figure out the easiest way to produce/consume these objects.
I know I can go down the whole "create a web service contract" and use data annotations route, but I was hoping there was an easier, less time-consuming way of doing it.
Using Json.NET:
Server-Side
string serializedObject = JsonConvert.SerializeObject(yourComplexObject);
// Send the string to the client...
Client-Side
In the client, you don't even have to know the deserialized object's type, you can take advantage of anonymous objects and dynamic:
string serializedObject = // ... Fetch from server
dynamic complexObject = JsonConvert.DeserializeObject(serializedObject);
// ...
string id = complexObject.UserId;
P.S.: Please note that the object's methods or state is not going to get serialized, only the public properties are.
Can your action just return your object? If so, your client code would look something like (using HttpClient)
var result = client.GetAsync(url).Result;
var myObj = await result.Content.ReadAsAsync<T>();
I have a REST method for search users. Right now I am having following signature for the REST method:
MyResponse GetUsers(UserSearchDTO search, int pageno, int totalrecords);
i.e it is accepting one object of UserSearchDTO, pageno and totalrecords param. The URL will look like
myapp/users?pageno={pageno}&totalrecords={totalrecords}
The end client will send "PUT" request for this service like:
myapp/users?pageno=1&totalrecords=10 and along with it it will pass xml data posted of UserSearchDTO like
<UserSearchDTO><Department>d</Department><Name>abc</Name></UserSearchDTO>
Is this a good architecture i.e in order to get users I am using "PUT" request type. The reason for doing this is because end client has to pass UserSearchDTO in xml form?
The other approach which I'm thinking is pure "GET" i.e instead of using UserSearchDTO I should have the following signature:
MyResponse GetUsers(string department,string name,...., int pageno, int totalrecords);
and the end client will call it like:
myapp/users?department=d&name=abc&......&pageno=1&totalrecords=10
I am in the process of writing my first REST service, so I am no expert, but in my opinion, I think it would be best to use a GET request, since that is exactly what you are doing -- getting data from the server. This will make it easier for other developers to support the app, instead of trying to figure out why you used PUT for a basic data retrieval.
If possible, I suggest that you try casting the UserSearchDTO XML as a string on the client and passing it to the GetUsers method as a string, then load the string into an XmlDocument() on the server and parse it into the DTO. Then your method signature would look like:
MyResponse GetUsers(string userSearchXmlString, int pageno, int totalrecords);
It looks like you're using WCF REST. With WCF REST, you have to implement the query mechanisms yourself as you are attempting to do. Have you considered using ASP.NET Web API? In Web API, your GetUsers() method simply needs to return an IQueryable<User> and Web API wraps that with OData querying capability which handles projection, filtering, sorting, aggregating and paging for you.
I've created a linked list class in my JavaScript code and then translated that code into C#.
Right now I have a JavaScript function that calls a Web Service in order to get an array of names, the JavaScript onComplete function then takes that array and makes it into a linked list.
Is there any way I can create the linked list in the Web Service and pass it back to be used by the JavaScript code or can linked lists not transfer properly?
Edit: Let me rephrase my question to something that makes a little more sense. If you have a custom made object created by a class say.... class User, and that class has a variable called user name. If you pass a User object: objUser, back from C# to JavaScript, how does the JavaScript know it can access objUser.userName? What about possible methods it can invoke on this user object?
I had a similar question when I was creating my ASP.NET MVC application. Basically the answer is that JavaScript does not have the same concept of Types as in C#.
Let's say that you've decided to use JSON to pass data between your client and server in your application. The choice of JSON, XML, YAML or other format is not important.
Server Side
On your server side, in your C# code, you can do something like this (assuming you are using a JSON library of some sort):
var myLinkedList = JsonConvert.DeserializeObject<LinkedList>(json);
Now you've got a myLinkedList variable of Type LinkedList. myLinkedList now behaves like all LinkedList instances.
Client Side
However on the client site, in your JavaScript code, you probably do something like this:
function LinkedList(){
//Constructor for your LinkedList
};
LinkedList.prototype = {
//Various functions to operate on your linked list
};
You need to write something like this to deserialize the data that returns from the server:
var linkedList = JSON.parse(jsonString);
Note that there is NO WAY to indicate that you want this deserialized data to go into the LinkedList "class" that you've defined earlier. JavaScript does not understand that LinkedList is a "class" that you've added functionality to using prototype.
What you get back is a JavaScript object.
One way to get around this is to do something like this:
var linkedList = new LinkedList();
var deserializedObject = JSON.parse(jsonString);
linkedList.Items = deserializedObject.Items;
Basically, you'd have to copy over all the state from your deserialized object into your linkedList variable.