Can't take file from server - javascript

I use Asp.Net WebApi and jQuery.
From page to WebApi i send 'POST' HTTP-Request with object.
$.ajax({
type: "POST",
url: "api/Result",
data: JSON.stringify(makeResultInfo()),//makeResultInfo - function that returns object
contentType: "application/json; charset=utf-8",
dataType: "json",
processData: true,
success: function (data) {
window.location = data;
alert("success");
},
error: function (xhr) {
alert('error');
}
});
WebApi take object correctly and return Excel-file.
[HttpPost]
public HttpResponseMessage Post([FromBody]ResultInfo value)
{
ExcelClass ec = new ExcelClass();
var stream = ec.GetStream(ec.mini_wb);//после теста поправить
// processing the stream.
var result = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new ByteArrayContent(stream.ToArray())
};
result.Content.Headers.ContentDisposition =
new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment")
{
FileName = "test.xlsx"
};
result.Content.Headers.ContentType =
new MediaTypeHeaderValue("application/octet-stream");
return result;
}
When i make Request to 'api/Result' without parameters - file downloading correctly. But when i send object, response incorrect always and alert always write 'error'.
How i can send object and take file in browser?

Related

Sending strings to MVC Controller via AJAX

I am trying to send data via AJAX to MVC Controller method. I am trying to make booking system app. I want to check that user input exists in Entity Model. Ajax is pushing parameters to method controller but i don't get response.
Here is my AJAX call in View:
var check = document.getElementById('check');
//starttime.onchange = checkvalidate(startdate, starttime);
$(check).click(function (datevalue, timevalue) {
var startdate = document.getElementById('startdate');
var starttime = document.getElementById('starttime');
var log = document.getElementById('log');
var datevalue = startdate.value;
var timevalue = starttime.value;
$.ajax({
type: "POST",
url: "/Home/CheckValidate",
data: { 'start': datevalue, 'time': timevalue },
dataType: "Boolean",
success: function (response) {
console.log = response;
if (response == true) {
log.value = "YES";
} else
{
log.value = "NO";
}
}
})
})
And method in controller:
public bool CheckValidate(string start, string time)
{
string datastart = start + " " + time;
DateTime startDate = Convert.ToDateTime(datastart);
EventsEntities dc = new EventsEntities();
var MatchedElements = dc.Events.Where(x => x.start <= startDate && startDate < x.end).FirstOrDefault();
if (MatchedElements == null)
{
return true;
} else
{
return false;
}
}
I want to send string inputs and get back data to show message that is possible to book that room.
Where did I mistake?
You can do like this.
var obj = {};
obj.startdate = document.getElementById('startdate');
obj.starttime = document.getElementById('starttime');
$.ajax({
type: "POST",
url: "/Home/CheckValidate",
data: JSON.stringify(obj),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: OnSuccess,
failure: function (response) {
//failure message
}
});
function OnSuccess(response) {
//do your stuff after success response
}
There are a few things missing from your ajax call. You need to specify data you're sending in such way so that it is sent as JSON and properly. To do that you need to stringify your javascript json object and declare that you're sending a JSON data type. Here is your click event handler code with changes:
$(check).click(function () {
var data = {
start: datevalue,
time: timevalue
};
$.ajax({
type: "POST",
url: "/Home/CheckValidate",
data: JSON.stringify(data),
contentType: "application/json; charset=utf-8",
dataType: "boolean",
success: function (response) {
if (response) {
log.val = "YES";
} else {
log.val = "NO";
}
}
})
});
You can read more about it here: jquery ajax documentation
There are also other existing question here that already answer your question such as this one.

Return JSON instead of XML from web service using Ajax while 'contentType' is 'false'

