[AngularJS][JavaEE] How to send multiple data with $http.post() - javascript

I work on a webapp, i have a probleme to send data and i didn't find some example. I use AngularJS and JavaEE.
Now :
AngularJs :
quiz is an object.
roomFactory.create = function(quiz){
//item.idLesson = $stateParams.lessonid;
return $http.post("/api/private/room/create",quiz)
.then(function (response){
roomFactory.room = response.data;
return roomFactory.room;
},function (response){
$q.reject(response);
});
};
Servlet :
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//get the identity of the one who send the request
Map<String, Object> payload = AppConfig.getRequestPayload(request);
//objetMapper --> use to add request....
ObjectMapper objectMapper = new ObjectMapper();
Random randomGenerator;
// Number of question for the two sets
int nbQuestion = 0;
List<Question> questionsRandom = new ArrayList<>();
//Get object from request
//List<String> list = objectMapper.readValue(AppConfig.getJsonRequest(request), new TypeReference<List<String>>(){});
//List<Quiz> list2 = objectMapper.readValue(AppConfig.getJsonRequest(request), new TypeReference<List<Quiz>>(){});
//String name = list.get(0);
Quiz quiz = objectMapper.readValue(AppConfig.getJsonRequest(request),Quiz.class);
if (quiz.getDuration() == null) {
quiz.setDuration(-1);
}
//LOGGER.info("getIdLesson : ");
//Get list of question from datastore
List<Question> questions = ofy().load().type(Question.class).filter("idLesson", quiz.getIdLesson()).list();
//Take some questions from the list to make the quiz
if (!questions.isEmpty()) {
if (questions.size() < quiz.getNbQuestion()) {
nbQuestion = questions.size();
} else {
nbQuestion = quiz.getNbQuestion();
}
// we peek all the question randomly to the server and create a list of question
while (nbQuestion > 0) {
randomGenerator = new Random();
int index = randomGenerator.nextInt(questions.size());
questionsRandom.add(questions.get(index));
questions.remove(questions.get(index));
nbQuestion--;
}
if (!questionsRandom.isEmpty()) {
//Set the quiz
quiz.setQuestions(questionsRandom);
quiz.setNbQuestion(questionsRandom.size());
Lesson lesson = ofy().load().type(Lesson.class).id(Long.valueOf(quiz.getIdLesson())).now();
//Lesson lesson = ofy().load().type(Lesson.class).filter("idLesson", quiz.getIdLesson()).first().now();
//SET the room
//User user = ofy().load().type(User.class).id(Long.valueOf(jsonUserId.toString())).now();
User user = ofy().load().type(User.class).filter("email", payload.get("email").toString()).first().now();
//LOGGER.info("User : "+user.getFirstName());
Room room = new Room(user, quiz, 60);
room.calculTimeToFinishTheQuiz();
room.setName(lesson.getTitle() + RoomManager.roomNumber);
room.setId(quiz.getIdLesson() + RoomManager.roomNumber);
//Save the room in RoomManager
RoomManager.roomNumber++;
RoomManager.addNewRoom(quiz.getIdLesson(), room);
//Send the room in response
String json = objectMapper.writeValueAsString(room);
response.setContentType("application/json");
response.getWriter().write(json);
}
}
}
}
I need another parameter in my fonction create :
roomFactory.create = function(quiz, roomName){
I try this to send both data :
return $http.post("/api/private/room/create",quiz, roomName)
or
return $http.post("/api/private/room/create",[quiz, roomName])
Get data in Servlet :
first solution :
String roomName= objectMapper.readValue(AppConfig.getJsonRequest(request),String.class);
second solution :
List<String> list = objectMapper.readValue(AppConfig.getJsonRequest(request), new TypeReference<List<String>>(){});
String roomName = list.get(0);
roomName = roomName.replace("\"", "");
but the second didn't work because quiz is an object. I try to convert quiz but i didn't work as well.

You can pass multiple Data as follow
var Indata = {'pram1': 'value1', 'pram2': 'value2' };
$http.post("/api/private/room/create", Indata)
.then(function (response){
roomFactory.room = response.data;
return roomFactory.room;
},function (response){
$q.reject(response);
});
Here is the better example

For sending multiple list in the json to rest api use this code
var settings1 = {pram1: 'value1', pram2: 'value2',pram3: 'value3'};
var settings2 = {pram1: 'value1', pram2: 'value2',pram3: 'value3'};
var settings3 = {pram1: 'value1', pram2: 'value2',pram3: 'value3'};
var listObj = [settings1,settings2,settings3];
$http.post("/api/private/room/create",listObj)
.then(function (response){
roomFactory.room = response.data;
return roomFactory.room;
},function (response){
$q.reject(response);
});
and in the controller
#RequestMapping(value = "/api/private/room/create", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
ResponseEntity createRequest(#RequestBody List<SettingsModel> settingsList) {
}
SeetingsModel class is like this
public class SettingsModel {
private String param1;
private String param2;
private String param3;
public String getParam1() {
return param1;
}
public void setParam1(String param1) {
this.param1 = param1;
}
public String getParam2() {
return param2;
}
public void setParam2(String param2) {
this.param2 = param2;
}
public String getParam3() {
return param3;
}
public void setParam3(String param3) {
this.param3 = param3;
}
}

Related

.Net Core Web API not accepting a json string field value

I have a problem whereby I would like to pass a json string as a field value but I keep getting "The input was not valid". So to be clear I have an object in my front end that I use the below to pass to my API:
let j: Settings = {} as Settings;
j.user_settings_ID = object.user_settings_ID;
j.user_ID = object.user_ID;
j.user_filter = JSON.stringify(object.user_filter);
j.user_test_filter = JSON.stringify(object.user_test_filter);
fetch('api/Profile/UpdateProfileSettings/?id=' + object.user_settings_ID, {
method: 'put',
headers: {
'Content-Type': 'application/json; charset=utf-8',
'Authorization': 'Bearer ' + sessionStorage.getItem('token')
},
body: "'" + JSON.stringify(j) + "'",
}).then(data => {
if (!data.ok) {
alert("Failed");
}
}).catch((ex) => {
alert("Failed");
});
In my API I have:
[HttpPut("[action]")]
public async Task<string> UpdateProfileSettings(int id, [FromBody] string obj)
{
HttpClient clientRoute = new HttpClient();
var response = await clientRoute.PutAsync("https://something.com/api/UserSettings/put/" + id, new StringContent(obj, Encoding.UTF8, "application/json"));
var contents = await response.Content.ReadAsStringAsync();
return contents;
}
I don't have a problem when I set the j.user_filter and j.user_test_filter with any normal string, but I would like to put the 'jsonified' string as the value for the field, but the Web API doesn't like it for some reason (probably because it isn't seeing it as a string but a json object perhaps)
If someone could help I would be most grateful.
Ok after messing about with this for a long time, I came up with this 'solution'.
So as #Niladri pointed out the "'" before JSON.stringify(j) was a factor but was not the only thing that needed to be changed. The main problem was actually in the controller itself.
I had this previously in my controller:
public async Task<string> UpdateProfileSettings(int id,[FromBody] string obj)
{
HttpClient clientRoute = new HttpClient();
var response = await clientRoute.PutAsync("https://something.com/api/UserSettings/put/" + id, new StringContent(obj, Encoding.UTF8, "application/json"));
var contents = await response.Content.ReadAsStringAsync();
return contents;
}
But I had to change it to:
public async Task<string> UpdateProfileSettings(int id,[FromBody] object obj)
{
HttpClient clientRoute = new HttpClient();
var response = await clientRoute.PutAsync("https://something.com/api/UserSettings/put/" + id, new StringContent(obj.ToString(), Encoding.UTF8, "application/json"));
var contents = await response.Content.ReadAsStringAsync();
return contents;
}
Notice the change of [FromBody] string obj to [FromBody] object obj and also
changed StringContent(obj, Encoding.UTF8, "application/json")) to StringContent(obj.ToString(), Encoding.UTF8, "application/json"))
My previous method with "'" before JSON.stringify(j) works if your controller [FromBody] is of string type and you aren't looking to pump a string which looks like JSON into your controller.
I apologise if this is a bad explanation but tried my best and it worked for me
This is very similar to mcc20's own fix, but I didn't get that code to work. The 2.1 framework has Issues https://github.com/aspnet/Mvc/issues/7609 and https://github.com/aspnet/Mvc/issues/7799. I got this JSON post to complex class working in 2.1: client javascript is unchanged:
var payload = JSON.stringify({ "name": document.getElementById('firstname').value, "email": document.getElementById('email').value, "captcha": grecaptcha.getResponse() });
var oReq = new XMLHttpRequest();
oReq.ContentType = "application/json";
oReq.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("update").innerHTML = this.responseText;
}
else document.getElementById("update").innerHTML = "not 4&200! : " + this.responseText;
};
oReq.open('POST', 'api/u');
oReq.send(payload);
and the controller has:
[Route("api/[controller]")]
// [ApiController] // works either way
public class UController : ControllerBase
{
[HttpPost]
public async Task<string> signUp()
{
String body;
using (StreamReader reader = new StreamReader(Request.Body, Encoding.UTF8))
{
body = await reader.ReadToEndAsync();
}
UserSignup user = JsonConvert.DeserializeObject<UserSignup>(body);
return user.email;
}
}
I was trying something like ([FromBody] UserSignup user) getting Mvc.SerializableError and "The input was not valid." Soon to be on https://github.com/Hover-Us/

