I want to validate file. While file is invalid, i want to refresh my page and inform user that he did not upload proper file. So i have this in my
views/campaign.py
try:
wb = load_workbook(mp_file)
except BadZipfile:
return redirect('campaign_add', client_id)
The only way i know how to do it is add another attribute to client class which will be
is_error(models.BooleanField())
And then change views/campaign to
try:
client.is_error = False
wb = load_workbook(mp_file)
client.save()
except BadZipfile:
client.is_error = True
client.save()
return redirect('campaign_add', client)
And with another attribute i can add in my campaign.html file some kind of if is.error is true i'm adding some kind of windows with information about bad file after reloading page. But is there any way to do it without adding another attribute?
Ok, let's imagine that the answer is a little bit complicated than you've expected.
Modern UI's are not reloading pages just to inform about some errors with user input or upload.
So what is the best user experience here?
User is uploading some file(s) from the page.
You are sending a file via JavaScript to the dedicated API endpoint for this uploading. Let's say /workbook/uploads/. You need to create a handler for this endpoint (view)
Endpoint returns 200 OK with the empty body on success or an error, let's say 400 Bad Request with detailed JSON in the body to show to the user what's wrong.
You're parsing responses in JavaScript and show the user what's wrong
No refreshes are needed. 🙌
But the particular answer will need more code from your implementation. (view, urls, template)
I have an AspNet/AngularJS website (using System.Web.Http version 5.2.6.0), I'm adding card payment integration, with 3DS security. 3DS has this step called "data device gathering" where the PSP endpoint sends you back an url and you have to post it into a hidden iframe on the frontend.
Presumably there's some javascript that gathers the device data, and then redirects the iframe to an url you have provided. It almost doesn't matter what page is behind that url, the important thing is listening for the redirect. It just needs to contain some specific html so you can verify you were redirected to the correct page.
So I just added a static page to my website and provided the url. The redirect attempt resulted in "405 method not allowed" because the PSP's device gathering logic does a POST to the redirect url.
So I'm trying to make an API method that allows POST and returns a html page. This has proved unexpectedly challenging. These are some of the things I've tried from answers here on StackOverflow:
[HttpPost]
[AllowAnonymous]
[Route("methodnotification")]
public NegotiatedContentResult<string> MethodNotification()
{
return base.Content(System.Net.HttpStatusCode.OK,"<div id = \"threeDSMethodData\" name = \"threeDSMethodData\" > PROCESSING...</ div >");
}
This will return the following in PostMan:
"<div id = "threeDSMethodData" name = "threeDSMethodData" >
PROCESSING...</ div >"
It may look OK, but it's actually a string of type application/json; charset=utf-8. I tried the POST from FireFox, it returns this:
< string> <div id = "threeDSMethodData" name = "threeDSMethodData"
> PROCESSING...</ div > < /string>
Even setting the Accept header to only accept "text/html" will return a "plain text" not html.
I've tried different overloads of base.Content, which required me to add a "formatter" (if I also wanted to specify content type), and change the return type of the method to FormattedContentResult. After experimenting with different formatters I gave up because it just keeps giving me JSON or string.
I've also tried the following:
return new System.Web.Mvc.ContentResult
{
Content = "<div id = \"threeDSMethodData\" name = \"threeDSMethodData\" > PROCESSING...</ div >",
ContentType = "text/html"
};
Note the fully qualified name was necessary here because if I add a using statement for System.Web.Mvc, all my annotations start giving me "ambiguous reference" between System.Web.Mvc and System.Web.Http. This approach also returned a JSON file.
How do I return html from a POST in ASPNET?
EDIT: The API project targets .NET Framework 4.6. I wish I knew which version of ASPNET that corresponded to.
Try to change the function definition from
public NegotiatedContentResult<string> MethodNotification()
to
public ContentResult MethodNotification()
You should use NegotiatedContentResult if you are passing an object to be made text/json i.e:
NegotiatedContentResult<MyDTOClass>
This is why you receive the json string.
By spefifying NegotiatedContentResult<STRING> you break the text/html contentType, cause string implies, json string
I have a Blazor Webassembly project with a controller method as follows:
[HttpGet]
public async Task<List<string>> GetStatesForProfile()
{
IConfigurationSection statesSection = configuration.GetSection("SiteSettings:States");
var sections = statesSection.GetChildren();
var states = statesSection.GetChildren().Select(s => s.Key).ToList<string>();
return states;
}
The razor page calls this method:
private async Task<bool> GetStatesModel()
{
try
{
States = await http.GetJsonAsync<List<string>>("api/account/getstatesforprofile");
...
}
catch (Exception ex)
{
Console.WriteLine($"Exception: {ex.Message}, Inner: {ex.InnerException.Message}");
}
I get this Exception:
Exception: '<' is an invalid start of a value.
I read these values from appsettings.json file, And there is no '<' in values.
{
"SiteSettings": {
"States": {
"New York": ["NYC"],
"California": ["Los Angeles", "San Francisco"]
}
}
Also I put a breakpoint in the controller method and it doesn't hit.
What is this error? Is it from parsing json? and how to resolve this?
I had a very similar problem.
In the end it turned out that my browser had cached the HTML error page (I guess I had some problems with the code when I first tried it). And no matter how I tried fixing the code I still only got the error from cache. Clearing my cache also cleared the problem.
It happens when you're trying to access an API that doesn't exist. You have to check your API project connectionstring under AppSettings and make sure it's correct and running. If it's a Blazor project, you can set it as your default project, execute and see if you get a json response.
Most probably the response you are receiving is html instead of actual JSON format for the endpoint you are requesting. Please check that.
An as HTML usually starts with <html> tag, the JSON validator fails on the very first character.
You should also clear any cache, that might be interfering with the returned data. (this has helped people resolve this same issue)
I know this is an old question, but it's one of the top results when Googling the error.
I've just spent more time than I care to admit to tracking down this error. I had a straightforward Blazor hosted app, basically unchanged from the template. It worked just fine when run locally, but when published to my web host API calls failed. I finally figured out that the problem was that I was running the publish from the Client project. When I changed to the Server project it worked properly.
Hopefully my long frustration and slight stupidity will save someone else making a similar mistake.
Seems like your api is not not accessible and its returning error HTML page by default.
You can try below solution:-
I think you are using httpclient to get data to blazor application.
If you have separate projects in solution for blazor and web api,
currently your startup application may set to run blazor project only.
Change startup projects to multiple (blazor and web api app) and give httpClient url in startup of blazor application, as webApi application url, that may solve your issue.
This error indicates a mismatch of the project targeting framework version and installed runtime on the machine. So make sure that the target framework for your project matches an installed runtime - this could be verified by multiple means; one of them is to check out the Individual Components tab of the Visual Studio Installer and lookup the target version.
E.g., there is the TargetFramework attribute in the proj file:
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
Then launch the Visual Studio Installer, click Modify, and visit the Individual Components tab:
Install the missing runtime (.NET 5 Runtime in this case) and you're good to go.
I got the same error. Red herring. use your browser or postman to check your api endpoint is returning the json data and not some HTML. In my case my "api/companytypes" had a typo.
private CompanyType[] companytypesarray;
private List<CompanyType> CompanyTypeList;
private List<CompanyType> CompanyTypeList2;
public async Task<bool> LoadCompanyTypes()
{
//this works
CompanyTypeList = await Http.GetFromJsonAsync<List<CompanyType>>("api/companytype");
//this also works reading the json into an array first
companytypesarray = await Http.GetFromJsonAsync<CompanyType[]>("api/companytype");
CompanyTypeList2 = companytypesarray.ToList();
return true;
}
I know this is an old question, but I had the same problem. It took some searching, but I realized that the return data was in XML instead of JSON.
I'm assuming your "http" variable is of type HttpClient, so here's what I found worked for me.
By setting the "Accept" header to allow only JSON, you avoid a miscommunication between your app and the remote server.
http.DefaultRequestHeaders.Add("Accept", "application/json");
States = await http.GetJsonAsync<List<string>>("api/account/getstatesforprofile");
I had the same issue when passing in an empty string to a controller method. Creating a second controller method that doesn't accept any input variables, and just passing an empty string to the first method helped to fix my problem.
[HttpGet]
[ActionName("GetStuff")]
public async Task<IEnumerable<MyModel>> GetStuff()
{
return await GetStuff("");
}
[HttpGet("{search}")]
[ActionName("GetStuff")]
public async Task<IEnumerable<MyModel>> GetStuff(string search)
{
...
}
Versions of package
Try to update your packages to old or new version. In my case, system.net.http.json is updated from 6.0 to 5.0
Likely you are using an Asp.NetCore hosted WASM application. By default the client's App.razor has something similar to:
<CascadingAuthenticationState>
<Router AppAssembly="#typeof(Program).Assembly">
<Found Context="routeData">
<AuthorizeRouteView DefaultLayout="#typeof(MainLayout)"
RouteData="#routeData">
<NotAuthorized>
<RedirectToLogin />
</NotAuthorized>
<Authorizing>
<Loading Caption="Authorizing..."></Loading>
</Authorizing>
</AuthorizeRouteView>
</Found>
<NotFound>
<LayoutView Layout="#typeof(MainLayout)">
<p>Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router>
</CascadingAuthenticationState>
Herein lies the problem. Since the Client and Server share the same base address, when the application cannot find "api/account/getstatesforprofile" it gives you the client's "Sorry, there's nothing at the address" page. Which is of course HTML.
I have not found the solution to this issue, but I am working on it and will reply once I find an issue.
I was having the same problem,
"JsonReaderException: '<' is an invalid start of a value."
In my case the url for the REST service was wrong.
I was using the URL from the client project. Then I looked at the Swagger screen,
https://localhost:44322/swagger/index.html
and noticed the right URL should start with "44322"...
Corrected, worked.
In my case, I had a comma (,) written mistakenly at the beginning of the appsettings.json file ...
Just check your file and verify
///////
my error details
//////
System.FormatException HResult=0x80131537 Message=Could not parse the JSON file.
Source=Microsoft.Extensions.Configuration.Json StackTrace: at line 16 This exception was originally thrown at this call stack: [External Code] Inner Exception 1: JsonReaderException: ',' is an invalid start of a value. LineNumber: 0 | BytePositionInLine: 0.
////
For me, most of the time it is the #lauri-peltonen answer above. However, now and again, depending on who wrote the controller I have found that this will work in Swagger but not when you call it via the client (at least in this Blazor project we are on.)
[HttpGet]
[Route("prog-map-formulations")]
public async Task<List<GetProgramMapFormulationsResult>> GetProgramMapFormulations(int formulationId)
{
...
}
It sends the request as:
api/formulation-performance-program-map/analytical-assoc-values?formulationId=1
And I get results in Swagger but failes with the '<' OP error.
When I change ONLY the route to:
[HttpGet]
[Route("prog-map-formulations/{formulationId:int}")]
public async Task<List<GetProgramMapFormulationsResult>> GetProgramMapFormulations(int formulationId)
{
...
}
It sends the request as:
api/formulation-performance-program-map/analytical-assoc-values/1
And this works in both Swagger as well as from the Client side in Blazor.
Of course, once updated, I did have to clear the cache!
If you delete "obj" folder in your directory then clean the solution and rebbuild it the exception will be resolved
In all these, there is two things that was my issue and realized, first off was that Route[("api/controller")] instead of Route[("api/[controller]")], that is missing square brackets. In the second exercise I was doing, with the first experience in mind, was from the name of the database. The database had a dot in the name (Stock.Inventory). When I change the database name to StockInventory it worked. The second one I am not so sure but it worked for me.
I am trying to read a JSON file with Meteor. I've seen various answers on stackoverflow but cannot seem to get them to work. I have tried this one which basically says:
Create a file called private/test.json with the following contents:
[{"id":1,"text":"foo"},{"id":2,"text":"bar"}]
Read the file contents when the server starts (server/start.js):
Meteor.startup(function() {
console.log(JSON.parse(Assets.getText('test.json')));
});
However this seemingly very simple example does not log anything to the console. If I trye to store it in a variable instead on console.logging it and then displaying it client side I get
Uncaught ReferenceError: myjson is not defined
where myjson was the variable I stored it in. I have tried reading the JSON client side
Template.hello.events({
'click input': function () {
myjson = JSON.parse(Assets.getText("myfile.json"));
console.log("myjson")
});
}
Which results in:
Uncaught ReferenceError: Assets is not defined
If have tried all of the options described here: Importing a JSON file in Meteor with more or less the same outcome.
Hope someone can help me out
As per the docs, Assets.getText is only available on the server as it's designed to read data in the private directory, to which clients should not have access (thus the name).
If you want to deliver this information to the client, you have two options:
Use Assets.getText exactly as you have done, but inside a method on the server, and call this method from the client to return the results. This seems like the best option to me as you're rationing access to your data via the method, rather than making it completely public.
Put it in the public folder instead and use something like jQuery.getJSON() to read it. This isn't something I've ever done, so I can't provide any further advice, but it looks pretty straightforward.
The server method is OK, just remove the extra semi-colon(;). You need a little more in the client call. The JSON data comes from the callback.
Use this in your click event:
if (typeof console !== 'undefined'){
console.log("You're calling readit");
Meteor.call('readit',function(err,response){
console.log(response);
});
}
Meteor!
For some reason, any document I upload to OneNote via the new REST API is corrupt when viewed from OneNote. Everything else is fine, but the file (for example a Word document) isn't clickable and if you try and open is shows as corrupt.
This is similar to what may happen when there is a problem with the byte array, or its in memory, but that doesn't seem to be the case. I use essentially the same process to upload the file bytes to SharePoint, OneDrive, etc. It's only to OneNote that the file seems to be corrupt.
Here is a simplified version of the C#
HttpRequestMessage createMessage = null;
HttpResponseMessage response = null;
using (var streamContent = new ByteArrayContent(fileBytes))
{
streamContent.Headers.ContentType = new MediaTypeHeaderValue("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
streamContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data");
streamContent.Headers.ContentDisposition.Name = fileName;
createMessage = new HttpRequestMessage(HttpMethod.Post, authorizationUrl)
{
Content = new MultipartFormDataContent
{
{
new StringContent(simpleHtml,
System.Text.Encoding.UTF8, "text/html"), "Presentation"
},
{streamContent}
}
};
response = await client.SendAsync(createMessage);
var stream = await response.Content.ReadAsStreamAsync();
successful = response.IsSuccessStatusCode;
}
Does anyone have any thoughts or working code uploading an actual binary document via the OneNote API via a Windows Store app?
The WinStore code sample contains a working example (method: CreatePageWithAttachedFile) of how to upload an attachment.
The slight differences I can think of between the above code snippet and the code sample are that the code sample uploads a pdf file (instead of a document) and the sample uses StreamContent (while the above code snippet uses ByteArrayContent).
I downloaded the code sample and locally modified it to use a document file and ByteArrayContent. I was able to upload the attachment and view it successfully. Used the following to get a byte array from a given stream:
using (BinaryReader br = new BinaryReader(stream))
{
byte[] b = br.ReadBytes(Convert.ToInt32(s.Length));
}
The rest of the code looks pretty similar to the above snippet and overall worked successfully for me.
Here are a few more things to consider while troubleshooting the issue:
Verify the attachment file itself isn't corrupt in the first place. for e.g. can it be opened without the OneNote API being in the mix?
Verify the API returned a 201 Http Status code back and the resulting page contains the attachment icon and allows downloading/viewing the attached file.
So, the issue was (strangely) the addition of the meta Content Type in the tag sent over in the HTML content that's not shown. The documentation refers to adding a type=[mime type] in the object tag, and since the WinStore example didn't do this (it only adds the mime type to the MediaTypeHeaderValue I removed it and it worked perfectly.
Just changing it to this worked:
<object data-attachment=\"" + fileName + "\" data=\"name:" + attachmentPartName + "\" />
Thanks for pointing me in the right direction with the sample code!