How to log JSON requests of web services - c#

I have a web method, which is called from jquery's ajax method, like this:
$.ajax({
type: "POST",
url: "MyWebService.aspx/DoSomething",
data: '{"myClass": ' + JSON.stringify(myClass) + '}',
contentType: "application/json; charset=utf-8",
dataType: "json",
async: false,
success: function (result) {
alert("success");
},
error: function () {
alert("error");
}
});
And this is my web method:
[WebMethod(EnableSession = true)]
public static object DoSomething(MyClass myClass)
{
HttpContext.Current.Request.InputStream.Position = 0;
using (var reader = new StreamReader(HttpContext.Current.Request.InputStream))
{
Logger.Log(reader.ReadToEnd());
}
}
If myClass in javascript is serialized to correct format, then DoSomething methods executes and saves the raw json to database.
But if myClass is in wrong then the method doesn't execute at all and I can't log the problematic json...
What is the best way to always somehow get and log the raw json, that my web method receives, even if the serialization fails?

With the help of some other answers on stackoverflow I came to this:
public class RequestLogModule : IHttpModule
{
private HttpApplication _application;
public void Dispose()
{
}
public void Init(HttpApplication context)
{
_application = context;
_application.BeginRequest += ContextBeginRequest;
}
private void ContextBeginRequest(object sender, EventArgs e)
{
var request = _application.Request;
var bytes = new byte[request.InputStream.Length];
request.InputStream.Read(bytes, 0, bytes.Length);
request.InputStream.Position = 0;
string content = Encoding.UTF8.GetString(bytes);
Logger.LogRequest(
request.UrlReferrer == null ? "" : request.UrlReferrer.AbsoluteUri,
request.Url.AbsoluteUri,
request.UserAgent,
request.UserHostAddress,
request.UserHostName,
request.UserLanguages == null ? "" : request.UserLanguages.Aggregate((a, b) => a + "," + b),
request.ContentType,
request.HttpMethod,
content
);
}
}
And in the web.config:
<httpModules>
<add name="MyRequestLogModule" type="MyNamespace.RequestLogModule, MyAssembly"/>
</httpModules>

You always can do that in the server side .
when you sent the request to "MyWebService.aspx/DoSomething" which call web service you can log the result (success/error) into log file .

Related

I am trying to check that If email already exist in databse or not or not in database but my code throws error

