Consuming Web Service from javascript in .net page - c#

How to do it? I am completely new to this and wish to start learning it. I am going to have a tree structure, most probably a html/Javascript tree which will need to be saved into the database through Web Services.
What is the most efficient way to do this with ASP .net web services + asp.net 3.5?
UPDATED:
thanks for all the answers, I am still missing some pieces to this scenario, namely:
1) when the node is to be added to the tree, a user will get a pop-up, where some info will be entered, saved in the database, and a integer code returned from the database. Upon it's return, I need do some logic, and insert a node(or several) into the node selected. And so on, so forth. SO from what i understand, this logic (the meat of the code) will have to be performed on the client, in my Javascript code.
2) What would trigger the tree "refresh" after the pop-up is closed?
3) Where is .net with this picture at all? From what I gather, no server-side coding is performed here at all (aside from Web Services).
Is that the general direction these days, step away from server-side coding with .net controls and use a Javascript lib of choice + web services?
Thanks everyone.

You can achieve this by using ASP.net Ajax calls. On the server-side you create a webservice (WCF or asmx) having the attribute ScriptService:
namespace MyCompany.Project.Services
{
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.Web.Script.Services.ScriptService]
public class MyWebServiceClass : System.Web.Services.WebService
{
[WebMethod]
public string GreetFromServer(string name)
{
return "Hello, " + name;
}
}
}
On the page, you add a ScriptManager referencing your webservice.
<asp:ScriptManager id="scriptManager" runat="server">
<Services>
<asp:ServiceReference Path="~/Services/MyWebServiceClass"/>
</Services>
</asp:ScriptManager>
Then on the client side (JavaScript):
function invokeService(){
MyCompany.Project.Services.MyWebServiceClass.GreetFromServer("Juri", onSuccess, onFailure);
}
function onSuccess(result){
//check if result different null etc..It will be in JSON format, so deserialize
//use result
}
function onFailure(){
//handle errors
}
That should just be a hint on how to create a service and access it from within JavaScript. I mostly wrote it out of my head now, without checking it.
A hint: use Firebug! It's really great for verifying the data that is sent back and forth between your JavaScript client code and the webservice on the server-side.
I've just written a blog post with a downloadable example that describes the communication of client-server using asmx as well as WCF webservices.

Encosia.com has everything you need:
Using jQuery to Consume ASP.NET JSON Web Services

I would suggest you use jquery on the client side in your html / Javascript tree. Here is a tutorial to get you started on using jquery with asp.net
http://dotnetslackers.com/articles/ajax/Using-jQuery-with-ASP-NET.aspx

Have a look
Consuming a Web Service using ASP.NET Ajax

Related

ABP framework - Best way to ValidateModel() and show success message

Context: Web application developed with ASPNet Core over ABP 2.9 framework (Razor pages).
I need to validate a model (it implements Validate(...) from IValidatableObject and calls the application service to perform some validations), then call an application service, and finally show a success message (with the same look & feel as abp.notify.success(...)).
Purpose of this post: To validate whether I am following the best practices or doing things in the correct way with ABP framework. If so, there are some suggestions to ABP team.
What I've tried:
1.- First, I tried submitting the form, but I didn't find an easy way to show the success message (like abp.notify.success ones) from the server method: public virtual async Task<IActionResult> OnPostAsync().
It would be nice to have a simple way to send client messages (like abp.notify.success ones) from server side. Maybe there is a way and I didn't find it.
2.- Second, I tried to cancel form submission and peform validation in client side, call the application service and show the message, also from client side. The issue here is that validations on public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) method were not executed from client side calling form.valid().
Possible improvement to ABP framework would be to enable an easy way to perform same server DataValidation() from client side. Maybe it exists and I didn't find it.
3.- Finally, I did the following:
a) Server side: to perform ValidateModel() and call the application service (see cshtml.cs code).
b) Client Side: avoid form submission and submit it with ajax, and finally show the success message with abp.notify.success(...)) (see javascript code).
Here are the questions related to previous issues. I appreaciate your comments or suggestions:
1.- Is there any better way to perform this scenario using ABP framework utils?
2.- Am I following the best practices? (placing the classes and logic in the correct layers)
DTO with data annotations in Application.Contracts layer.
DTOValidator class that inherits from DTO and IValidatableObject and implements Validate(...) method in Application.Contracts layer. This is to keep simple DTOs between client and application services.
Model class that inherits from DTOValidator and is binded to form in .cshtml.cs (Example: public class IndexPolicies : UpdatePolicyDtoValidator {})
You can cancel form submission and directly call application service. Then use DataAnnotations to validate your dto. If you need custom logic in validation, you can validate it in application service method (or create a custom DataAnnotation).
See https://docs.abp.io/en/abp/latest/Tutorials/Part-1?UI=MVC#dynamic-javascript-proxies for best way to call application service from javascript side.
Dealing with another issue I have found a solution that solves the problem taking full advantage of the ABP framework::
a) Server side: to perform ValidateModel() and call the application service (same as described on my third try).
b) Client Side: to use a simple button instead of submit one and call abpAjaxForm(options) with abp.notify.success() on success function. Then submit the form:
var _defaultPoliciesForm = $("#DefaultPoliciesForm");
var _saveButton = $("#SaveButton");
_saveButton.click(function (e) {
var options = {
beforeSubmit: function (arr, form) {
_saveButton.buttonBusy(true);
},
success: function (responseText, statusText, xhr, form) {
abp.notify.success(l("UpdatedSuccessfully"));
},
complete: function (jqXhr, status, form) {
_saveButton.buttonBusy(false);
}
}
_defaultPoliciesForm.abpAjaxForm(options);
_defaultPoliciesForm.submit();
});
Hope it can be useful to others with the same issue. Anyway, I remember my suggestions to ABP team:
Ability to send client messages like abp.notify.success(...) ones from server side.
Ability to perform same server validation as DataValidation() from client side