I made an AJAX call to send an image file to one of my web service (.asmx) methods. Everything's okay, but the problem is that the web service returns XML instead of JSON because I HAVE TO set 'contentType' to 'false', otherwise file can't be sent. (If I set contentType to application/json; charset=utf-8, it returns JSON but I can't do that because I'm sending a file.)
This is my JavaScript:
function setAvatar(imageFile, successCallback) {
var formData = new FormData();
formData.append("UploadedAvatar", imageFile);
$.ajax({
type: "POST",
url: "/Services/UserService.asmx/SetAvatar",
contentType: false,
processData: false,
dataType: 'json',
data: formData,
success: function (result) {
alert(result.d);
alert(result.d.IsSuccessful);
if (typeof successCallback === 'function')
successCallback(result);
}
});
And the web service method:
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public Result SetAvatar()
{
HttpPostedFile postedFile = HttpContext.Current.Request.Files["UploadedAvatar"];
Image avatar = Image.FromStream(postedFile.InputStream, true, true);
avatar = new Bitmap(avatar, new Size(150, 150));
avatar.Save(Path.Combine(path, $"Avatar-Small.jpg"), System.Drawing.Imaging.ImageFormat.Jpeg);
return new Result(true, Messages.AvatarSavedSuccessfully);
}
Set the Accept header when making the request to expect JSON
$.ajax({
type: "POST",
url: "/Services/UserService.asmx/SetAvatar",
headers: { //SET ACCEPT HEADER
Accept : "application/json; charset=utf-8",
},
contentType: false,
processData: false,
dataType: 'json',
data: formData,
success: function (result) {
alert(result.d);
alert(result.d.IsSuccessful);
if (typeof successCallback === 'function')
successCallback(result);
}
});
On the server side, using Json.Net you can serialize the result
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public string SetAvatar() {
HttpPostedFile postedFile = HttpContext.Current.Request.Files["UploadedAvatar"];
Image avatar = Image.FromStream(postedFile.InputStream, true, true);
avatar = new Bitmap(avatar, new Size(150, 150));
avatar.Save(Path.Combine(path, $"Avatar-Small.jpg"), System.Drawing.Imaging.ImageFormat.Jpeg);
var result = new Result(true, Messages.AvatarSavedSuccessfully);
return JsonConvert.SerializeObject(result);
}
This should allow the response to be in the desired type
You need to update your .NET code and add options.RespectBrowserAcceptHeader = true
services
.AddMvc(options => {
options.RespectBrowserAcceptHeader = true;
})
//support application/xml
.AddXmlDataContractSerializerFormatters()
//support application/json
.AddJsonOptions(options => {
// Force Camel Case to JSON
options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
});
The dataType: 'json' will automatically add the Accept header as below
"accept":"application/json, text/javascript, */*; q=0.01"
If you specifically want just application/json, then you need to add below to your ajax options
headers: {
Accept : "application/json; charset=utf-8"
}
After beating my head against the wall for many days, I finally figured out the solution which belongs to Ajay, here.
While nothing else has helped me, I used this and it worked perfectly:
Change the return type of your method to void.
And then instead of writing the return statement in your method, you need to do this to return a value:
Context.Response.ContentType = "application/json; charset=utf-8";
Context.Response.Write(new JavaScriptSerializer().Serialize(new YourData()));
After that you can easily get the result using the success event of the Ajax call:
success: function (result) {
alert(result.Property); // Note: Don't use result.d here
}

MVC maxJsonLength error

I'm struggling with maxJsonLength error.
I'm passing very long xml string (~4MB) from controller action to javascript method in a View. This method proceses data and send it back with AJAX to another controller method, and here I'm getting error.
I've set MaxJsonLength in JsonResult object, in the controller method, and the is no problem with passing this string from controller to view.
But when I'm try to pass it back after processing I'm getting error.
This is my Controller method whitch prepare data:
private JsonResult PrepareXml(int someId)
{
// preparing data...
string xmlData = "..."; //(~4Mb)
JsonResult res = Json(xmlData);
res.MaxJsonLength = 10000000; // 10Mb
return res;
}
And this is my Controller method whitch is trying to proces data passed from ajax method:
private JsonResult GetProcesedXml(string resultXml)
{
// This method is not ivoking
}
And below is my script method:
var data = {
someId: rowId,
};
$.ajax({
type: "POST",
url: "MyController/PrepareXml",
data: data,
contentType: "application/json; charset=utf-8",
success: function (result) {
// proces the result (big xml file)
//...
var processedResult = ""; // size of processedResult is a little bit bigger than 'result'
var data2 = {
resultXml: processedResult
};
$.ajax({
type: "POST",
url: "MyController/GetProcesedXml",
data: data2,
contentType: "application/json; charset=utf-8",
success: function (r) {
alert('success');
},
error: function (data) {
alert(data.responseText);
}
});
}
});
What I've tried already:
<add key="aspnet:MaxJsonDeserializerMembers" value="2147483647" /> //(max value)
<requestLimits maxAllowedContentLength="2097151000" /> //(max value)
<httpRuntime maxRequestLength="10000" /> //(~10MB)
I've found some workaround for this problem.
I've changed content type in Ajax method to "text/plain" and used JSON.stringify on my xml file data.
var data2 = { resultXml: processedResult };
$.ajax({
type: "POST",
url: "MyController/GetProcesedXml",
data: JSON.stringify(data2),
contentType: "text/plain",
success: function (r) {
alert('success');
},
});
Another change is in controller. I've read file from input stream and parse it to form JSON type:
private JsonResult GetProcesedXml()
{
JObject json = null;
Stream request = Request.InputStream;
using (StreamReader sr = new StreamReader(stream))
{
stream.Seek(0, System.IO.SeekOrigin.Begin);
json = JObject.Parse(sr.ReadToEnd());
}
string xmlSigninigResult = json["resultXml"].ToString();
// rest of the method
}

Calling Rest Api from classic ASP

I need to call Api using ajax in javascript.
I have used following code to call api
$.ajax({
type: 'GET',
//contentType: "application/json; charset=utf-8",
url: 'http://localhost:51870/api/Home/Get',
dataType:'json',
success: function (data) {
debugger;
alert(data);
},
error: function (error) {
debugger;
alert('error; ' + eval(error));
}
});
and Code for API is
[System.Web.Http.HttpGet]
public JsonResult Get()
{
List<PieChartValue> lstPieChartValue = new List<PieChartValue>();
PieChartValue p1 = new PieChartValue
{
ColumnName = "text",
Value = 100
};
PieChartValue p2 = new PieChartValue
{
ColumnName = "text",
Value = 200
};
lstPieChartValue.Add(p1);
lstPieChartValue.Add(p2);
return new JsonResult(){ Data = lstPieChartValue };
}
I am getting error:
No 'Access-Control-Allow-Origin' header is present on the requested resource
Thanks.

Web service receiving null with jQuery post JSON

The web service on http://localhost:57501/api/addDatabase has the following code.
[System.Web.Mvc.HttpPost]
public ActionResult Post(addDatabase pNuevaConeccion)
{
pNuevaConeccion.insertarMetaData();
return null;
}
The Ajax function is on a javascript that creates the JSON from the give values on http://localhost:1161/CreateServer.
$(document).ready(function ()
{
$("#createServer").click(function (e) {
e.preventDefault(); //Prevent the normal submission action
var frm = $("#CreateServerID");
var dataa = JSON.stringify(frm.serializeJSON());
console.log(dataa);
$.ajax({
type: 'POST',
url: 'http://localhost:57501/api/addDatabase/',
contentType: 'application/json; charset=utf-8',
crossDomain: true,
//ContentLength: dataa.length,
data: dataa,
datatype: 'json',
error: function (response)
{
alert(response.responseText);
},
success: function (response)
{
alert(response);
if (response == "Database successfully connected") {
var pagina = "/CreateServer"
location.href = pagina
}
}
});
});
});
When I run this code an alert pops up saying "undefined" but if I delete the contentType the alert doesn't show up. The problem is that the variables that the function Post (from the web service) receives are NULL even though I know that the JSON named dataa is not NULL since I did a console.log.
I have seen various examples and pretty much all of them say that I should use a relative URL but the problem is that since there are 2 different domains and when I tried it, it couldn't find the URL since it's not in the same localhost.
Web service should return a JSON format instead of null. like below example.
public JsonResult Post()
{
string output = pNuevaConeccion.insertarMetaData();
return Json(output, JsonRequestBehavior.AllowGet);
}
try to use this code for calling the web method
$.ajax({
method: "POST",
contentType: "application/json; charset=utf-8",
data: dataa,
url: 'http://localhost:57501/api/addDatabase/',
success: function (data) {
console.log(data);
},
error: function (error) {
console.log(error);
}
});
its my old code.(ensure action parameter variable name and post variable name are same)
$('#ConnectionAddres_ZonesId').change(function () {
var optionSelected = $(this).find("option:selected");
var id = { id: optionSelected.val() };
$.ajax({
type: "POST",
url: '#Url.Action("GetParetArea", "Customers")',
contentType: "application/json;charset=utf-8",
data: JSON.stringify(id),
dataType: "json",
success: function (data) {
$('#ConnectionAddres_ParentAreaId').empty().append('<option value="">Select parent area</option>');
$.each(data, function (index, value) {
$('#ConnectionAddres_ParentAreaId').append($('<option />', {
value: value.Id,
text: value.Area
}));
});
},
});
});
public ActionResult GetParetArea(int id)
{
var parents="";
return Json(parents, JsonRequestBehavior.AllowGet);
}

Categories

Resources