.net core Razor pages with JQuery AJAX

I am trying to call a Razor Page Handler using JQuery AJAX. Here is the sample code.
<script type="text/javascript">
$(document).ready(function () {
$("#SectionId").change(function () {
var options = {};
options.url = $(location).attr('href') + "/?SectionId=" + $("#SectionId").val() + "?handler=SelectByID";
options.type = "GET";
options.dataType = "json";
options.success = function (data) {
};
options.error = function () {
$("#msg").html("Error while making Ajax call!" + options.error.val);
};
$.ajax(options);
});
});
</script>
Razor Page cs code:
public class CreateModel : PageModel
{
private readonly ApplicationDbContext _context;
private readonly UserManager<ApplicationUser> _userManager;
private Task<ApplicationUser> GetCurrentUserAsync() => _userManager.GetUserAsync(HttpContext.User);
[BindProperty]
public FileRecord FileRecord { get; set; }
public List<SelectListItem> UserList { get; set; }
public string SelectedSectionId { get; set; }
public CreateModel(ApplicationDbContext context, UserManager<ApplicationUser> userManager)
{
_context = context;
_userManager = userManager;
}
public IActionResult OnGetSelectByID(string SectionId)
{
return null;
}
public async Task<IActionResult> OnGetAsync()
{
//Prepare UserList
UserList = new List<SelectListItem>();
List<ApplicationUser> Users = await _context.Users.ToListAsync();
foreach (var item in Users)
{
string role = Enum.GetName(typeof(EmRoles), EmRoles.NormalUser);
if (await _userManager.IsInRoleAsync(item, role) && item.IsEnabled)
{
UserList.Add(new SelectListItem()
{
Text = item.FullName,
Value = item.Id
});
}
}
//Sections
ViewData["Sections"] = new SelectList(_context.Sections, "Id", "Name");
//FileNOs
ViewData["Files"] = new SelectList(_context.FileRegisters, "Id", "FileNo");
//ViewData["ReceiverUserId"] = new SelectList(_context.Users, "Id", "Id");
//ViewData["SenderUserId"] = new SelectList(_context.Users, "Id", "Id");
return Page();
}
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
//Two File Records have to be created. One For Sender & One for receiver.
FileRecord SenderRecord = new FileRecord
{
//create unique file id
//FileId = Guid.NewGuid().ToString(),
OutDate = DateTime.Now,
};
FileRecord ReceiverRecord = new FileRecord
{
//create unique file id
//FileId = SenderRecord.FileId,
InDate = SenderRecord.OutDate,
};
//Current logged-in user
var user = await GetCurrentUserAsync();
SenderRecord.OwnerUserId = user.Id;
//Receiver
ReceiverRecord.OwnerUserId = FileRecord.ReceiverUserId;
ReceiverRecord.SenderUserId = SenderRecord.OwnerUserId;
//Sender Record
if (await TryUpdateModelAsync<FileRecord>(SenderRecord, "FileRecord", f => f.FileId, f => f.Remarks, f => f.Gist, f => f.ReceiverUserId))
{
//Receiver Record
if (await TryUpdateModelAsync<FileRecord>(ReceiverRecord, "FileRecord", f => f.FileId, f => f.Gist))
{
_context.FileRecords.Add(SenderRecord);
_context.FileRecords.Add(ReceiverRecord);
await _context.SaveChangesAsync();
return RedirectToPage("./Index");
}
}
//If it reaches here. that means some error occurred.
return null;
}
}
The Issue is am not getting a call to Razor Page Handler defined above. If i skip the SectionId parameter passed-in & call only the handler. it is working fine. but it is not working when parameter is sent to the handler, default OnGet() is being called.
Help plz.
You don't need to append your handler parameter
options.url = $(location).attr('href') + "/?SectionId=" + $("#SectionId").val();
You also need to decorate the method with the HttpGet attribute
[HttpGet("GetSelectByID")]
public IActionResult OnGetSelectByID(string SectionId)
{
return null;
}
Then your URL to call this method needs to be
http://localhost:xxxx/FileMovement/Create/GetSelectByID?SectionId=yyy
When you have more than one GET defined on a controller you must tag the additional GET methods with the HttpGet attribute and add a string to define the name of that method.
Finally i was able to solve the issue.
<script type="text/javascript">
$(document).ready(function () {
$("#SectionId").change(function () {
var options = {};
options.url = $(location).attr('href') + "?handler=SelectByID" + "&SectionId=" + $("#SectionId").val();;
options.type = "GET";
options.dataType = "json";
options.success = function (data) {
};
options.error = function (data) {
$("#msg").html("Error while making Ajax call!" + data.error.val);
};
$.ajax(options);
});
});
Everything was right except i have to use "&" in "&SectionId="