How to make an HTTP GET request to OWIN self hosted API?

I'm very new to web development but I wanted to create a web api for an existing Windows Service application I created for work.
My goal right now is to create a simple web app consisting of some text input fields where someone can enter their email and subscribe to a mailing list.
I was pointed in the direction of using OWIN to self-host a web api in my existing project so I looked at this guide to get started:
https://www.asp.net/web-api/overview/hosting-aspnet-web-api/use-owin-to-self-host-web-api
This guide shows the console app calling and displaying the API, but I wanted to do the same from a web app. So I tried to do what is accomplished here in the 'Getting Started with ASP.NET Web Api 2' guide using a console application with OWIN.
When I start my console application, I can enter http://localhost:8080/api/values/1 and I get <string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">value</string> Which I assume means the web server is running and responds to the request to get my string value that I'm returning from my ValuesController.
However I've been trying to create a simple web page that calls the API to get the value but I haven't been able to figure it out.
Right now my index.html has the following in the body:
<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.0.3.min.js"></script>
<script>
var uri = "http://localhost:8080/api/values/1";
$(document).ready(function () {
$.getJSON(uri)
.done(function (data) {
$('#value').text("done");
})
.fail(function (jqXHR, textStatus, err) {
$('#value').text('Error: ' + err);
});
});
</script>
And I just get Error: printed on the page. Again I'm new to working on web related technologies so any guidance would be much appreciated.
Ok so, following the discussion in comments (helping you to debug the app).
The cross-origin security policy in browsers restricts web pages from calling an data source that exists on a different domain. A domain is either a different url, or a different port at the same url.
http://localhost:80
is a different url/domain from:
http://localhost:81
There are two solutions to this, either utilise JSONP, or CORS to make the request to the api, JSONP basically wraps your json data up in a function call. When the api call returns, it executes the callback/function call, bypassing the security restriction.
However, both JSONP and CORS require server support, which brings solution 2...
Serve up the webpage you are trying to use from the API, meaning you server it from the same domain, hence no cross-domain issues!!
Glad you have got it sorted, I know it can be frustrating with web calls.

How can I run a check on page-load (server-side) on a website which includes both aspx pages and mvc?

