如何使用HttpWebRequest或MetaWeblog API在DotClear博客中添加Category

时间:2009-11-10 16:52:20

标签: c# httpwebrequest

我正在尝试创建/修改dotclear博客。

对于大多数选项,我使用XmlRpc API(DotClear.MetaWeblog)。但我没有找到办法处理类别。

所以我开始查看Http数据包并尝试“与浏览器相同”。

  1. 这是我用来“Http POST”的方法

    protected HttpStatusCode HttpPost(Uri url_, string data_, bool allowAutoRedirect_)
    {
        HttpWebRequest Request;
        HttpWebResponse Response = null;
        Stream ResponseStream = null;
        Request = (System.Net.HttpWebRequest)HttpWebRequest.Create(url_);
        Request.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)";
        Request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
        Request.AllowAutoRedirect = allowAutoRedirect_;
        // Add the network credentials to the request.
        Request.Credentials = new NetworkCredential(Username, Password);
    
        string authInfo = Username + ":" + Password;
        authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(authInfo));
        Request.Headers["Authorization"] = "Basic " + authInfo; 
    
        Request.Method = "POST";
        Request.CookieContainer = Cookies;
        if(ConnectionCookie!=null)
            Request.CookieContainer.Add(url_, ConnectionCookie);
        if (dcAdminCookie != null)
            Request.CookieContainer.Add(url_, dcAdminCookie);
        Request.PreAuthenticate = true;
    
        ASCIIEncoding encoding = new ASCIIEncoding();
        string postData = data_;
        byte[] data = encoding.GetBytes(postData); //Encoding.UTF8.GetBytes(data_);  //encoding.GetBytes(postData);
        Request.ContentLength = data.Length;
        Request.ContentType = "application/x-www-form-urlencoded";
        Stream newStream = Request.GetRequestStream();
        // Send the data.
        newStream.Write(data, 0, data.Length);
        newStream.Close();
    
        try
        {
            // get the response from the server.
            Response = (HttpWebResponse)Request.GetResponse();
            if (!allowAutoRedirect_)
            {
                foreach (Cookie c in Response.Cookies)
                {
                    if (c.Name == "dcxd")
                        ConnectionCookie = c;
                    if (c.Name == "dc_admin")
                        dcAdminCookie = c;
    
                }
    
                Cookies.Add(Response.Cookies);
            }
            // Get the response stream.
            ResponseStream = Response.GetResponseStream();
            // Pipes the stream to a higher level stream reader with the required encoding format. 
            StreamReader readStream = new StreamReader(ResponseStream, Encoding.UTF8);
            string result = readStream.ReadToEnd();
    
            if (Request.RequestUri == Response.ResponseUri)
            {
                _log.InfoFormat("{0} ==> {1}({2})", Request.RequestUri, Response.StatusCode, Response.StatusDescription);
            }
            else
            {
                _log.WarnFormat("RequestUri:{0}\r\nResponseUri:{1}\r\nstatus code:{2} Status descr:{3}", Request.RequestUri, Response.ResponseUri, Response.StatusCode, Response.StatusDescription);
            }
        }
        catch (WebException wex)
        {
            Response = wex.Response as HttpWebResponse;
    
            if (Response != null)
            {
                _log.ErrorFormat("{0} ==> {1}({2})", Request.RequestUri, Response.StatusCode, Response.StatusDescription);
            }
    
            Request.Abort();
        }
        finally
        {
            if (Response != null)
            { 
                // Releases the resources of the response.
                Response.Close();
            }
    
        }
        if(Response !=null)
            return Response.StatusCode;
    
        return HttpStatusCode.Ambiguous;
    }
    
  2. 所以要做的第一件事就是以管理员身份进行身份验证。这是代码:

    protected bool HttpAuthenticate()
    {
        Uri u = new Uri(this.Url);
        Uri url = new Uri(string.Format("{0}/admin/auth.php", u.GetLeftPart(UriPartial.Authority)));
        string data = string.Format("user_id={0}&user_pwd={1}&user_remember=1", Username, Password);
        var ret = HttpPost(url,data,false);
        return (ret == HttpStatusCode.OK || ret==HttpStatusCode.Found);
    }
    
  3. 现在我已通过身份验证,我需要获取xd_chek信息(我可以在页面上找到,所以基本上它是/admin/category.php +正则表达式{{1}上的GET }))

  4. 因此我已通过身份验证并拥有dotclear[.]nonce = '(.*)'信息。最后要做的事情似乎是发布下一个类别。但当然它根本不起作用......这是代码:

    xd_check
  5. 我哪里错了?

1 个答案:

答案 0 :(得分:1)

最终我找到了解决方案。

似乎在认证和使用页面之间丢失了cookie。

所以我决定不使用框架的de CookiesContainer,而只是将cookie保存在字符串中并在每次请求时传递它们。

它很棒!

代码示例:

private string _cookieAsString = string.Empty;

    protected string CookieAsString
    {
        get { return _cookieAsString; }
        set
        {
            if (value != null)
            {
                if (!_cookieAsString.Contains(value))
                {
                    if (_cookieAsString.Length == 0)
                        _cookieAsString = value;
                    else
                        _cookieAsString += string.Format(";{0}", value);
                }
            }
        }
    }

在HttpWebRequest中,我这样设置:

...
Request.Headers.Add(HttpRequestHeader.Cookie, CookieAsString);
...

将cookie保存在httpWebRequest中,如下所示:

...
CookieAsString = Response.Headers[HttpResponseHeader.SetCookie];
...