Easy openid? .NET/JS? - javascript

I tried to understand dotnetopenid and failed. I dont know asp.net well enough and i want to do this problematically.
Is there a simple JS openid lib? or a simple/good openid example doing it for a C# desktop application?

Here is an example of open ID in c# .net . Not desktop but web.
http://www.nikhedonia.com/notebook/entry/openid-and-asp-net-mvc/

Here is my aspx file, i only added one line, the WebApplication1.openidtest.Authenticate line
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication1._Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<% WebApplication1.openidtest.Authenticate("http://your_id.myopenid.com/"); %>
</div>
</form>
</body>
</html>
Here is the cs file. Note it works but doesnt handle things like errors and really is just for testing/breakpoints.
NOTE: If email is required and the user submit a persona that doesnt have an email there will be no email listed thus you must check and handle accordingly.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using DotNetOpenAuth;
using DotNetOpenAuth.OpenId;
using DotNetOpenAuth.OpenId.RelyingParty;
using DotNetOpenAuth.OpenId.Extensions.AttributeExchange;
using DotNetOpenAuth.OpenId.Extensions.SimpleRegistration;
namespace WebApplication1
{
static public class openidtest
{
static public void Authenticate(string openIdIdentifier)
{
var openId = new OpenIdRelyingParty();
var response = openId.GetResponse();
if (UserNeedsToLogin(response))
{
var request = openId.CreateRequest(openIdIdentifier);
request.AddExtension(new ClaimsRequest { Email = DemandLevel.Require });
request.RedirectingResponse.Send();
return;
}
HandleAuthenticationResponse(response);
}
static bool UserNeedsToLogin(IAuthenticationResponse response)
{
return response == null;
}
static void HandleAuthenticationResponse(IAuthenticationResponse response)
{
switch (response.Status)
{
case AuthenticationStatus.Authenticated:
{
var claims = response.GetExtension<ClaimsResponse>();
if (claims != null)
{
var s = claims.Email;
}
return;
//return HandleSuccessfulLogin(response);
}
case AuthenticationStatus.Canceled:
//_context.ErrorMessage = "Login was cancelled at the provider.";
break;
case AuthenticationStatus.Failed:
//_context.ErrorMessage = "Login failed at the provider.";
break;
case AuthenticationStatus.SetupRequired:
//_context.ErrorMessage = "The provider requires setup.";
break;
default:
//_context.ErrorMessage = "Login failed.";
break;
}
}
}
}

Related

How can I get the callback data with WebView2

I'm building a WPF application and try to get the ajax callback data with the WebView2 control.
WebApplication is a simple Login View, and login method code like this:
$("#btn").click(function () {
$.post("loginHandler.ashx",
{
name: $("#name").val(),
pwd: $("#pwd").val()
},
function (data, status) {
var r=JSON.parse(data)
alert(r.result);
});
});
the XAML code in wpf is:
<wv2:WebView2 Name="webView" Source="http://localhost:44372/login.html" />
Now I use the CoreWebView2_WebResourceResponseReceived to get the request and response information, but I can't get the data in the callback function...
After searching around for decent maybe I should use Javascript? Can JS catch another function's callback result?
Please give me some advise, I'm the first time use to controls...
(If WebView2 can't do this, may the CefSharp do that?)
Any assistance is appreciated, THX!
CoreWebView2.WebResourceResponseReceived is raised whenever the WebView2 gets an http(s) response back from a server and you can check the contents and headers for the response.
But if the content you're trying to obtain exists only in JavaScript you can use CoreWebView2.WebMessageReceived and window.chrome.webview.postMessage to send the content from script to your C#.
In script you'd do something along the lines of:
$("#btn").click(function () {
$.post("loginHandler.ashx",
{
name: $("#name").val(),
pwd: $("#pwd").val()
},
function (data, status) {
var r=JSON.parse(data)
// Send data to the host app
chrome.webview.postMessage(r);
});
});
And in your C# you'd hook up a WebMessageReceived event handler something like:
// During initialization after CoreWebView2 property is set
// and before you navigate the webview2 to the page that will
// post the data.
webView.CoreWebView2.WebMessageReceived += ReceiveLoginData;
// ...
}
void ReceiveLoginData(object sender, CoreWebView2WebMessageReceivedEventArgs args)
{
String loginDataAsJson = args.WebMessageAsJson();
// parse the JSON string into an object
// ...
}
You can see more example usage of WebMessageReceived and PostWebMessage in the WebView2 sample app.
Create a html folder in bin/debug/ path :
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title></title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="script.js"></script>
</head>
<body>
<div id="demo">lkkkkkkkkkkkkkkkkkkkkkk</div>
<div id="demo1">uuuuuuuuuuuuuuuuuuuuuu</div>
<div id="demo2">pppppppppppppppppppppp</div>
<button onclick="me()">Click me</button>
<button onclick="sendThisItem('hidear')">Clickkkkkkkkkkkkkkkkkkk me</button>
<script>
function me() {
var me = "ddddddddd";
document.getElementById('demo1').style.color = 'yellow';
window.chrome.webview.postMessage('dellmaddddddddddddddddddd');
}
</script>
</body>
</html>
Now in Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using Microsoft.Web.WebView2.Core;
namespace WindowsFormsAppWebview
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
InitwebView();
}
async void InitwebView()
{
await webView21.EnsureCoreWebView2Async(null);
webView21.CoreWebView2.Navigate(Path.Combine("file:", Application.StartupPath, #"html\", "index.html"));
webView21.WebMessageReceived += webView2_WebMessageReceived;
}
private void webView2_WebMessageReceived(object sender, Microsoft.Web.WebView2.Core.CoreWebView2WebMessageReceivedEventArgs args)
{
label1.Text = args.TryGetWebMessageAsString();
}
private void button1_Click(object sender, EventArgs e)
{
label1.Text = "sssssssss";
//MessageBox.Show("hello world ");
webView21.CoreWebView2.ExecuteScriptAsync("document.getElementById('demo').style.color = 'red'");
}
}
}
You need to Create label1,button1 , webView21 in Form.
This line is importent:
webView21.WebMessageReceived += webView2_WebMessageReceived;