I want to run a version consistency check between the website and database on every page in the software I work on to see whether one or the other is out of sync. (background: someone could upgrade while a user is using the software, so restricting the check to the sign in page isn't realistic - also why the check is required on any page in the software).
I am not in control of the deployment, as the customer hosts the software themselves on their own hardware.
The front-end is a mixture of asp.net pages and MVC4 (gradually replacing the aspx pages with MVC) , so I can't simply just run the check on Page_Load() in our inner and outer basepages and then have something different for our MVC pages - I would rather not duplicate code for each page type.
Having a look around, I have seen filters which exist for MVC which could be an option for those pages.
I've been investigating HttpHandlers and in theory could restrict the requests down to page load and not static content.
Is there an alternative/better way to do this server side check which would have the code in just one place and would affect both aspx pages and MVC?
Depending on what it should do when its passes the check or fails the check you could set up a new controller Version with an action Check
public class Version : Controller
{
public JsonResult Check() {
return new Json((GetWebsiteVersionNumber() == GetDatabaseVersionNumber()));
}
}
You can then call this endpoint from MVC using #Html.Action in _Layout or in another view and respond accordingly. On the Web Forms side you can then call this end point using the serverside WebRequest class and take appropriate action depending upon the response from your MasterPage PageLoad event or anywhere else you prefer.
Further you could call the endpoint from a common javascript file i(ncluded on both the WebForms and MVC client side includes) and using an AJAX request get the response and deal with it there also.
Excuse syntax errors as I was writing this off the top of my head.

Using config vars with angular and JQuery

I have an .NET application that uses mostly AngularJS, but for getting some things to work on IE9 we used sometimes a Jquery plugin to fix it (e.g. file upload)
Then on the other side there is an API that handles that application. But the API and the App won't be running on the same urls, so as good practice I would love to have 1 place where all the URl's can be set for where the API is where you can find the videos, ....
but how can I handle all this?
If i set them on the angular side, the controller is loaded after the JQuery,
so the value is undefined.
It can't read the web.config because it's just plain html files that are getting loaded. so no support from C#.
And didn't find any way on loading it in via JQuery.
Any suggestion on how to do this?
You can set it as a basic Object so scripts outside of Angular can use it. When you need to use it in the app, you can either require it directly or set it as a constant or create a service using it.
For example,
var api = {
baseUrl: 'www.moo.com/api/v1',
dogs: '/dogs',
cows: '/cows'
};
alert('This alert was created prior to angular module declartion with your api: ' + api.baseUrl);
angular.module('myCheeseIsGoodApp', [])
.constant('apiConstant', api)
.controller('TestController', ['$scope', 'apiConstant', function($scope, apiConstant){
$scope.apiConstant = apiConstant;
}]);
Here is a plunkr to check out how it works.http://plnkr.co/edit/fnqcwHxgxgrZlCpryMiC?p=preview
Keep in mind this was just a quick way to show you how to use it, but you may want to make it a bit more elegant.

Is it possible to fill in an Ajax form programatically?

I'm doing some automation work and can make my way around a site & post to HTML forms okay, but now I'm up against a new challenge, Ajax forms.
Since there's no source to read, I'm left wondering if it's possible to fill in an Ajax form progamatically, in C#. I'm currently using a non-visible axWebBrowser.
Thanks in advance for your help!
Yes, but I recommend using a different approach to requesting/responding to the server pages including the regular pages, and the AJAX handler pages.
In c#, try using the WebRequest/WebResponse or the more specialized HttpWebRequest/HttpWebResponse classes.
Ajax is no more than a "fancy" name for a technology that allows Javascript to make HTTP requests to a server which usually implements some handlers that produce specialized, light-weight content for the Javascript caller (comonly encoded as JSON).
Therefore in order to simulate AJAX calls, all you have to do is inspect your target application (the web page that you want to "post" to) and see what format is used for the AJAX communications - then replicate the page's Javascript behavior from C# using the WebREquest/WebResponse classes.
See Firebug - a great tool that allows you to inspect a web page to determine what calls it makes, to which pages and what those pages respond. It does a pretty good job at inspecting AJAX calls too.
Here's a very simple example of how to do a web request:
HttpWebRequest wReq = (HttpWebRequest)WebRequest.Create("http://www.mysite.com");
using (HttpWebResponse resp = (HttpWebResponse)wReq.GetResponse())
{
// NOTE: A better approach would be to use the encoding returned by the server in
// the Response headers (I'm using UTF 8 for brevity)
using (StreamReader sr = new StreamReader(resp.GetResponseStream(), Encoding.UTF8))
{
string content = sr.ReadToEnd();
// Do something with the content
}
}
A POST is also a request, but with a different method. See this page for an example of how to do a very simple post.
EDIT - Details on Inspecting the page behavior with Firebug
What I mean by inspecting the page you're trying to replicate is to use a tool (I use Firebug - on Firefox) to determine the flow of information between the page and the server.
With Firebug, you can do this by using the "Net" and "Console" panels. The Net panel lists all requests executed by the browser while loading the page. While the "Console" will list communications between the page and the server that take place after the page has loaded. Those communications that take place after the page has loaded are essentially the AJAX calls that you'll want to replicate (Note: Network monitoring has to be enbled in Firebug for this to work)
Check out Michael Sync's tutorial to learn more about Firebug and experiment with the Console panel to learn more about the AJAX requests.
Regarding "replicate the page's behavior from C# using the WebRequest/WebResponse" - what you have to realize is that like I said earlier, the Javascript AJAX call is nothing more than an HTTP Request. It's an HTTP Request that the Javacript makes "behind the scenes", or out-of-band, to the web server. To replicate this, it is really no different than replicating a normal GET or a normal POST like I showed above. And this is where Firebug comes in to play. Using it you can view the requests, as the Javascript makes them - look at the Console panel, and see what the Request message looks like.
Then you can use the same technique as above, using the HttpWebRequest/HttpWebResponse to make the same type of request as the Javascript does, only do it from C# instead.
Gregg, I hope this clarifies my answer a little bit but beyond this I suggest playing with Firebug and maybe learning more about how the HTTP protocol works and how AJAX works as a technology.
Have you looked at using Selenium. AFAIK, you can write the test cases in C# and I know our testers have successfully used it before to UI Test a Ajax enabled ASP.NET site
http://seleniumhq.org/

Categories