how can i pass an array in window.location without ajax call

I want to send list array in ExportTo Method, but in ExportTo method student parameter get null value. If I use ajax it will work fine. But have to use window.locatoin for pass list array.
View
$(document).ready(function () {
$("#SaveBtn").click(function () {
var student = {
Name: "Tanzid",
Department: "CSE"
};
var student1 = {
Name: "Yasir",
Department: "BBA"
};
var list = [];
list.push(student);
list.push(student1);
var url = '#Url.Action("ExportTo", "Students")';
var a = JSON.stringify(list);
window.location = url + '?' + a;
});
})
.
Controller
Public void ExportTo(List<Student> student)
{
}
Iv'e tested some scenario of your problem and its work without using ajax:
Commented first your code coz i don't have it.
From Index View:
#{
ViewBag.Title = "Index";
}
<script src="~/scripts/jquery-1.10.2.js"></script>
<h2>Index</h2>
<script>
$(document).ready(function () {
var person = [];
person.push("Reign");//change like $("#idname").val();
person.push("John");
var listOfObjects = [];
person.forEach(function (names) {
var singleObj = {}
singleObj['name'] = names;
singleObj['dept'] = 'IT Dept.';
listOfObjects.push(singleObj);
});
var url = '#Url.Action("Sample", "Home")';
window.location = url + '?id=' + JSON.stringify(listOfObjects);
})
HomeController:
public ActionResult Sample()
{
string getval = Request.QueryString["id"];
string concat = #"{""data"":" + getval + "}";
ValList vl = new JavaScriptSerializer().Deserialize<ValList>(concat);
foreach (var item in vl.data)
{
Console.WriteLine("dept: {0}, name: {1}", item.dept, item.name);
}
return View();
}
public class ValList
{
public List<Values> data { get; set; }
}
public class Values
{
public string name { get; set; }
public string dept { get; set; }
}
It's all working its just depend on your project code with this:
//var List = [];
//var a = {
// Name: $("#").val(),
// Dept: $("#").val()
//};
//List.Push(a);
This is all i got..
It's Tested according to your needs.. Good Luck