This is the error I am getting in my console;
GET http://localhost:1089/api/Employee/EmailAlreadyExist?%22some#abc.com%22 404 (Not Found)
This my ajax code where I am sending the user email while creating a new user, and I want this method to let me know if the email already exist in database or not;
function CheckAvailability() {
var email = $("#officialemail").val();
$.ajax({
type: "GET",
url: 'http://localhost:1089/api/Employee/EmailAlreadyExist',
dataType: 'json',
contentType: "application/json",
data: JSON.stringify(email),
success: function (response) {
var message = $("#message");
if (response) {
//Email available.
message.css("color", "green");
message.html("Email is available");
}
else {
//Email not available.
message.css("color", "red");
message.html("Email is NOT available");
}
}
});
}
function ClearMessage() {
$("#message").html("");
};
and I am passing this entire function in another fucntion in which I am passing the email parameter in attempt of creating a new user along with all of the other parameters with their values;
$('.empOfficialDetails').click(function (ev) {
ev.preventDefault();
CheckAvailability()
var data = new Object();
data.UserName = $('#username').val();
data.UPassword = $('#userpass').val();
data.OfficialEmailAddress = $('#officialemail').val();
data.Departments = $('#departments :selected').text();
data.Designation = $('#designation :selected').text();
data.RoleID = $('#role').val();
data.Role = $('#role :selected').text();
data.ReportToID = $('#reportToID').val();
data.ReportTo = $('#reportTo :selected').text();
data.JoiningDate = $('#joindate').val();
data.IsAdmin = $('#isAdmin :selected').val() ? 1 : 0;
data.IsActive = $('#isActive :selected').val() ? 1 : 0;
data.IsPermanent = $('#isPermanent :selected').val() ? 1 : 0;
data.DateofPermanancy = $('#permanantdate').val();
data.HiredbyReference = $('#hiredbyRef :selected').val() ? 1 : 0;
data.HiredbyReferenceName = $('#refePersonName').val();
data.BasicSalary = $('#basicSalary').val();
data.CurrentPicURL = $('.picture').val();
if (data.UserName && data.UPassword && data.OfficialEmailAddress && data.Departments && data.Designation && data.Role && data.IsAdmin && data.IsPermanent) {
$.ajax({
url: 'http://localhost:1089/api/Employee/EmpOfficialDetails',
type: "POST",
dataType: 'json',
contentType: "application/json",
data: JSON.stringify(data),
beforeSend: function () {
$("#dvRoomsLoader").show();
},
complete: function () {
$("#dvRoomsLoader").hide();
},
success: function (data) {
var ID = parseInt(data);
if (ID > 0) {
//var id = data;
$(".HiddenID").val(data);
//var id = $(".HiddenID").val();
$('#official').css('display', 'block');
$('#official').html("Employees Official details added successfully...!");
$('#official').fadeOut(25000);
$("#dvRoomsLoader").show();
$('.empOfficialDetails').html("Update <i class='fa fa-angle-right rotate-icon'></i>");
}
else {
$('#official').find("alert alert-success").addClass("alert alert-danger").remove("alert alert-success");
}
},
error: function (ex) {
alert("There was an error while submitting employee data");
alert('Error' + ex.responseXML);
alert('Error' + ex.responseText);
alert('Error' + ex.responseJSON);
alert('Error' + ex.readyState);
alert('Error' + ex.statusText);
}
});
}
return false;
});
and in my controller I am using an inline query to check for similar email in my database;
[Route("api/Employee/EmailALreadyExist")]
[HttpGet]
public bool EmailAlreadyExist(string email)
{
string retval;
var con = DB.getDatabaseConnection();
Employee emp = new Employee();
string query = "IF EXISTS (SELECT 1 FROM Employee WHERE OfficialEmailAddress = #OfficialEmailAddress)";
SqlCommand com = new SqlCommand(query, con);
com.Parameters.AddWithValue("#OfficialEmailAddress", email);
email = emp.OfficialEmailAddress;
SqlDataReader rdr = com.ExecuteReader();
if (rdr.HasRows)
{
retval = "true";
}
else
{
retval = "false";
}
return Convert.ToBoolean(retval);
}
all of the help I get is highly appreciated and sugesttions for making this code better are all warmly welcomed
thank you
I can see that there is a typo in the route. The L in EmailALreadyExist is capitalized. But you are calling it with a lowercase letter.
Also, I am seeing a missing semicolon in the Ajax code, check that out too.
Your code uses a GET method that can't have a body. So it had to append an URL parameter to it. In ASP.NET it should be named. But your method has not named parameters. So it is not found. Add the parameter name to your payload (name "email"). to your JSON - replace in your JS function CheckAvailability data: JSON.stringify(email), with data: JSON.stringify({email: email}),. Then jQuery should call for api/Employee/EmailALreadyExist?email=.... that will match public bool EmailAlreadyExist(string email).
It is better to use a POST method to hide the email in the request body. Then your original code could have a C# smaller update:
public bool EmailAlreadyExist([FromBody]string email). It will map the single parameter from the body to the C# email variable.
There is a point to separate your logic from the controller. "Thin controller" could validate parameters, a service will contain your "business logic".
From your url
http://localhost:1089/api/Employee/EmailAlreadyExist?%22some#abc.com%22
it looks like you aren't passing email parameter correctly.
You can pass it like
http://localhost:1089/api/Employee/EmailAlreadyExist?email=some#abc.com
or change your route a bit to support your url
[Route("api/Employee/EmailAlreadyExist/{email}")]

Not able to consume my second web method in same web service

