How to POST infinite number of parameters in c# function through API - c#

So I have thisfunction I have to make. All previous functions have been made pretty much the same way like so:
[Route("MemberInfo"), HttpPost]
public IHttpActionResult ArrayTest([FromBody]Member member)
{
using (var db = new DBContext())
{
var member = db.Members.Where(m => m.email == loginForm.email).FirstOrDefault();
if (member != null)
{
return Ok(new { success = true, message = member });
}
else
{
return Json(new { success = false, message = "Invalid email or password" });
}
}
}
Just an example, there are a lot more lines of code in that function but it was just an example of how I write them.
I use Google's Advanced REST client to make sure all my functions are working. For MemberInfo I give this with the POST option clicked and content-type is application/json:
{
email: "blahblah#gmail.com",
password: "123456789"
}
and I get all my info.
These function are used by another developer who is creating my iPhone app. I am in the process of creating a function to refer a friend/friends.
I created a little test to see how infinite parameters work(in case there are multiple referred emails):
[Route("ArrayTest"), HttpPost]
public IHttpActionResult ArrayTest(params string[] emails)
{
string emailSentence = "";
for (Int32 i = 0; i < emails.Length; i++ )
{
emailSentence += emails[i] + ", ";
}
return Ok(new { success = true, emails = emailSentence });
}
I am having trouble inputing the parameters, how can I do that?
I try it like this:
{
("hello", "buhbye", "ella")
}
and it says "{"Object reference not set to an instance of an object."}"

That's not valid JSON. You can validate your request by running it through jsonlint.com
Try this instead, post the emails as an array
{
"emails": [
"hello",
"buhbye",
"ella"
]
}

Related

MVC 5 c# hide url parameter

