I'm relatively new to utilizing web services. I'm trying to create one that will be accepting data from a ASP.Net form whose input controls are created dynamically at runtime and I don't how many control values will be getting passed.
I'm thinking I'll be using jQuery's serialize() on the form to get the data, but what do I have the web service accept for a parameter? I thought maybe I could use serializeArray(), but still I don't know what type of variable to accept for the JavaScript array.
Finally, I was thinking that I might need to create a simple data transfer object with the data before sending it along to the web service. I just didn't wanna go through with the DTO route if there was a much simpler way or an established best practice that I should follow.
Thanks in advance for any direction you can provide and let me know I wasn't clear enough, or if you have any questions.
The answer to the headline question (assuming this is an ASP.Net web service) is to use the params keyword in your web service method:
[WebMethod]
public void SendSomething(params string[] somethings)
{
foreach (string s in somethings)
{
// do whatever you're gonna do
}
}
Examples:
SendSomething("whatever");
SendSomething("whatever 1", "whatever 2", "whatever 3");
In fact, you don't really even need the params keyword - using an ordinary array as a parameter will let you pass in an unknown number of values.
Well I went with creating my own data transfer object which I guess was always the front of brain solution, I was just thinking that there was probably a recognized best practice on how to handle this.
Related
I'm trying to find the vocabulary to describe what I want and if it exists.
I have a table that shows a few data points from large objects. Loading the entire objects just for the table is very slow. Is there a way to only pass to the front the few properties I want without having to define a new object?
I found something called Sparse Fieldsets in JSON API, and I'm wondering if something like this exists for .NET under another name.
Update:
Talking to another coder, I realize it probably makes more sense to implement something like this between the backend and the database and make a specific call for this table. I still need to work out if I need to create a new object to support this. I think it'd still be faster if I just kept the same object but nulled out all of the connecting objects that I don't need for the table. But maybe that's considered bad practice? Also we're using Entity Framework for what it's worth.
Update 2:
I just created a new query without all of the .Include() and works well enough for what I need:
_dataContext.ApplePie
.Include(f => f.Apples).ThenInclude(f => f.Apple)
.Include(f => f.Sugars).ThenInclude(f => f.MolecularStructure)
.Include(f => f.Recipe)
Maybe you are looking for Anonymous Types?
For example, if you had a typed object with three properties, but you only wanted to operate on two:
var threePropThing = new ThreePropertyThing { Id = 1, Message = "test", ExtraProperty = "ex" };
var myAnonThing = new { Id = threePropThing.Id, Message = threePropThing.Message };
Best practice would be to not pass this anonymous object around. But, if you really needed to, you could return it as type object.
Typically, when passing data around in c#, you want to have it typed.
C# is a strongly-typed language and I would say that it is unusual for C# to support scenarios, when object definition (properties) are not known in advance, like in JSON API "fields" parameter case. Implementing this would imply using reflection to filter the properties, which is usually slow and error-prone.
When implementing C# web-services, people usually create one DTO response model per each request.
If your table has fixed set of fields, I would personally recommend to create a DTO class containing only the fields which are required for your table, and then create a method which returns this response for your specific request. While it doesn't align with "without having to define a new object" in the question, it makes the intention clear and makes it really easier to maintain the API in future.
You might want to use libraries like AutoMapper to save time and avoid duplicated code of copying the values from data model to DTO, if you have many such methods.
Here's my problem.
I'm using SOAP to retrieve information from a third-party web service.
Response time is too high, so I was planning on using JSON instead, at least in a couple of methods.
For this I'm using DataContractJsonSerializer, but I seem to be having some trouble.
For example, in SOAP there's a method called getAvailablePublic with returns an object of type getAvailablePublicResponse.
There's an equivalent for this method in JSON, which also returns a an object of type getAvailablePublicResponse.
In order to deserialize the information I needed to create a couple of data contracts, and here are my concerns:
Do I really need to create a DataContract? Why can't I use getAvailablePublicResponse object from asmx?
The problem is that if I create a DataContract, I need to use a different name other than getAvailablePublicResponse, as I would have two objects with the same name (the one created by me, and the one from SOAP), and this would require making several changes in my solution.
Hope this makes sense.
Thanks.
Can you post your client code that is making the call to the web service? I don't know what you are using now, but I'm a fan of RestSharp for making remote calls and serializing JSON to C# classes. Something like this:
RestClient client = new RestClient("http://some.domain.com/someservice?someparam=yes");
var results = client.Execute<MyGreatDTOClass>(new RestRequest(Method.GET));
I need to get some Json to the client side from the server and it's somewhat troublesome as almost all tutorials assume an Ajax call to a separate action to get the Json.
This led me to think that there must be some reason why it is done this way. In Asp.Net MVC we can pass a Model along with the view to get the information but we can't seem to easily pass a Json object. Instead you are supposed to make a separate call to get this information.
What if the Json info is known when the page is generated, why not generate it at the same time?
I'm sorry if I wasn't clear enough. While it's nice to hear of ways to get Json to the client, the question is actually whether there is a specific reason the Ajax call method is much more popular, like security or anything like that.
Can you put something like this into your view? (rough pseudo code, assuming using a Razor view)
< script >
var myJSON = { Field: #model.Field, Field2: #model.Field2 };
< /script >
Because you do not need both at the same time... on the first call will be to get html (the view of the data - represented by a view model), and any ajax calls will be to get the possibly updated data (json serialized view model).
No reason why you can't. You could use the javacript serializer to create a JSON string that drop on the page. You could also create an action that return the json string that you called from a script tag.
What you want if you're using KnockOut, would be the Mapping plugin that turns an ordinary JS object, like that generated above, into an observable ready for KnockOut to use. See here from info. http://knockoutjs.com/documentation/plugins-mapping.html
You can use content-negotiation by setting accept header. This is considered a best practice (and according to some RESTful).
This needs to be supported and implemented at server as well. ASP NET MVC does not make it easy to support content-negotiation and you have to implement it yourself by if-else or using ActionFilter and implementing action selector.
I'm building an ASP.NET (2.0, no, I can't change it) site with NHibernate, and have a custom JSON converter so I can not-serialize properties I want hidden from the client. This lets me just return the objects, and never have to worry about their serialized values - they're always secure.
Unfortunately, it appears that if I use query.FutureValue<class>(), the object that gets serialized is first the NHibernate.Impl.FutureValue<class> and not my entity, which means I get JSON that looks like this if I throw it in a dictionary and return it to the client:
{key: { Value: { /* my serialized object properties */ } }
Previously I discovered that I can't get any interfaces to work in ASP's JavaScriptConverter implementations... only regular or abstract classes. So returning typeof(IFutureValue<MyBaseClass>) as a supported type means my converter is completely ignored. I can catch MyBaseClass, because I refactored things earlier to use an abstract base instead of an interface, but not the interface.
And then I discover that the FutureValue implementation in .Impl is internal to the assembly, or some other such nonsense that only serves to make my .NET experience even more painful. So I can't use typeof(FutureValue<MyBaseClass>) to handle it all, because FutureValue exists only in my debugging sessions.
Is there a way to get the class type out of the assembly? Or a way to convince ASP that interfaces do in fact have uses? Or might there be some superclass I can access that would let me get around the whole issue?
Help! I like my Futures, it lets me batch a whole heck-ton of calls at once!
(if something isn't clear, or you want more code, by all means, ask! I can post quite a bit.)
If I'm understanding you correctly, it seems you are mixing things a together a little bit.
It sounds like you're trying to serialize an instance of query.FutureValue<class>(), which unsurprisingly gives you just that: a JSON object where the Value fields has JSON representing your entity.
To me it sounds like you really want to just serialize query.FutureValue<class>().Value.
Using NHibernate futures like this gives you little benefit though, so you're probably after something like:
var future1 = query1.FutureValue<SomeEntity>();
var future2 = query2.FutureValue<AnotherEntity>();
var json1 = serializer.Serialize(future1.Value); //<BAM! Multi-query gets fired!
var json2 = serializer.Serialize(future2.Value);
Does that make sense?
I am building a site in which we are making moderate use of email templates. As in, HTML templates which we pass tokens into like {UserName}, {Email}, {NameFirst}, etc.
I am struggling with where to store these, as far as best practice goes. I'll first show the approach I took, and I'd be really excited to hear some expert perspective as a far as alternate approaches.
I created HTML templates in a folder called /Templates/.
I call a static method in my service layer, which takes in the following arguments:
UserName
UserID
Email
TemplatePath ("~/Templates")
Email Subject
Within the service layer I have my static method SendUserEmail() which makes use of a Template class - which takes a path, loads it as a string, and has a AddToken() Method.
Within my static SendUserEmail(), I build the token list off of the method signature, and send the email.
This makes for a quite long method call in my actual usage, especially since I am calling from the web.config the "TemplatePath", and "Email Subject". I could create a utility that has a shorter method call than the ConfigurationManager.AppSettings, but my concern is more that I don't usually see method signatures this long and I feel like it's because I'm doing something wrong.
This technique works great for the emails I have now, which at the most are using the first 3 tokens. However in the future I will have more tokens to pass in, and I'm just wondering what approach to take.
Do I create methods specific to the email needing to be sent? ie. SendNewUserRegistration(), SendMarketingMaterial(), and each has a different signature for the parameters?
I am using ASP.NET Membership, which contains probably the extend of all the fields I'll ever need. There are three main objects, aspnet_User, aspnet_Mebership and aspnet_profile. If it was all contained in one object, I would have just passed that in. Is there performance concerns with passing in all 3, to get all the fields I need? That is versus just passing in aspnet_User.UserID, aspnet_User.Email, etc?
I could see passing in a dictionary with the token entries, but I'm just wondering if that is too much to ask the calling page?
Is there a way to stick these in a config file of it's own called Templates.config, which has tags like -
<Templates>
<EmailTemplate Name="New User Registration">
<Tokens>
<UserName>
<UserID>
<Email>
</Tokens>
<Message Subject="Hi welcome...">
Hi {UserName}...
</Message>
</EmailTemplate>
</Templates>
I guess the main reason I'm asking, is because I'm having a hard time determining where the responsibility should be as far as determining what template to use, and how to pass in parameters. Is it OK if the calling page has to build the dictionary of TokenName, TokenValue? Or should the method take each in as a defined parameter? This looks out of place in the web.config, because I have 2 entries for and , and it feels like it should look more nested.
Thank you. Any techniques or suggestions of an objective approach I can use to ask whether my approach is OK.
First of all I would like to suggest you to use NVelocity as a template engine. As for main problem I think you can create an abstract class MailMessage and derive each one for every needed message (with unique template). So you will use this like following:
MailMessage message = new UserRegistrationMessage(tokens);
//some code that sends this message
Going this way you force each concrete XXXMessage class to be responsible for storing a template and filling it with the given tokens. How to deal with tokens? The simpliest way is to create a dictionary before passing it to the message, so each concrete message class will know how to deal with passed dictionary and what tokens it should contain, but you also need to remember what tokens it should contain. Another way (I like it more) is to create a general abstract type TokenSet and a derived one for every needed unique set of tokens. For example you can create a UserMessageTokenSet : TokenSet and several properties in it:
UserNameToken
SomeUserProfileDataToken
etc. So using this way you will always know, what data you should set for each token set and
UserRegistrationMessage will know what to take from this tokenSet.
There are a lot of ways to go. If you will describe you task better I think I will try suggest you something more concrete. But general idea is listed above. Hope it helps =)