How to connect SignalR Client on mobile device

Now i am developing selfhost signalr server application using VS2012 and client application using HTML/JS WebUI in Mosync IDE. When communication between client and server application, the signalr hub is successfully created on all browser and android emulator. But its doesn't work when i am using USB Debugging on my mobile. its produce 'undefined' message. How to make successful connection on my mobile. Please guide me.
Server side code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Reflection;
using System.IO;
using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Hubs;
using Microsoft.Owin.Hosting;
using Microsoft.Owin.Cors;
using Microsoft.Owin;
using Owin;
namespace SignalRServer
{
public partial class Form1 : Form
{
private IDisposable signalR { get; set; }
public string ServerURI;
MyNewHub h = new MyNewHub();
public Form1()
{
InitializeComponent();
}
private void btnStart_Click(object sender, EventArgs e)
{
writeToConsole("Starting server...");
btnStart.Enabled = false;
Task.Run(() => StartServer());
}
private void StartServer()
{
try
{
//signalR = WebApp.Start(ServerURI);
if (File.Exists(Application.StartupPath + "\\IPAddress.txt"))
{
ServerURI = System.IO.File.ReadAllText(Application.StartupPath + "\\IPAddress.txt").Trim();
signalR = WebApp.Start(ServerURI);
}
else
{
MessageBox.Show("IPAddress not found");
}
}
catch (TargetInvocationException)
{
writeToConsole("Server failed to start. A server is already running on" + ServerURI);
this.Invoke((Action)(() => btnStart.Enabled = true));
return;
}
this.Invoke((Action)(() => btnStart.Enabled = true));
writeToConsole("Server started at" + ServerURI);
}
public void writeToConsole(string message)
{
if (RichTextBoxConsole.InvokeRequired)
{
this.Invoke((Action)(() => writeToConsole(message)));
return;
}
RichTextBoxConsole.AppendText(message + Environment.NewLine);
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (signalR != null)
{
signalR.Dispose();
}
}
private void btnSend_Click(object sender, EventArgs e)
{
string msg = txtMesage.Text;
h.Receive(msg);
}
}
class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseCors(CorsOptions.AllowAll);
app.MapSignalR();
}
}
[HubName("myNewHub")]
public class MyNewHub : Hub
{
public void Send(string name, string message)
{
Clients.All.addMessage(name, message);
Program.mainform.writeToConsole(name + " : " + message);
}
public void Receive(string msg)
{
var context = GlobalHost.ConnectionManager.GetHubContext<MyNewHub>();
context.Clients.All.addMessage("Admin", msg);
}
public override Task OnConnected()
{
Program.mainform.writeToConsole("Client Connected:" + Context.ConnectionId);
return base.OnConnected();
}
public override Task OnDisconnected(bool stopCalled)
{
Program.mainform.writeToConsole("Client DisConnected: " + Context.ConnectionId);
return base.OnDisconnected(stopCalled);
}
}
}
Client side code:
<!DOCTYPE html>
<!--
* #file index.html
*
* Template application that shows examples of how to access
* device services from JavaScript using the Wormhole library.
-->
<html>
<head>
<title>SignalR Simple Chat</title>
<style type="text/css">
.container {
background-color: #99CCFF;
border: thick solid #808080;
padding: 20px;
margin: 20px;
}
</style>
<meta name="viewport" content="width=320, user-scalable=no">
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Wormhole Template App</title>
<link rel="stylesheet" href="style.css" type="text/css" media="screen" title="no title" charset="utf-8">
<script type="text/javascript" charset="utf-8" src="js/wormhole.js"></script>
<script src="js/jquery-1.6.4.min.js"></script>
<script src="js/jquery.signalR-2.0.3.min.js"></script>
<script src="http://192.168.0.7:8080/signalr/hubs"></script>
<script type="text/javascript">
function clientconnect()
{
alert("Start Button Clicked");
$.connection.hub.url = "http://192.168.0.7:8080/signalr";
// Declare a proxy to reference the hub.
var chats = $.connection.myNewHub;
alert(chats);
// Create a function that the hub can call to broadcast messages.
chats.client.addMessage = function (name, message) {
// Html encode display name and message.
var encodedName = $('<div />').text(name).html();
var encodedMsg = $('<div />').text(message).html();
// Add the message to the page.
$('#discussion').append('<li><strong>' + encodedName
+ '</strong>: ' + encodedMsg + '</li>');
};
// Get the user name and store it to prepend to messages.
$('#displayname').val(prompt('Enter your name:', ''));
// Set initial focus to message input box.
$('#message').focus();
// Start the connection.
$.connection.hub.start().done(function () {
$('#sendmessage').click(function () {
// Call the Send method on the hub.
chats.server.send($('#displayname').val(), $('#message').val());
// Clear text box and reset focus for next comment.
$('#message').val('').focus();
});
});
}
</script>
</head>
<body>
<div class="container">
<input type="text" id="message" />
<input type="button" id="sendmessage" value="Send" />
<input type="hidden" id="displayname" />
<input type="button" value="Start" onclick="clientconnect()"/>
<ul id="discussion"></ul>
</div>
</body>