In continuation to my previous question Not able to consume my web service through jQuery / AJAX i'm facing the problem again. I have now two [WebMethod] in my web service file. First one is FormSubmit() which works fine now and second one is LoginOnClick This is my code:
[WebMethod]
public void LoginOnClick(agentLoginInfo agentLoginObject)
{
string agentID = "";
string agentPassword = "";
try
{
if (agentLoginObject != null)
{
agentID = agentLoginObject.agentID;
agentPassword = agentLoginObject.agentPassword;
}
else
{
Console.Write("No Data");
}
}
catch (Exception e)
{
Console.Write("Error :" + e.Message);
}
RequestBLObject.AgentID = agentLoginObject.agentID.Trim();
RequestBLObject.AgentPassword = agentLoginObject.agentPassword.Trim();
DataTable UserDetails = new DataTable();
UserDetails = BehaviourBLObject.ValidateUsernamePasswordBL(RequestBLObject);
}
This is the AJAX:
function Login() {
var agentLoginObject = {};
var ID = $("#AgentID").val();
var Password = $("#Password").val();
agentLoginObject.AgentID = ID;
agentLoginObject.AgentPassword = Password;
$.ajax({
method: 'POST',
url: 'http://arohar.com/Service.asmx/LoginOnClick',
data: "{agentLoginObject:" + JSON.stringify(agentLoginObject) + "}",
processData: false,
dataType: 'JSON',
success: function() {
alert("success");
},
error: function() {
alert("error");
}
});
}
Keeping in mind what mistakes i did last time, i tried my best but i ran into same problem again. Can anyone point out where i went wrong again this time?
UPDATE: I saw on my networks tab and this is what I get every time
System.InvalidOperationException: LoginOnClick Web Service method name is not valid.
at System.Web.Services.Protocols.HttpServerProtocol.Initialize()
at System.Web.Services.Protocols.ServerProtocolFactory.Create(Type type, HttpContext context, HttpRequest request, HttpResponse response, Boolean& abortProcessing)

Unknown web method Delete_Local_ABC. Parameter name: methodName in ASP.NET app

I have been getting this error on my following code, which basically initiates the POST request as
ABC.ascx
var ABCid = $(aTag).data('id');
$.ajax({
type: "POST",
url: "WebMethods.aspx/Delete_Local_ABC",
data: "{'id':'" + ABCid + "'}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: successdelete_ABC,
error: Errordelete_ABC
});
}
WebMethods.aspx.cs
[WebMethod]
public static int Delete_Local_ABC(string id)
{
ABC objABC = new ABC();
objABC.ABC_ID = Convert.ToInt32(id);
// call business manager
try
{
BusinessManager businessManager = new BusinessManager();
businessManager.ManageABC(objABC, OperationTypes.Validate);
return 1;
}
catch (Exception ex)
{
throw ex;
}
}
and I am calling following method in BusinessManager.cs
....
case OperationTypes.Validate:
obj.deleteLocalABC();
break;
...
and ABC.cs
public bool deleteLocalABC()
{
string query = "DELETE FROM TBL_ABC WHERE ABC_ID ='" + this.ABC_ID + "'";
_dbManager.executeQuery(query);
return true;
}
I have tried all the solutions available online but nothing is working. This code works perfectly with Visual Studio but not on main deployment.
Use
[WebMethod, ScriptMethod(ResponseFormat = ResponseFormat.Json, UseHttpGet = false)]
instead of just [WebMethod].
I hope your method work fine after that addition.

Calling C# method from javascript in MVC4

i'm trying to call a c# method from javascript but nothing works. What this have to do is that i call the javascript after user press enter, then i call the method in c#, the API try to find the city, then i show the temperature of the city that he typed. But i tried a lot of thing, but nothing worked.
the code:
My JavaScript:
function enterpressalert(e, textarea) {
var code = (e.keyCode ? e.keyCode : e.which);
if (code == 13) { //Enter keycode
var tb = $('#search-bar').val();
$.ajax({
url: '#Url.Action("getWeather", "IndexController")',
type: 'GET',
dataType: 'text',
// we set cache: false because GET requests are often cached by browsers
// IE is particularly aggressive in that respect
cache: false,
data: { city: tb },
success: function () {
$('#search-bar').val() = 'funcionou';
}
});
}
}
My c# method that i'm trying to call:
[WebMethod]
public LocalWeather getWeather(string city)
{
LocalWeatherInput input = new LocalWeatherInput();
input.query = city;
input.num_of_days = "5";
input.format = "JSON";
FreeAPI api = new FreeAPI();
LocalWeather localWeather = api.GetLocalWeather(input);
return localWeather;
}
thanks.
Place a break point in getWeather() function and try this:
[HttpGet]
public LocalWeather getWeather(string city)
{
LocalWeatherInput input = new LocalWeatherInput();
input.query = city;
input.num_of_days = "5";
input.format = "JSON";
FreeAPI api = new FreeAPI();
LocalWeather localWeather = api.GetLocalWeather(input);
return localWeather;
}
and also check whether your are using url routing in global.asax