Download File From MVC

I need a way to pass a list of strings when a user clicks an icon from angular/script and send it to an MVC controller in .NET. This list does what it needs to then is supposed to download a file in my browser. I have learned that I cannot do this via AJAX and/or it get pretty messy.
Edit: the list of strings refers to a list of file ids that I am retrieving, then zipping up into one file, which is to be downloaded. I do not want to store this zipped file anywhere permanently.
I am open to ideas!
$http.post('document/downloadfiles', data).success(function () {/*success callback*/ });
[HttpPost]
public ActionResult DownloadFiles(List<string> fileUniqueIdentifiers)
{
var file = _service.ArchiveAndDownloadDocuments(fileUniqueIdentifiers);
file.Position = 0;
return new FileStreamResult(file, "application/force-download");
}
Ok, third-time lucky I guess?
(I think this'll be my last implementation sorry Jim - you'll have to work the rest out for yourself, I think I've given you more than enough free pointers for now... if you want more you can contact me and I'll charge you to write it! :P).
This version uses a cookie-based interchange, accepts the input strings (assuming they are filenames) from the javascript, stores these in the instance class along with the token as key, then assembles the ZipFile in-memory (without writing to disk), and then returns the zipfile as a Content Result. For efficiency you could remove the actual token checks against the GUID list and just check against the key in the file list. Obviously you probably won't want the filenames hard-coded in that javascript as I've done, but you can work that part out for yourself.
Hint: Create a database table with identifier/filepath pairs and use the identifiers to lookup the individual file paths after the request is sent to the server...
View Part (I added mine to index.cshtml):
<script type="text/javascript">
function sendStringandGetFiles() {
var files = ['c:\\temp\\afile.txt', 'c:\\temp\\afile2.txt', 'c:\\temp\\afile3.txt'];
$.ajax({
type: "POST",
url: "/Home/GetFile",
contentType: 'application/json',
data: JSON.stringify(files),
success: function (result) {
//alert("Yes This worked! - " + result);
window.location = "/Home/GetFile";
}
});
}
</script>
<h5>Just something to click</h5>
<button onclick="sendStringandGetFiles()">Send String and Get Files</button>
Then Controller Part (I used HomeController.cs)
[AcceptVerbs(HttpVerbs.Post)]
public string GetFile(string[] strings)
{
Guid token = Guid.NewGuid();
InMemoryInstances instance = InMemoryInstances.Instance;
instance.addToken(token.ToString());
instance.addFiles(token.ToString(), strings);
HttpCookie cookie = new HttpCookie("CookieToken");
cookie.Value = token.ToString();
this.ControllerContext.HttpContext.Response.Cookies.Add(cookie);
return token.ToString();
}
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult GetFile()
{
InMemoryInstances instance = InMemoryInstances.Instance;
if (this.ControllerContext.HttpContext.Request.Cookies.AllKeys.Contains("CookieToken"))
{
HttpCookie cookie = this.ControllerContext.HttpContext.Request.Cookies["CookieToken"];
if (instance.checkToken(cookie.Value))
{
cookie.Expires = DateTime.Now.AddDays(-1);
this.ControllerContext.HttpContext.Response.Cookies.Add(cookie);
MemoryStream ms = new MemoryStream();
string[] filenames = instance.getFiles(cookie.Value);
using (ZipArchive zs = new ZipArchive(ms,ZipArchiveMode.Create, true))
{
for (int i=0;i < filenames.Length; i++)
zs.CreateEntryFromFile(filenames[i], Path.GetFileName(filenames[i]));
}
FileContentResult resultContent = new FileContentResult(ms.ToArray(),"application/zip");
instance.removeFiles(cookie.Value);
resultContent.FileDownloadName = "ARandomlyGeneratedFileNameHere.zip";
return resultContent;
} else
{
return View("Index");
}
}
else
{
return View("Index");
}
}
InMemoryInstances Class:
public class InMemoryInstances
{
private static volatile InMemoryInstances instance;
private static object syncRoot = new Object();
private List<Guid> activeTokens;
private NameValueCollection filesByKeyCollection;
private InMemoryInstances()
{
activeTokens = new List<Guid>();
filesByKeyCollection = new NameValueCollection();
}
public static InMemoryInstances Instance
{
get
{
if (instance == null)
{
lock (syncRoot)
{
if (instance == null)
instance = new InMemoryInstances();
}
}
return instance;
}
}
public bool checkToken(string token)
{
return activeTokens.Contains(new Guid(token));
}
public string[] getFiles(string token)
{
return filesByKeyCollection.GetValues(token);
}
public bool addFiles(string token, string[] files)
{
for (int i = 0; i < files.Length; i++)
filesByKeyCollection.Add(token, files[i]);
return true;
}
public bool addToken(string token)
{
activeTokens.Add(new Guid(token));
return true;
}
public bool removeFiles(string token)
{
filesByKeyCollection.Remove(token);
return true;
}
public bool removeToken(string token)
{
return activeTokens.Remove(new Guid(token));
}
}
Hope this helps!
I normally wouldn't go to this length of effort to help, but I'm home sick and feel like writing some code, so here's an implementation of what I think you're asking for. Here I'm using token exchange to track the file interchange for a specific user storing the data in a singleton instance, you could use another method (e.g. database token storage) if you wanted...
View Part (I added mine to index.cshtml):
<script type="text/javascript">
function sendStringandGetFiles() {
var strings = ['One String', 'Two String', 'Three String'];
$.ajax({
type: "POST",
url: "/Home/GetFile",
contentType: 'application/json',
data: JSON.stringify(strings),
success: function (result) {
//alert("Yes This worked! - " + result);
window.location = "/Home/GetFile?token=" + result;
}
});
}
</script>
<h5>Just something to click</h5>
<button onclick="sendStringandGetFiles()">Send String and Get Files</button>
Then, Controller part (I used HomeController.cs):
[AcceptVerbs(HttpVerbs.Post)]
public string GetFile(string[] strings)
{
for (int i = 0; i < strings.Length; i++)
{
// Do some stuff with string array here.
}
Guid token = Guid.NewGuid();
InMemoryInstances instance = InMemoryInstances.Instance;
instance.addToken(token.ToString());
return token.ToString();
}
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult GetFile(string token)
{
string filename = #"c:\temp\afile.txt";
InMemoryInstances instance = InMemoryInstances.Instance;
if (instance.checkToken(token))
{
instance.removeToken(token);
FileStreamResult resultStream = new FileStreamResult(new FileStream(filename, FileMode.Open, FileAccess.Read), "txt/plain");
resultStream.FileDownloadName = Path.GetFileName(filename);
return resultStream;
}
else
{
return View("Index");
}
}
InMemoryInstances Class:
public class InMemoryInstances
{
private static volatile InMemoryInstances instance;
private static object syncRoot = new Object();
private List<Guid> activeTokens;
private InMemoryInstances()
{
activeTokens = new List<Guid>();
}
public static InMemoryInstances Instance
{
get
{
if (instance == null)
{
lock (syncRoot)
{
if (instance == null)
instance = new InMemoryInstances();
}
}
return instance;
}
}
public bool checkToken(string token)
{
return activeTokens.Contains(new Guid(token));
}
public bool addToken(string token)
{
activeTokens.Add(new Guid(token));
return true;
}
public bool removeToken(string token)
{
return activeTokens.Remove(new Guid(token));
}
}
Hope this helps!
I also wrote yet another implementation which uses cookies to perform the same operation (incase you wanted to store the information client-side instead of using a query-string, yes, I'm slightly bored)...
View Part (I added mine to index.cshtml):
<script type="text/javascript">
function sendStringandGetFiles() {
var strings = ['One String', 'Two String', 'Three String'];
$.ajax({
type: "POST",
url: "/Home/GetFile",
contentType: 'application/json',
data: JSON.stringify(strings),
success: function (result) {
//alert("Yes This worked! - " + result);
window.location = "/Home/GetFile?token=" + result;
}
});
}
</script>
<h5>Just something to click</h5>
<button onclick="sendStringandGetFiles()">Send String and Get Files</button>
Then Controller Part (I used HomeController.cs)
[AcceptVerbs(HttpVerbs.Post)]
public string GetFile(string[] strings)
{
for (int i = 0; i < strings.Length; i++)
{
// Do some stuff with string array here.
}
Guid token = Guid.NewGuid();
InMemoryInstances instance = InMemoryInstances.Instance;
instance.addToken(token.ToString());
HttpCookie cookie = new HttpCookie("CookieToken");
cookie.Value = token.ToString();
this.ControllerContext.HttpContext.Response.Cookies.Add(cookie);
return token.ToString();
}
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult GetFile()
{
string filename = #"c:\temp\afile.txt";
InMemoryInstances instance = InMemoryInstances.Instance;
if (this.ControllerContext.HttpContext.Request.Cookies.AllKeys.Contains("CookieToken"))
{
HttpCookie cookie = this.ControllerContext.HttpContext.Request.Cookies["CookieToken"];
if (instance.checkToken(cookie.Value))
{
cookie.Expires = DateTime.Now.AddDays(-1);
this.ControllerContext.HttpContext.Response.Cookies.Add(cookie);
FileStreamResult resultStream = new FileStreamResult(new FileStream(filename, FileMode.Open, FileAccess.Read), "txt/plain");
resultStream.FileDownloadName = Path.GetFileName(filename);
return resultStream;
} else
{
return View("Index");
}
}
else
{
return View("Index");
}
}
InMemoryInstances Class:
public class InMemoryInstances
{
private static volatile InMemoryInstances instance;
private static object syncRoot = new Object();
private List<Guid> activeTokens;
private InMemoryInstances()
{
activeTokens = new List<Guid>();
}
public static InMemoryInstances Instance
{
get
{
if (instance == null)
{
lock (syncRoot)
{
if (instance == null)
instance = new InMemoryInstances();
}
}
return instance;
}
}
public bool checkToken(string token)
{
return activeTokens.Contains(new Guid(token));
}
public bool addToken(string token)
{
activeTokens.Add(new Guid(token));
return true;
}
public bool removeToken(string token)
{
return activeTokens.Remove(new Guid(token));
}
}
Maybe that is better if you want to hide the token interchange from the browser address bar?

JQuery request not working in Chrome and Firefox. Works in IE

I have a WCF service being hosted locally and a website also being hosted locally. I make a GET ajax request for JSON data which I handle on success. I have a problem where in Chrome and Firefox it goes into the error block of the Ajax request.
<!--jQuery dependencies-->
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.9.1/themes/base/jquery-ui.css" />
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.9.1/jquery-ui.min.js"></script>
<script type="text/javascript" src="../../Library/JS/pqgrid.min.js"></script>
<script type="text/javascript">
var jqNew = $.noConflict(true);
</script>
Because of the complexity of the website, I am using two different versions of JQuery. The newer version has the alias of jqNew.
jqNew(document).ready(function () {
$($.ajax({
url: "http://wks52025:82/WcfDataService.svc/GetNotesFromView()?$format=json",
type: "GET",
datatype: "json",
async: false,
success: function (data, textStatus) {
alert(textStatus);
$.each(data.d, function (i, item) {
alert(i);
DataArray[i] = [];
DataArray[i][0] = item.NotesID;
DataArray[i][1] = item.NotesTitle;
DataArray[i][2] = item.NotesText;
DataArray[i][3] = item.ProfileName;
DataArray[i][4] = item.IsShared;
DataArray[i][5] = item.NameOfUser;
});
},
error: function (data, textStatus) {
alert(textStatus);
}
})).then(buildGrid(DataArray));
This is my request. It is synchronous because I want the data before I build my grid. It is a GET request because all I want is to retrieve data. I am not doing a cross-domain request because everything is happening locally, at least I think it's local because the website and service is localhost.
//------------------------------------------------------------------------------
// <copyright file="WebDataService.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
using System;
using System.Data.Services;
using System.Data.Services.Common;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel.Web;
using System.Web;
using System.Data.Services.Parsing;
using WCFNotes;
[JSONPSupportBehavior]
public class WcfDataService : DataService< GenesisOnlineEntities >
{
// This method is called only once to initialize service-wide policies.
public static void InitializeService(DataServiceConfiguration config)
{
// TODO: set rules to indicate which entity sets and service operations are visible, updatable, etc.
// Examples:
config.UseVerboseErrors = true;
config.SetEntitySetAccessRule("*", EntitySetRights.All);
config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V3;
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
config.SetServiceOperationAccessRule("GetNotes", ServiceOperationRights.AllRead);
config.SetServiceOperationAccessRule("GetNotesFromView", ServiceOperationRights.AllRead);
config.SetServiceOperationAccessRule("AddNewNote", ServiceOperationRights.All);
config.SetServiceOperationAccessRule("UpdateNote", ServiceOperationRights.All);
config.SetServiceOperationAccessRule("DeleteNote", ServiceOperationRights.All);
}
protected override void OnStartProcessingRequest(ProcessRequestArgs args)
{
base.OnStartProcessingRequest(args);
//Cache for a minute based on querystring
//HttpContext context = HttpContext.Current;
HttpCachePolicy c = HttpContext.Current.Response.Cache;
c.SetCacheability(HttpCacheability.NoCache);
//c.SetExpires(HttpContext.Current.Timestamp.AddSeconds(60));
c.VaryByHeaders["Accept"] = true;
c.VaryByHeaders["Accept-Charset"] = true;
c.VaryByHeaders["Accept-Encoding"] = true;
c.VaryByParams["*"] = true;
}
[WebGet]
public IQueryable<tblNote> GetNotes()
{
IQueryable<tblNote> biglist = (from c in this.CurrentDataSource.tblNotes select c);
return biglist;
}
[WebGet]
public IQueryable<vw_Note> GetNoteByID(Guid NoteID)
{
IQueryable<vw_Note> biglist = (from c in this.CurrentDataSource.vw_Notes where c.NotesID.Equals(NoteID) select c);
return biglist;
}
[WebGet]
public IQueryable<vw_Note> GetNotesFromView()
{
Guid UserID = new Guid("8b0e303a-68aa-49a5-af95-d994e2bdd5ac");
IQueryable<vw_Note> biglist = (from c in this.CurrentDataSource.vw_Notes select c);
return biglist;
}
//[WebGet]
//public void AddNewNote(string ParamNoteTitle, string ParamNoteText)
//{
// //My hardcoded values for now...
// int ParentID = 8879;
// int JobID = 1000088150;
// int ContactID = 309;
// Guid UserID = Guid.NewGuid();
// string RelatedType = "Advertiser Contact";
// bool IsShared = true;
// tblNote N = new tblNote
// {
// NotesTitle = ParamNoteTitle,
// NotesText = ParamNoteText,
// ParentID = ParentID,
// ContactID = ContactID,
// JobID = JobID,
// UserID = UserID,
// GroupID = null,
// RelatedType = RelatedType,
// IsShared = IsShared
// };
// try
// {
// this.CurrentDataSource.tblNotes.Add(N);
// this.CurrentDataSource.SaveChanges();
// }
// catch (Exception ex)
// {
// }
//}
[WebGet]
public IQueryable<vw_Note> AddNewNote(string ParamNoteTitle, string ParamNoteText)
{
//My hardcoded values for now...
int ParentID = 8879;
int JobID = 1000088150;
int ContactID = 309;
Guid UserID = new Guid("8b0e303a-68aa-49a5-af95-d994e2bdd5ac");
Guid NoteID = Guid.NewGuid();
string RelatedType = "Advertiser Contact";
bool IsShared = true;
tblNote N = new tblNote
{
NotesID = NoteID,
NotesTitle = ParamNoteTitle,
NotesText = ParamNoteText,
ParentID = ParentID,
ContactID = ContactID,
JobID = JobID,
UserID = UserID,
GroupID = null,
RelatedType = RelatedType,
IsShared = IsShared
};
try
{
this.CurrentDataSource.tblNotes.Add(N);
this.CurrentDataSource.SaveChanges();
return GetNoteByID(NoteID);
}
catch (Exception ex)
{
return GetNoteByID(NoteID);
}
}
[WebGet]
public IQueryable<vw_Note> UpdateNote(string NoteID, string ParamNoteTitle, string ParamNoteText)
{
//My hardcoded values for now...
Guid GNoteID = Guid.Parse(NoteID);
try
{
tblNote n = CurrentDataSource.tblNotes.First(i => i.NotesID == GNoteID);
n.NotesTitle = ParamNoteTitle;
n.NotesText = ParamNoteText;
this.CurrentDataSource.SaveChanges();
return GetNoteByID(GNoteID);
}
catch (Exception ex)
{
return GetNoteByID(GNoteID);
}
}
[WebGet]
public IQueryable<vw_Note> DeleteNote(string NoteID)
{
Guid GNoteID = Guid.Parse(NoteID);
tblNote N = new tblNote
{
NotesID = GNoteID,
};
try
{
this.CurrentDataSource.tblNotes.Attach(N);
this.CurrentDataSource.tblNotes.Remove(N);
this.CurrentDataSource.SaveChanges();
// IF doesn't return value, delete was successful
return GetNoteByID(GNoteID);
}
catch (Exception ex)
{
return GetNoteByID(GNoteID);
}
}
}
This is my WCF service. Configuration is at the top of the code block.
Anyone know why this doesn't work in firefox and chrome?

Categories

Resources