I am using QXmlSchemaValidator to validate my xml against different xsds.
My code is as follows:
bool MyClass::verify(QByteArray message)
{
bool successfulValidated = false;
for(QByteArray& xsd: _xsds)
{
QXmlSchema schema;
schema.load(xsd);
if(!schema.isValid())
throw Exception("schema not valid");
QXmlSchemaValidator msgValidator(schema);
if(msgValidator.validate(message))
{
successfulValidated = true;
break;
}
}
return successfulValidated;
}
If msgValidator.validate(message) is false I get and application output like
Error XSDError in file:///MyApplication.exe, at line 1, column 47: No definition for element MyXMLElement available.
I do not want these application output messages as they clutter my output window. Is there any way that I can either suppress these messages or handle them myself?
In case anyone has the same problem:
Just add your own MessageHandler to the QXmlSchema as described in this Topic.
Related
I have dotnet WebAPI and I'm trying to get a specific behaviour but am constantly getting 415 responses.
I have reproduced this by starting a new webapi project using dotnet new webapi on the command line. From there, I added two things: a new controller, and a model class. In my real project the model class is obviously a bit more complex, with inheritance and methods etc...
Here they are:
[HttpGet("/data")]
public async Task<IActionResult> GetModel(BodyParams input)
{
var response = new { Message = "Hello", value = input.valueOne };
return Ok(response);
}
public class BodyParams {
public bool valueOne { get; set; } = true;
}
My goal is that the user can call https://localhost:7222/data with no headers or body needed at all, and will get the response - BodyParams will be used with the default value of true. Currently, from postman, or from the browser, I get a 415 response.
I've worked through several suggestions on stack and git but nothing seems to be working for me. Specifically, I have tried:
Adding [FromBody(EmptyBodyBehavior = EmptyBodyBehavior.Allow)] into the controller, but this makes no difference unless I provide an empty {} json object in the body. This is not what I want.
Making BodyParams nullable - again, no change.
Adding .AddControllers(opt => opt.AllowEmptyInputInBodyModelBinding = true)... again, no change.
I Implemented the solution suggested here using the attribute modification in the comment by #HappyGoLucky. Again, this did not give the desired outcome, but it did change the response to : 400 - "The input does not contain any JSON tokens. Expected the input to start with a valid JSON token, when isFinalBlock is true."
I tried modifying the solution in (4) to manually set context.HttpContext.Request.Body to an empty json object... but I can't figure out the syntax for this because it need to be a byte array and at that point I feel like I am way over complicating this.
How can I get the controller to use BodyParams with default values in the case that the user provides no body and no headers at all?
You can achieve that using a Minimal API.
app.MapGet("/data",
async (HttpRequest httpRequest) =>
{
var value = true;
if (Equals(httpRequest.GetTypedHeaders().ContentType, MediaTypeHeaderValue.Parse("application/json")))
{
var bodyParams = await httpRequest.ReadFromJsonAsync<BodyParams>();
if (bodyParams is not null) value = bodyParams.ValueOne;
}
var response = new {Message = "Hello", value};
return Results.Ok(response);
});
So, as there doesn't seem to be a more straightforward answer, I have currently gone with the approach number 5) from the OP, and just tweaking the code from there very slightly.
All this does is act as an action which checks the if the user has passed in any body json. If not, then it adds in an empty anonymous type. The behaviour then is to use the default True value from the BodyParams class.
The full code for the action class is:
internal class AllowMissingContentTypeForEmptyBodyConvention : Attribute, IActionModelConvention
{
public void Apply(ActionModel action)
{
action.Filters.Add(new AllowMissingContentTypeForEmptyBodyFilter());
}
private class AllowMissingContentTypeForEmptyBodyFilter : IResourceFilter
{
public void OnResourceExecuting(ResourceExecutingContext context)
{
if (!context.HttpContext.Request.HasJsonContentType()
&& (context.HttpContext.Request.ContentLength == default
|| context.HttpContext.Request.ContentLength == 0))
{
context.HttpContext.Request.ContentType = "application/json";
var str = new { };
//convert string to jsontype
var json = JsonConvert.SerializeObject(str);
//modified stream
var requestData = Encoding.UTF8.GetBytes(json);
context.HttpContext.Request.Body = new MemoryStream(requestData);
}
}
public void OnResourceExecuted(ResourceExecutedContext context)
{
// Do nothing
}
}
}
Then you can add this to any of your controllers using [AllowMissingContentTypeForEmptyBodyConvention]
If there's an unhandled server error 500 in ASP.NET MVC, the server returns a HTML page like this:
Question: is it possible to configure the application so that it returns a JSON with the same information instead of the above HTML?
eg:
{
Title:'Maximum request length exceeded',
Description:'An unhandled eception .....',
...etc
}
you need to catch the error somehwere appropriate [i suggest use custom error filter on the controller for example that inherits from HandleErrorAttribute], and override OnException method, from there you can check if it is Ajax, then do something else, here is a snippet that i wrote before (not clean yet)
and dont forget to set the status code!
if (filterContext.HttpContext.Request.IsAjaxRequest())
{
JsonResultObject result = new JsonResultObject();
result.Success = false;
string message = ("Common.WeAreFixing" + " , #" + errorLog.Id.ToString("00000"));
if (filterContext.HttpContext.Request.IsLocal)
{
message = filterContext.Exception.Message + Environment.NewLine + "st: " +
(filterContext.Exception.StackTrace ?? "");
}
result.AlertMessage = new Alert(message, Alert.Type.Error);
filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
filterContext.Result = new JsonDotNetResult()
{
JsonRequestBehavior = JsonRequestBehavior.AllowGet,
Data = result
};
filterContext.HttpContext.Items["ErrorNumber"] = errorLog.Id.ToString("00000");
}
Within exceptions there is sensitive information including stack details that should not be leaked to the consumer however as you are showing the error screen i am presuming that this is running in a debug environment and that is not an issue.
Also in a non debug environment the exception details may be stripped out of the response so ideally you should form a custom message of Json format that is based off that exception and then log the original stack details so you can handle the issue at a later date.
Something like the below should get you started:
try
{
// do some work
}
catch (ExplicitException ex)
{
// Log the exception(ex);
var message = "Error Doing Work");
return Json(new { status = "Error", message });
}
}
I used the MSDN guide on creating Custom Extraction Rule, which presents this example (Extract method):
public override void Extract(object sender, ExtractionEventArgs e)
{
if (e.Response.HtmlDocument != null)
{
foreach (HtmlTag tag in e.Response.HtmlDocument.GetFilteredHtmlTags(new string[] { "input" }))
{
if (String.Equals(tag.GetAttributeValueAsString("name"), Name, StringComparison.InvariantCultureIgnoreCase))
{
string formFieldValue = tag.GetAttributeValueAsString("value");
if (formFieldValue == null)
{
formFieldValue = String.Empty;
}
// add the extracted value to the web performance test context
e.WebTest.Context.Add("someNameHere", formFieldValue);
e.Success = true;
return;
}
}
}
// If the extraction fails, set the error text that the user sees
e.Success = false;
e.Message = String.Format(CultureInfo.CurrentCulture, "Not Found: {0}", Name);
}
However, I just don't know how to use access the someNameHere in the Web Test and add it to the QueryString as a parameter.
Any help would be greatly appreciated.
Right-click on the request in the web test and select "Add URL query string parameter". Alter the name as needed and into the value field enter {{someNameHere}}. The doubled curly braces call for a context parameter value to be inserted. The doubled curly braces can be used to insert the value of a context parameter into many other places in a web test. Note that strings such as text{{someNameHere}}moretext can be used to join context values to other strings.
Simple question is, how do i detect in actionscript if user have blocked from writing data to shared object?
sharedObj = SharedObject.getLocal("rememberme");
This return always shared object but it's size is 0, even I have blocked shared object.
When I'm trying to save data to shared object and flush it, it throws me an error, because writing is blocked. So what would be the right way check if writing to shared object is disabled?
Error: Error #2130: Unable to flush SharedObject.
var my_so:SharedObject = SharedObject.getLocal("mySpace");
var flushStatus:String = null;
try {
flushStatus = my_so.flush();
} catch (error:Error) {
trace("Error...Could not write SharedObject to disk\n");
}
if (flushStatus != null) {
switch (flushStatus) {
case SharedObjectFlushStatus.PENDING :
trace("Requesting permission to save object...\n");
my_so.addEventListener(NetStatusEvent.NET_STATUS, onFlushStatus);
break;
case SharedObjectFlushStatus.FLUSHED :
trace("Value flushed to disk.\n");
break;
}
}
function onFlushStatus(event:NetStatusEvent):void {
trace("User closed permission dialog...\n");
switch (event.info.code) {
case "SharedObject.Flush.Success" :
trace("User granted permission -- value saved.\n");
break;
case "SharedObject.Flush.Failed" :
trace("User denied permission -- value not saved.\n");
break;
}
my_so.removeEventListener(NetStatusEvent.NET_STATUS, onFlushStatus);
}
If shared object is blocked u can catch the error report else if 0 it goes to SharedObjectFlushStatus.PENDING.
SOURCE
Cant find any solution for this. Im trying to store some data on remote shared object and retrieve it. At the moment im working locally. Anyway, i read probably all posts on internet about that and still cant understand where is my problem. I managed to store arguments on rso, but when i tried to receive those values, im only getting undefined.
Here is my code for the version when im only working with client side and on server side just watching when client connects to shared objects or changes the value.
protected function application1_creationCompleteHandler(event:FlexEvent):void {
var room_id:Number = vars("room");
connection = new NetConnection();
connection.connect("rtmp://127.0.0.1/video/" + room_id);
connection.addEventListener(NetStatusEvent.NET_STATUS, onConnected);
connection.client = this;
}
private function onConnected(event:NetStatusEvent) : void {
if(event.info.code == "NetConnection.Connect.Success") {
so = SharedObject.getRemote("video", connection.uri, true);
so.addEventListener(SyncEvent.SYNC, onSync);
so.connect(connection);
// if i try to trace so in there it will be undefined
} else {
Alert.show("Unsuccessful Connection", "Information");
}
And finally:
private function onSync(event:SyncEvent):void {
for(var i:Object in event.changeList) {
var changeObj:Object = event.changeList[i];
switch(changeObj.code) {
case "success":
if(so.data.cameras) {
Alert.show(this.so.data.cameras.toString(), "I changed it");
} else {
Alert.show("I changed", "Information");
}
break;
case "change":
if(so.data.cameras)
Alert.show(so.data.cameras.toString(), "First");
else if (this.so.data.cameras) {
Alert.show(this.so.data.cameras.toString(), "Second");
} else {
Alert.show("Can't found changed value", "Error");
}
break;
}
}
}
And here we go, i always get the undefined value of cameras, unless im the client who is changing the value, but everybody else gets undefined value. So i cant understand, all listeners a noticed about changes, on the server side code i see that i have changes, and i even opened persistent red5 shared object file and i see there is value, but i just cant retrieve it. Anybody has a solution? I would be very grateful.
Updated:
Answer is here: rso between flex and red5. I can create but cant read