xmlHttpRequest GET/POST with Spring MVC

I am trying to find a workaround for using POST request, because I cannot use form, pass parameter and redirect to another page without displaying the parameter in the URL. I heard it is possible to do that via XHR GET request but I am not sure how. I have also tried it with POST.
Index.jsp (Peter is my example of POST via form, which works, but I cannot use. George is my example of GET. I can see that the function HttpGet is called and the responseText is the html of helloworld.jsp. Sam is my example of POST. I can see that the parameter is passed to the controller and added to mv but it stops short of redirecting to helloworld.jsp.)
<%# page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Spring 4 MVC - HelloWorld Index Page</title>
<script type="text/javascript">
function httpGet(theUrl)
{
var xmlHttp = null;
alert('httpGet is called');
alert(theUrl);
xmlHttp = new XMLHttpRequest();
xmlHttp.open( "GET", theUrl, false );
xmlHttp.send( null );
alert(xmlHttp.responseText);
return xmlHttp.responseText;
}
function doPost() {
var url = "http://localhost:8080/HelloWorld/hello";
var params = "name=Sam";
alert('Entered Sam');
var xhr = new XMLHttpRequest();
xhr.open("POST", url, true);
//Send the proper header information along with the request
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.send(params);
}
</script>
</head>
<body>
<h2>Hello World</h2>
<form action="hello" id="test" method="POST" style="display:none;">
<input type="hidden" name="name" value="Eric" />
<input type="hidden" name="lastname" value="Peters" />
<button>Go to user 123</button>
</form>
<a href="javascript:;" onclick="javascript:
document.getElementById('test').submit()">Eric Peters</a><br/>
George
Sam
</body>
</html>
Controller:
package com.programcreek.helloworld.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
#Controller
public class HelloWorldController {
String message = "Welcome to Spring MVC!";
#RequestMapping("/hello")
public ModelAndView showMessage(
#RequestParam(value = "name", required = true) String name,
#RequestParam(value = "lastname", required = false, defaultValue = "Doe") String lastname) {
System.out.println("in controller");
ModelAndView mv = new ModelAndView("helloworld");
mv.addObject("message", message);
mv.addObject("name", name);
mv.addObject("lastname", lastname);
return mv;
}
}
Helloworld.jsp
<%# page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Spring 4 MVC -HelloWorld</title>
</head>
<body>
<center>
<h2>Hello World</h2>
<h2>
${message} ${name} ${lastname}
</h2>
</center>
</body>
</html>
My questions are: 1) is it possible to use XHR get or post and not show the parameter in the URL? 2) which method (george or sam) is close, if any, and which files should I look at changing to make it redirect to helloworld.jsp (controller or index.jsp)? Thank you for your help.