Return a value from a WebMethod based on conditions provided in the WebMethod

I have a jQuery Ajax WebMethod call as shown below:
<script type="text/javascript">
$(document).ready(function () {
$("#btnsubmit").click(function () {
var arr = new Array();
arr.push($("#control1").val()); arr.push($("#control2").val()); arr.push($("#control13 option:selected").val()); arr.push($("#control4 option:selected").val()); arr.push($("#control15 option:selected").val());
var requestedData = JSON.stringify(arr);
requestedData = "{'details':'" + requestedData + "'}";
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "EmployeeDemotion.aspx/Save",
data: requestedData,
dataType: "json",
success: function (result) {
//check the value returned from the WebMethod and provide alerts accordingly
},
error: function (result) {
alert("Error");
}
});
});
});
</script>
and, the WebMethod is as below:
[WebMethod(EnableSession = true)]
public static InsertDetails[] Save(string details)
{
DataTable dt = new DataTable(); DataTable dts = new DataTable();
List<InsertDetails> data = new List<InsertDetails>();
JavaScriptSerializer js = new JavaScriptSerializer();
string[] Tags = js.Deserialize<string[]>(details);
object[] obj = new object[8];
obj[0] = Tags[0].ToString(); obj[1] = Tags[1].ToString(); obj[2] = Tags[2].ToString(); obj[3] = Tags[3].ToString();
obj[4] = Tags[4].ToString();
int a = //say condition 1
int b = //say condition 2
if (a< b)
{
//insert into database and set a value which says the insertion has succeeded
}
else
{
//alert that data cannot be inserted
}
return data.ToArray();
}
Now I require a value of any possible type (boolean,array,string,integer or other) to be returned to the ajax method so that the success function in the ajax method alerts the status of insertion (as commented in te snippet) i.e; a value should be returned along with the last statement "return data.ToArray();" to the ajax method.
I do not require the element 'data' to be returned, the value which validates the insertion should be returned either along with 'data' or in any other form.
not sure what you want. Whether you want both the data and the flag to be returned to the client function or simply the flag.
Case 1 : all that you want is to return a message about the action that took place inside save
just change your save method like this
[WebMethod(EnableSession = true)]
public static string Save(string details)
{
string message =string.Empty;
/// rest of the usual code of yours
///
if (a< b)
{
//rest of the code
message = "Insertion Successful";
}
else
{
//rest of the code
message = "Error Occured";
}
}
and in your client side inside the ajax success, simple do this:
success: function (result) {
alert(result.d);
}
Case 2: you want to send data also in case insertion is successful
make a wrapper and append the data and the flag both to it. Serialize it and
then send it to the client side function. i.e
//wrapper class
public class ServiceResponse
{
public bool IsSuccess {get;set;}
public string Message {get;set;}
}
now inside your save do this:
[WebMethod(EnableSession = true)]
public static string Save(string details)
{
ServiceResponse serviceResponse =new ServiceResponse();
/// rest of the usual code of yours
///
if (a< b)
{
//rest of the code
serviceResponse.IsSuccess= true;
serviceResponse.Message = String.Join(",",data.ToArray());
}
else
{
//rest of the code
serviceResponse.IsSuccess = false;
}
return new JavaScriptSerializer().Serialize(serviceResponse);
}
and use it inside your client method like :
success: function (result) {
var jsonData = $.parseJSON(result.d);
if(jsonData.IsSuccess){
alert('success');
grid.data(jsonData.Message);
}
else{
alert('failure');
}
}

Categories