PDA

View Full Version : QNetworkRequest atribute



mero
12th March 2011, 02:03
How can I set atribute of network request ?
I use this:



...
QNetworkRequest request;
request.setUrl(QUrl(strUrl));
request.setAttribute(QNetworkRequest::User, strTest1);
request.setAttribute(QNetworkRequest::UserMax, strCategory);
accessManager->get(request);
...

... net_finished(QNetworkReply *reply)
{
reply->deleteLater();

if (reply->error())
return;

QString strTest1 = reply->attribute(QNetworkRequest::User).toString();
QString strCategory = reply->attribute(QNetworkRequest::UserMax).toString();
QByteArray bData = reply->readAll();
...


but in net_finished strTest1 and strCategory is empty .. why ?

unit
12th March 2011, 08:50
From QT Doc:


QNetworkRequest::User. Special type. Additional information can be passed in QVariants with types ranging from User to UserMax. The default implementation of Network Access will ignore any request attributes in this range and it will not produce any attributes in this range in replies. The range is reserved for extensions of QNetworkAccessManager.

mero
12th March 2011, 13:58
So how I can add my own attributes/data to request ?

unit
12th March 2011, 14:07
Create your own class from QNetworkAccessManager or extension. I don't known how hard it. But you can read Network Access src code

mero
12th March 2011, 14:15
Create your own class from QNetworkAccessManager. I don't known how hard it. But you can read QNetworkAccessManager src code

It is too hard for too easy option. There should be another way to do this

unit
12th March 2011, 14:17
I don't kkown. QNetworkRequest::CustomVerbAttribute is only for request.

Let's tell what is your goal?

mero
12th March 2011, 14:24
Let's tell what is your goal?

I want to add 2 parameters to request, I will know then in finished() that kind of result reply contains, what kind of (my own) category

unit
12th March 2011, 14:28
Do you use many different request in one time in one class?

mero
12th March 2011, 14:36
Do you use many different request in one time in one class?
yes, thats why i need to add 2 parameters, because I use many requests, and I need to know (my own) category of reply

unit
12th March 2011, 14:49
Ok. Sorry me, i'm not software developer, but i think problem in your code architecture.

Try create class for each request. This class should do request and read reply. And have category or other attributes (and getters|setters :) ) I think it best way and solution.

And also you can ask Mr. Wysota for best architecture solition. He is very good programmer.

mero
12th March 2011, 14:59
Ok. Sorry me, i'm not software developer, but i think problem in your code architecture.

Try create class for each request. This class should do request and read reply. And have category or other attributes (and getters|setters :) ) I think it best way and solution.

And also you can ask Mr. Wysota for best architecture solition. He is very good programmer.

It's not architecture problem. Each request has my own named category, and I just want to add my variable to each request and read it in finished().

squidge
12th March 2011, 15:01
It is too hard for too easy option. There should be another way to do this

This is basic C++, it should not be too hard to implement. It is simple subclassing of existing object.

unit
12th March 2011, 15:02
What problem create class that do it? It will do request and have variable. It's more good and easy way as i think. Nut i'm not developer so i can mistake.

mero
12th March 2011, 15:15
What problem create class that do it? It will do request and have variable. It's more good and easy way as i think. Nut i'm not developer so i can mistake.

Categories are dynamic so creating class for earch category is impossible and idiotic.
There should be way to add my own string parameters to each request.

Wysota help ! :-)

unit
12th March 2011, 15:28
Categories are dynamic so creating class for earch category is impossible and idiotic.
There should be way to add my own string parameters to each request.

Wysota help ! :-)

No class for every category. :) Create class that do request and read reaply and have variable category.

And also try subclass QNetworkReply. I'm trying simple code for you, wait plz.

squidge
12th March 2011, 17:59
Categories are dynamic so creating class for earch category is impossible and idiotic.
There should be way to add my own string parameters to each request. You can simply subclass the object and provide get and set for a string parameter (or enum or integer, whichever). This would take less than 5 minutes to code and provide the functionality you request.

unit
12th March 2011, 18:36
Oh. You are right. Subclass any access network class is hard job and take long time.

And i known only two way:

1. you add variable to URL if server can ignore it and than parse it from reply->url();