Converting Serverside C# to ASP.NET Web API

After posting on how to get server side information to JS (on client side) link here, I was advised to create my server side logic into a Web Api in order to expose data via HTTP through a JQuery AJAX call. After looking through a lot of documentation, and even a tutorial series online hosted by Microsoft, I found little to no good instruction. Previously, I was calling my serverside methods through inline C# calls in my js script, but learned that because C# is precompiled, it simply just "fills in" the values returned by the C# functions.
Just for a reference as to how I am improperly calling my C# methods.
This is my front end: Login.aspx
<%# Page Language="C#" AutoEventWireup="true" CodeFile="Login.aspx.cs" Inherits="Login" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>PAM testing</title>
<link rel="stylesheet" type="text/css" href="Styles/Site.css" />
<script type="text/javascript" src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
<script type="text/javascript" src="Scripts/JScript.js"></script>
</head>
<body>
<div id="banner">PAM Testing Tool</div>
<div id="content">
<form id="form1" runat="server" style="margin-left: 25%; text-align: center; height: 41px; width: 292px;">
<%--Login ASP Object--%>
<asp:Login ID="Login1" runat="server" onclick="process()"></asp:Login>
<asp:ValidationSummary ID="ValidationSummary1" runat="server" style="text-align: center" ValidationGroup="Login1" />
</form>
<%--TEST AREA--%>
<script type="text/javascript">
function logCookie(){
document.cookie = "user=" + document.getElementById("Login1_UserName").value;// this is the id of username input field once displayed in the browser
}
function testFunction() {
<%=Login1_Authenticate() %>;
}
function process(){
logCookie();
testFunction();
}
</script>
</div>
</body>
</html>
My C# code looks like this
Login.aspx.cs
using System;
using System.Data;
using System.Data.SqlClient;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.EnterpriseServices;
public partial class Login : System.Web.UI.Page
{
int status;
int role;
SqlConnection conn;
SqlCommand command;
SqlDataReader reader;
protected string Login1_Authenticate()
{
// create an open connection
conn =
new SqlConnection("Data Source=xxx;"
+ "Initial Catalog=xxx;"
+ "User ID=xxx;Password=xxx");
conn.Open();
//string userName;
//userName = Convert.ToString(Console.ReadLine());
// create a SqlCommand object for this connection
command = conn.CreateCommand();
command.CommandText = "EXEC dbo.SP_CA_CHECK_USER #USER_ID = '"+Login1.UserName+"', #PASSWORD = '"+Login1.Password+"'";
command.CommandType = CommandType.Text;
// execute the command that returns a SqlDataReader
reader = command.ExecuteReader();
// display the results
while (reader.Read())
{
status = reader.GetInt32(0);
}
// close first reader
reader.Close();
//----------
existTest();
return "the login process is finished";
}
public static string GetData(int userid)
{
/*You can do database operations here if required*/
return "my userid is" + userid.ToString();
}
public string existTest()
{
if (status == 0)
{
//login
Session["userID"] = Login1.UserName;
command.CommandText = "EXEC dbo.SP_CA_RETURN_USER_ROLE #USER_ID = '" + Login1.UserName + "'";
reader = command.ExecuteReader();
while (reader.Read())
{
role = reader.GetInt32(0);
}
Session["roleID"] = role;
if (Session["userID"] != null)
{
string userID = (string)(Session["userID"]);
//string roleID = (string)(Session["roleID"]);
}
Response.Redirect("Home.aspx");
}
else
{
//wrong username/password
}
// close the connection
reader.Close();
conn.Close();
return "process complete";
}
}
How can I convert my C# into Web api's? I would very much appreciate it if any answers could link me to good documentation or tutorials.
Moving this into Web API would require creating a new Web API project, setting up your appropriate controllers, and moving Form Control to parameters to pass into the Controller methods. Please visit this tutorial for more information on getting started with ASP.NET Web MVC: Getting Started With ASP-NET Web API
Please Note: Executing dynamic SQL the way you are doing in the above code leaves your application open to SQL Injection attacks! Please consider using parameterized SQL instead.