$.ajax({
type: "POST",
url: "#Url.Action("SignInUp")",
data: JSON.stringify({ email_add: email_add ,}),
contentType: "application/json; charset=utf-8",
success: function (response) {
if (response.result == 'SignUp') {
alert("Opp`s its look like you dont have an access for this website");
window.location = response.Urls;
}
else
{
alert("Success fully login");
window.location = response.Url;
}
}
});
hi guys I`m new in mvc5 c# and i in counter this problem i want to hide my url parameter. any can help me thank you for advance
this is my code:
public ActionResult SingInUp(string email_add)
{
bool obj = db.tblUsers.Any(x => x.email_add.Equals(email_add));
if (obj)
{
tblUser user = db.tblUsers.Single(x => x.email_add == email_add);
Session["email_add"] = user.email_add;
Session["fname"] = user.fname;
Session["lname"] = user.lname;
return Json(new { result = "Redirect", Url = Url.Action("Check", "ProjectV3") });
}
else
{
return Json(new { result = "SingUp", Urls = Url.Action("SignUp", "ProjectV3", new { email_add = email_add}) });
}
}
This is i want to hide
If you want to effectively hide something from the client Url you will need to find a way to either mask it, or store it somewhere on the server that can be captured on the next request.
There are many places you can store this data on your server but really the obvious ones are.
Cookies
TempData
Now TempData may seem like the obvious choice as it persists across requests and is cleared from the TempData when accessed. Which is also its downfall, lets say you set the TempData in your SingUpIn method, then return the JsonResul which I am assuming is then used via JavaScript for a redirect. Then you redirect to this page and then pull the value of the TempData dictionary it is subsequently removed. So if the person ends up on the SingUp page and for some reasons decides to refresh the page the value in the TempData wont be found again.
Now this can be handled by resetting the TempData property on each read. So basically you read the TempData item then you reassign the TempData entry.
Here is some very basic code that [basically] works and doesnt show the email in the url.
public ActionResult SignUpIn(string email_acct)
{
//pretend i tested for a real user
TempData["email_acct"] = email_acct;
var r = new { result = "SingUp", Urls = Url.Action("SingUp") };
return Json(r);
}
public ActionResult SingUp()
{
if (!TempData.ContainsKey("email_acct"))
{
//no temp data email.. maybe redirect.. who knows!!
return RedirectToAction("Index");
}
//read the temp data entry..
string emailAcct = TempData["email_acct"].ToString();
//reset the temp data entry
TempData["email_acct"] = emailAcct;
return View(new SingUpModel { EmailAccount = emailAcct });
}
Unless you want to go to POST rather than URL parameters you are stuck. If you just want to hide some of the implementation details you could encode the parameter to obfuscate its meaning.
return Json(new { result = "SingUp", Urls = Url.Action("SignUp", "ProjectV3", new { email_add = Base64Encode(email_add)}) })
...
public static string Base64Encode(string plainText) {
var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText);
return System.Convert.ToBase64String(plainTextBytes);
}
You would end up with a URL like: http://localhost:1126/ProjectV3/SignUp?email_add=cGtleWJpcmQ5NUBnbWFpbC5jb20=. You could obviously change the name of the parameter to hide its intent.

How to get the value that is returned from the kendoui upload success or complete function

I am using Kendo UI upload control. I have defined the Kendo UI upload like this:
<input type="file" name="resume" />
$("#file").kendoUpload({
async: {
saveUrl: "/Home/SaveResume",
autoUpload: true
},
complete: function (e)
{
// here i want to get the text that is returned from the controller
}
});
The controller code is like:
public ActionResult SaveResume(HttpPostedFileBase resume)
{
var text;
// code for the file to convert to text and assign it to text
return Json(text, JsonRequestBehavior.AllowGet);
}
After returning the code I want to retrieve the code in complete function. How can I do that?
You can get the response to success function like this
function onSuccess(e)
{
var response = e.response.data();
}
where the return json could be
return Json(new { data = text }, "text/plain");
If you just passing a string back you should be able to do:
function onSuccess(e) {
var text = e.XMLHttpRequest.responseText;
}
You could also pass back a more complex object, if required:
// Object
public class MyObject
{
public int ID { get; set; }
public string Text { get; set; }
}
// Controller Action
public virtual ActionResult Upload(HttpPostedFileBase file)
{
return this.Json(new MyObject(), "text/plain");
}
// Javascript Handler
function onSuccess(e) {
var response = jQuery.parseJSON(e.XMLHttpRequest.responseText);
var id = response.ID;
var text = response.Text;
}
I'll add my answer alongside the other valid answers here. First though you will want to get the returned response in the success function instead of the complete function:
$("#files").kendoUpload({
async: {
saveUrl: url,
removeUrl: removeUrl,
autoUpload: true
},
select: onFileSelect, // function for when a file is selected
success: onFileSuccess, // function that returns response after upload
complete: onFileComplete, // function after success
remove: onFileRemove, // function for when a file is removed
});
The on success function returns an object (normally people name it e)
function onFileSuccess(e) {
console.log("e.response", e.response);
console.log("e.operation", e.operation);
console.log("e.XMLHttpRequest.status", e.XMLHttpRequest.status);
//e.operation is upload or remove
if (e.operation === "upload") {
// a file was added, get the response
var fileid = e.response;
} else {
// Do something after a file was removed
}
}
My console.log entries return this data:
console.log values
This is how I return my data from the server:
public HttpResponseMessage InsertTempFile()
{
HttpPostedFile file = System.Web.HttpContext.Current.Request.Files[0];
//........
// Code that adds my file to the database
// and generates a new primary key for my file
//.........
var response = new HttpResponseMessage(HttpStatusCode.OK);
response.Content = new StringContent(myNewId.ToString());
return response;
}
The response.Content returns my new Id in e.response
The HttpStatusCode.Ok returns my status of 200. There's a bunch of other data that is returned as well if you inspect the response.
Note that to use HttpResponseMessage and HttpStatuseCode you need to include the following namespaces in your class:
using System.Net.Http;
using System.Net;

How to pass the error message server side to client side using mvc and ajax format

I need some work follow as:
I pass the some value client side to server side (mvc format using ajax)
Check the value in my controller after some action, its need to return the checked id not found in my client side ( this 1 st error message).
If this condition is true means check the another condition's in next step.
In this condition check the value give the message for client like " would you like perform the id for same student 'yes' yes to all' 'no' 'no to all'.
using the this click action i ll do the next action.
[ i am very confuse in 4 and 5th step] .My just sample code brackets given below, please forward your big knowledge. i know this is tuff one . Thank you
My code:
public ActionResult Action(parameters)
{
foreach (var seletedid in id)
{
// my code
}
if (1st condition )
{
return Json(new { success = false });
// 1st error message i use like this
// after that the preform goes to the end
}
try
{
foreach (some code)
{
// my code
if (2nd condtion (3 point))
{
// using this i perform the some action herer
}
}
}
catch (Exception ex)
{
return null;
}
return null;
}
On First button click call Function below:
function MyFunction() {
$.post('#Url.Action("Action", "Controller")', { pareter1: value1, pareter2: value2 }, function (json) {
if (json.Status) {
var confirm = confirm("would you like perform the id for same student?");
if (confirm) {
$.post('#Url.Action("SecondAction", "Controller")', { pareter3: value3, pareter4: value4 }, function (result) {
//check the condition and proceed here, if needed.
});
}
});
}
</script>
If you are using:
Ajax.BeginForm("Action", "ControllerName", new AjaxOptions { OnSuccess = "SuccessNotification" })
Then do:
function SuccessNotification(json) {
if (json.Status) {
var confirm = confirm("would you like perform the id for same student?");
if (confirm) {
$.post('#Url.Action("SectionAction", "Controller")', { pareter3: value3, pareter4: value4 }, function (result) {
//check the condition and proceed here, if needed.
});
}
}
}
SuccessNotification will be called when something will be returned from server side. Here you can check the return data and based on you condition you can call next method.

Jquery Post & ASP.NET MVC Anti-ForgeryToken Validation

In my controller,
[HttpPost]
[OutputCache(CacheProfile = "Short", VaryByParam = "id", VaryByCustom = "none")]
[ValidateAntiForgeryToken(Salt = #ApplicationEnvironment.SALT)]
public ActionResult username(string id) {
try {
if (id == null || id.Length < 3)
return Json(false, JsonRequestBehavior.AllowGet);
var member = Membership.GetUser(id);
if (member == null) {
//string userPattern = #"^([a-zA-Z])[a-zA-Z_-]*[\w_-]*[\S]$|^([a-zA-Z])[0-9_-]*[\S]$|^[a-zA-Z]*[\S]$";
string userPattern = "[A-Za-z][A-Za-z0-9._]{5,14}";
if (Regex.IsMatch(id, userPattern))
return Json(true, JsonRequestBehavior.AllowGet);
}
} catch (Exception ex) {
CustomErrorHandling.HandleErrorByEmail(ex, "Validate LogName()");
return Json(false, JsonRequestBehavior.AllowGet);
}
//found e false
return Json(false, JsonRequestBehavior.AllowGet);
}
and in my view I am doing this for post, I was able to retrieve data for getJSON using HTTP Get. The problem is, when the user puts a space in the name, it doesn't validate and gives a 404. So I thought I could do this using the post method, but it seems that I am unable to send my logname because I am sending an Antiforgery token in the data by serializing it ...
Can any one please help? I would be grateful.
#{
string SALT = ApplicationEnvironment.SALT;
}
<script type="text/javascript" defer="defer">
$(function () {
if($("#LogName").length > 0){
$("#LogName").blur(function(){
var logValidate = "/Validation/username/" + $("#LogName").val();
//anti-forgery token works don't need to create the input field here but if I pass the logname into the form as an input then if a user puts double quote/single quote then it will also crash.. so is there any other way around.
var data = $('<form>#Html.AntiForgeryToken(SALT)</form>').serialize();
$.post(logValidate, data, function (json) {
alert(json);
});
});
$("#Email").blur(function(){
var emailValidate = "/Validation/email/" + $("#Email").val();
alert("got it");
});
}
});
</script>
How about you take the value of the antiforgery token by jquery when sending the request?
Generate your antiforgery key as a hidden field:
#Html.AntiForgeryToken()
Look at the sourcecode and adjust the "#__RequestVerificationToken" selector
var antiForgeryVal = $('#__RequestVerificationToken').val();
data["__RequestVerificationToken"] = antiForgeryVal ;
$.post(logValidate, data, function (json) {
alert(json);
});

How do I force session timeout or a logout of a user when the app auto saves in an asp.net mvc 2 application?

I've seen this question asked a few ways and the solutions are generally for other languages and don't apply to ASP.NET MVC 2.
I am using Jquery & Jquery forms to auto-save user data at a set interval. I still want the application to be able to time out, but the auto-saves via jquery forms keep refreshing the server.
My initial idea to fix this was pretty simple. I've already got an ActionFilter I use to see if the session expires. Well, the session won't ever expire; however, I just keep track of how many auto saves occurr based on a value in session and when it reaches a limit (specified in the web.config), it does a:
filterContext.Result = new RedirectResult("~/Account.aspx/LogOn");
Well, this doesn't work because the auto save is doing an ajaxFormSubmit to call the action in the first place. I've tried changing the action to redirect to the login page, but the same thing happens....it just doesn't do a redirect. The only thing the action can return is a Json result. In my latest version (code below) I'm setting the json return value to false and calling a redirectToLogin() function to send the page over to the login page. It doesn't work and i'm not sure why.
Any thoughts on this would be most helpful.
Excerpt of code that sets up the interval for autosaving on the view (placed just before the form is closed):
<%
double sessionTimeoutInMinutes = double.Parse(ConfigurationManager.AppSettings["SESSION_TIMEOUT_IN_MINUTES"].ToString());
double maxContiguousAutoSaves = double.Parse(ConfigurationManager.AppSettings["MAX_CONTIGUOUS_AUTO_SAVES"].ToString());
double autoSaveInterval = (sessionTimeoutInMinutes / maxContiguousAutoSaves) * 60 * 1000;
%>
<%= Html.Hidden("autoSaveInterval", autoSaveInterval) %>
<script type="text/javascript">
$(document).ready(function() {
var autoSaveFrequency = $('[id=autoSaveInterval]').val();
//alert(' Auto Save Interval in miliseconds: ' + autoSaveFrequency);
setInterval(
"initAutoSave('AutoSaveGoals', 'message')"
, autoSaveFrequency);
});
</script>
"AutoSaveGoals" goals is the name of one of my actions. It handles the post, updates certain items in session, and calls the repository.update. It is defined below:
[HttpPost]
public ActionResult AutoSaveGoals(Data data)
{
Data sessdata = Data();
sessdata.MpaGoals = data.Goals;
sessdata.MpaStatus = data.MpaStatus;
sessdata.StartPeriodDate = data.StartPeriodDate;
sessdata.EndPeriodDate = data.EndPeriodDate;
sessdata.AssociatePassword = data.AssociatePassword;
try
{
_repository.update(sessdata);
}
catch (Exception e)
{
LogUtil.Write("AutoSaveGoals", "Auto Save Goals Failed");
LogUtil.WriteException(e);
}
if (!autoLogOffUser(RouteData.GetRequiredString("action")))
return Json(new { success = true });
else
return Json(new { success = false });
}
The initAutoSave function is javascript that uses Jquery & Jquery Forms plugin. Here it is:
function initAutoSave(targetUrl, messageDivId) {
var options = {
url: targetUrl,
type: 'POST',
beforeSubmit: showRequest,
success: function(data, textStatus) {
//alert('Returned from save! data: ' + data);
if (data.success) {
var currDateAndTime = " Page last saved on: " + getCurrentDateAndTime();
$('[id=' + messageDivId + ']').text(currDateAndTime).show('normal', function() { })
}
else {
alert('redirecting to login page');
redirectToLogin();
//$('[id=' + messageDivId + ']').text(' An error occurred while attempting to auto save this page.').show('normal', function() { })
//alert('ERROR: Page was not auto-saved properly!!!!');
}
}
};
$('form').ajaxSubmit(options);
}
I try doing a javascript redirect in redirectToLogin() but it doesn't seem to get the url or something behind the scenes is blowing up. Here is how it's defined:
function redirectToLogin() {
window.location = "Account.aspx/LogOn";
}
best way to solve this is to have your code always return an Json result, i use a model called StandardAjaxResponse that has an ID, a Message and an answer answer is always false unless my code completes in the correct way and sets this to true. Any errors from try / catch are placed into the message field, so if !data.Answer and the Message is equal to not loggged in the you can then location.href to the login page, without getting the login page as your ajax response.
for example:
public class AjaxGenericResponse{
public bool Answer {get;set; }
public int Id {ge; set; } // this is for cases when i want an ID result
public string Mesage {get;set;} // this is so i can show errors from ajax
}
the controller / action
public JsonResult DoAutoSave(Data data){
var JsonResults = new AjaxGenericResponse{Answer=false};
// do code here to save etc
// no matter what always return a result, even if code is broken
return Json(model);
}
your Javascript:
$.ajax({
url:"",
dataTYpe: 'json',
success:function(data){
if(data.Answer) {
// all is good
} else {
if(data.Message === "logout') { href.location=('login'); } else { alert(data.Message); }
}
}
});
thats one solution anyway!
Stupid me. Thanks for your response minus, but I think our solutions coincided for the answer. My issue was I didn't have the right url to redirect to in the redirectToLogin method. I've made minor tweaks, and presto, its redirecting.
Javascript changes:
function redirectToLogin(url) {
window.location = url;
}
function initAutoSave(targetUrl, messageDivId) {
var options = {
url: targetUrl,
type: 'POST',
beforeSubmit: showRequest,
success: function(data, textStatus) {
//alert('Returned from save! data: ' + data);
if (data.success) {
var currDateAndTime = " Page last saved on: " + getCurrentDateAndTime();
$('[id=' + messageDivId + ']').text(currDateAndTime).show('normal', function() { })
}
else {
alert('redirecting to login page');
redirectToLogin(data.url);
//$('[id=' + messageDivId + ']').text(' An error occurred while attempting to auto save this page.').show('normal', function() { })
//alert('ERROR: Page was not auto-saved properly!!!!');
}
}
};
$('form').ajaxSubmit(options);
}
Action changes
if (!shouldAutoLogOffUser(RouteData.GetRequiredString("action")))
return Json(new { success = true, url = "" });
else
return Json(new { success = false , url = Url.Action("LogOff","Account").ToString() });
The shouldAutoLogOffUser checks a session variable that was updated by an action filter to track the # of contiguous auto saves and handles the logic to see if that value has exceeded the max # of contiguous autosaves allowed. The action filter checked the actionname for 'AutoSave' and if it found it, the counter was incremented. Otherwise the counter was reset to 0 (a non autosave post occurred).
One more random question. If this application were loaded in an IFrame and the window.location call is made, would the IFrame content be changed or the entire page (the container in essence) be changed? Our company is looking to run some of our asp.net mvc 2 apps in IFrame's via websphere portal (yeah, I know....it's not my choice).
Now this is just absurd...So, I was looking over my applications (I've got several going to QA soon) and noted that I've already solved this very question with a much better solution - it was ALL handled in an ActionFilter. I wanted this from the getgo when I asked this question, but to have already implemented it, forgot about that, AND ask again on Stack Overflow...well, I hope my memory issues helps somebody with this. Below is the full action filter code. As always, I'm open to criticism so mock it, revise it, copy it, etc, etc.
public class UserStillActiveAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
int sessionTimeoutInMinutes = int.Parse(ConfigurationManager.AppSettings["SESSION_TIMEOUT"].ToString());
int maxContiguousAutoSaves = int.Parse(ConfigurationManager.AppSettings["MAX_CONSEC_SAVES"].ToString());
int autoSaveIntervalInMinutes = int.Parse(ConfigurationManager.AppSettings["AUTO_SAVE_INTERVAL"].ToString());
string actionName = filterContext.ActionDescriptor.ActionName;
string controllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;
HttpContext currentSession = HttpContext.Current;
LogAssociateGoalsSessionStatus(filterContext.HttpContext, actionName);
if (actionName.ToLower().Contains("autosave"))
{
int autoSaveCount = GetContigousAutoSaves(filterContext.HttpContext);
if (autoSaveCount == maxContiguousAutoSaves)
{
var result = new RedirectResult("~/Account.aspx/LogOff");
if (result != null && filterContext.HttpContext.Request.IsAjaxRequest())
{
//Value checked on Logon.aspx page and message displayed if not null
filterContext.Controller.TempData.Add(PersistenceKeys.SessionTimeOutMessage,
StaticData.MessageSessionExpiredWorkStillSaved);
string destinationUrl = UrlHelper.GenerateContentUrl(
result.Url,
filterContext.HttpContext);
filterContext.Result = new JavaScriptResult()
{
Script = "window.location='" + destinationUrl + "';"
};
}
}
else
{
RefreshContiguousAutoSaves(filterContext.HttpContext, autoSaveCount + 1);
}
}
else
{
RefreshContiguousAutoSaves(filterContext.HttpContext, 1);
}
}
private int GetContigousAutoSaves(HttpContextBase context)
{
Object o = context.Session[PersistenceKeys.ContiguousAutoUpdateCount];
int contiguousAutoSaves = 1;
if (o != null && int.TryParse(o.ToString(), out contiguousAutoSaves))
{
return contiguousAutoSaves;
}
else
{
return 1;
}
}
private void RefreshContiguousAutoSaves(HttpContextBase context,
int autoSavecount)
{
context.Session.Remove(PersistenceKeys.ContiguousAutoUpdateCount);
context.Session.Add(PersistenceKeys.ContiguousAutoUpdateCount,
autoSavecount);
}
private void LogAssociateGoalsSessionStatus(HttpContextBase filterContext, string actionName)
{
AssociateGoals ag = (AssociateGoals)filterContext.Session[(PersistenceKeys.SelectedAssociateGoals)];
bool assocGoalsIsNull = false;
bool assocGoalsInformationIsNull = false;
if (ag == null)
{
assocGoalsIsNull = true;
assocGoalsInformationIsNull = true;
}
else if (ag != null && ag.AssociateInformation == null)
assocGoalsInformationIsNull = true;
}
}
always use double quote in java script and jquery to avoid browser specific issues
like
dataTYpe: 'json' must be as "dataTYpe:"json"

Categories