2. or if you don't real need one connection access manager for all App, just create class that will be do request and read answer and have needed variables

I can suggest something like attached code

Plz, tell if attached code usefull for you, or should i find another solution

wysota
12th March 2011, 19:10
What do you need those extra values for? If they are to be parts of the request sent to the server then you should be using QNetworkRequest::setRawHeader(). If this is some kind of information you need for handling the reply then use QObject::setProperty() on the reply object you get when issuing a request to QNetworkAccessManager.

unit
12th March 2011, 19:24
QObject::setProperty() is good solution.

conner686
12th March 2011, 19:29
From QT Doc:


QNetworkRequest::User. Special type. Additional information can be passed in QVariants with types ranging from User to UserMax. The default implementation of Network Access will ignore any request attributes in this range and it will not produce any attributes in this range in replies. The range is reserved for extensions of QNetworkAccessManager.
I am pretty certain that is simply saying that the library will not touch anyhthing you put in that range, not that it won't allow you to pass information through them. Hence their choice of name "User" for the variable. Attributes put there stay there, they just don't automatically get forwarded to the resultant QNetworkReply* object because QNetworkAccessManager doesn't know if it is supposed to or not.

So you can still access it via `reply->request()->attribute(QNetworkRequest::User)`. Or you can insert it into the reply yourself:



...
QNetworkRequest request;
request.setUrl(QUrl(strUrl));
request.setAttribute(QNetworkRequest::User, strTest1);
request.setAttribute(QNetworkRequest::UserMax, strCategory);
//accessManager->get(request);
QNetworkReply* reply = accessManager->get(request);
reply->setAttribute(QNetworkRequest::User, strTest1);
reply->setAttribute(QNetworkRequest::UserMax, strCategory);
...

... net_finished(QNetworkReply *reply)
{
reply->deleteLater();

if (reply->error())
return;

QString strTest1 = reply->attribute(QNetworkRequest::User).toString();
QString strCategory = reply->attribute(QNetworkRequest::UserMax).toString();
//Or:
//QString strTest1 = reply->request()->attribute(QNetworkRequest::User).toString();
//QString strCategory = reply->request()->attribute(QNetworkRequest::UserMax).toString();

QByteArray bData = reply->readAll();
...

Both methods work for me at least. But I was just throwing code at a similar problem a few weeks ago until it started to function, so YMMV.

mero
12th March 2011, 20:51
QObject::setProperty() is good solution.



QNetworkRequest request;
request.setProperty("a123","b456");
...
accessManager->get(request);
....
...._finished(QNetworkReply *reply)
{
qDebug() << "test:" << reply->property("a123");
...


reply has property, but networkrequest not:



error: ‘class QNetworkRequest’ has no member named ‘setProperty’

stampede
12th March 2011, 20:56
Read again what wysota posted:

use QObject::setProperty() on the reply object you get when issuing a request to QNetworkAccessManager.

wysota
12th March 2011, 21:26
If you INSIST on using attributes, you can always do this:

class MyNetworkAccessManager : public QNetworkAccessManager {
public:
enum CustomAttribute { Attr1 = QNetworkRequest::User, Attr2 };
protected:
QNetworkReply * createRequest ( Operation op, const QNetworkRequest & req, QIODevice * outgoingData = 0 ) {
QNetworkReply *reply = QNetworkAccessManager::createRequest(op, req, outgoingData);
if(req.attribute(Attr1).isValid()) reply->setAttribute(Attr1, req.attribute(Attr1));
if(req.attribute(Attr2).isValid()) reply->setAttribute(Attr2, req.attribute(Attr2));
return reply;
}
};
... although I see no point in doing that. Attributes are there to mean something and not to provide storage for custom data. This is what dynamic properties are for.

unit
12th March 2011, 23:02
For your code is:


...
QNetworkRequest request;
request.setUrl(QUrl(strUrl));
QNetworkReply reply = accessManager->get(request);
reply->setProperty("test1", strTest1);
reply->setProperty("cat", strCategory);
...

... net_finished(QNetworkReply *reply)
{
reply->deleteLater();

if (reply->error())
return;

QString strTest1 = reply->property("test1").toString();
QString strCategory = reply->property("cat").toString();
QByteArray bData = reply->readAll();
...