Open a popup containing ASPX postback result

I have an ASPX page with many fields that generate PDF documents when I click an "export to PDF" button.
I'd now like to have a "print PDF" button in JavaScript that does something like this:
w = window.open(?);
w.print();
w.close();
where "?" will perform the same postback as my "export to PDF" button.
If you need to submit (postback) your form to new window you can try to change form target to fake, like:
var form = $("form");
form.attr("target", "__foo");
Submit a form.
form.submit();
And remove the target (setitmeout(,1) - pot the event in end of js "event-queue", in our case - after form submitting):
setTimeout(function () { form.removeAttr("target"); }, 1);
Also, before submit you can try to open window with __foo id for more styling, and the form will submitted (postback) in this window instead of a new one:
var wnd = window.open('', '__foo', 'width=450,height=300,status=yes,resizable=yes,scrollbars=yes');
But I have no idea how to handle the submitted window and catch the onload or jquery's ready event. If you can do it share the workaround please and call the wnd.print(); You can play with iframes inside this wnd and maybe you will find a solution.
Updated:
Try to have a look in this prototype [tested in Chrome]:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script type="text/javascript" src="https://code.jquery.com/jquery-2.1.0.min.js"></script>
<script type="text/javascript">
function PrintResult() {
var wnd, checker, debug;
debug = true;
// create popup window
wnd = window.open('about:blank', '__foo', 'width=700,height=500,status=yes,resizable=yes,scrollbars=yes');
// create "watermark" __loading.
wnd.document.write("<h1 id='__loading'>Loading...</h1>");
// submit form to popup window
$("form").attr("target", "__foo");
setTimeout(function() { $("form").removeAttr("target"); }, 1);
if (debug)
{
$("#log").remove();
$("body").append($("<div id='log'/>"));
}
// check for watermark
checker =
setInterval(function () {
if (debug) $("#log").append('. ');
try {
if (wnd.closed) { clearInterval(checker); return; }
// if watermark is gone
if (wnd.document == undefined || wnd.document.getElementById("__loading") == undefined) {
if (debug) $("#log").append(' printing.');
//stop checker
clearInterval(checker);
// print the document
setTimeout(function() {
wnd.print();
wnd.close();
}, 100);
}
} catch (e) {
// ooops...
clearInterval(checker);
if (debug) $("#log").append(e);
}
}, 10);
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Button runat="server" ID="ReportButton" OnClick="ReportRenderClick" Text="Export to PDF" OnClientClick="PrintResult()"/>
<asp:Button runat="server" Text="Just a button."/>
</div>
</form>
</body>
</html>
And here is .cs file:
public partial class Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void ReportRenderClick(object sender, EventArgs e)
{
Response.Clear();
Thread.Sleep(2000);
Response.ContentType = "application/pdf";
Response.WriteFile("d:\\1.pdf");
//Response.ContentType = "image/jpeg";
//Response.WriteFile("d:\\1.jpg");
//Response.Write("Hello!");
Response.End();
}
}
Open the pdf window with IFrame and you could do this:
Parent Frame content
<script>
window.onload=function() {
window.frames["pdf"].focus();
window.frames["pdf"].print();
}
</script>
<iframe name="pdf" src="url/to/pdf/generation"></iframe>
Inspired from this https://stackoverflow.com/a/9616706
In your question tag you have the asp.net tag, so I guess you have access to some kind of ASP.NET server technology.
I would suggest to do it like this:
Create a HttpHandler or an ASP.NET MVC action that returns a FileContentResult
In your page, use this code to download and print the file (actually found it here, pasting it for future reference!)
Click here to download the printable version
There are some good tutorials on writing the server side:
Walkthrough: Creating a Synchronous HTTP Handler
How to get particular image from the database?
And one of my own: Download PDF file from Web location and Prompt user SaveAs box on client in web-Application ASP C#

Categories

Resources