.NET HttpWebRequest.GETResponse () HTTP স্থিতি কোড 400 (খারাপ অনুরোধ) ফিরিয়ে এলে ব্যতিক্রম উত্থাপন করে


205

আমি এমন পরিস্থিতিতে আছি যেখানে যখন আমি সার্ভার থেকে এইচটিটিপি 400 কোড পাই, এটি সার্ভারের সম্পূর্ণ আইনি পদ্ধতি যা আমাকে জানায় যে আমার অনুরোধে কী ভুল ছিল (HTTP প্রতিক্রিয়া সামগ্রীতে কোনও বার্তা ব্যবহার করে)

তবে, স্থিতি কোড 400 হলে .NET HttpWebRequest একটি ব্যতিক্রম উত্থাপন করে।

আমি কীভাবে এটি পরিচালনা করব? আমার জন্য একটি 400 সম্পূর্ণ আইনী, এবং বরং সহায়ক helpful এইচটিটিপি বিষয়বস্তুতে কিছু গুরুত্বপূর্ণ তথ্য রয়েছে তবে ব্যতিক্রমটি আমাকে আমার পথে ফেলে দেয়।


6
আমি একই জিনিস অভিজ্ঞতা ছিল। আমি নেট নেট ফ্রেমওয়ার্ক টিমের কাছে একটি পরামর্শ জমা দিয়েছি। এটিতে বিনা দ্বিধা বোধ করুন: সংযুক্ত.মাইক্রোসফট
ভিজুয়ালস্টুডিও / ফেডব্যাক / ডিটেলস / ৫et৫৫৫৫/২

উত্তর:


344

এটি "নন-সাকসেস কোড নিক্ষেপ" বন্ধ করার কিছু উপায় থাকলে খুব ভাল হবে তবে আপনি যদি ওয়েবএক্সেপশন ধরেন তবে কমপক্ষে প্রতিক্রিয়াটি ব্যবহার করতে পারেন:

using System;
using System.IO;
using System.Web;
using System.Net;

public class Test
{
    static void Main()
    {
        WebRequest request = WebRequest.Create("http://csharpindepth.com/asd");
        try
        {
            using (WebResponse response = request.GetResponse())
            {
                Console.WriteLine("Won't get here");
            }
        }
        catch (WebException e)
        {
            using (WebResponse response = e.Response)
            {
                HttpWebResponse httpResponse = (HttpWebResponse) response;
                Console.WriteLine("Error code: {0}", httpResponse.StatusCode);
                using (Stream data = response.GetResponseStream())
                using (var reader = new StreamReader(data))
                {
                    string text = reader.ReadToEnd();
                    Console.WriteLine(text);
                }
            }
        }
    }
}

আপনি পৃথক পদ্ধতিতে "এটি একটি সাফল্য কোড না হলেও এমনকি আমার প্রতিক্রিয়া পান" সজ্জিত করতে পছন্দ করতে পারেন। (আমি প্রতিক্রিয়া না থাকলে আপনি এখনও ফেলে দেওয়ার পরামর্শ দিই, যেমন আপনি সংযোগ করতে না পারলে))

ত্রুটির প্রতিক্রিয়া যদি বৃহত্তর হতে পারে (যা অস্বাভাবিক) তবে আপনি HttpWebRequest.DefaultMaximumErrorResponseLengthসম্পূর্ণ ত্রুটিটি পেয়েছেন তা নিশ্চিত করতে আপনি টুইট করতে পারেন।


5
ওয়েবআরসেপশনের সাথে সংযুক্ত প্রতিক্রিয়াতে গেটআরস্পোনস্ট্রিম () দ্বারা প্রবাহিত স্ট্রিমের সামগ্রীগুলি সার্ভারের দ্বারা প্রাপ্ত প্রতিক্রিয়াটির পরিবর্তে কেবলমাত্র স্থিতি কোডের নাম (যেমন "খারাপ অনুরোধ")। এই তথ্য পেতে কোন উপায় আছে?
মার্ক ওয়াটস

@ মারকওয়াটস: সার্ভার দ্বারা যা কিছু ফিরিয়ে দেওয়া উচিত তা হওয়া উচিত এবং আমি যতটা পরিস্থিতিতে দেখেছি তা হয়েছে। আপনি কি কোনও নির্দিষ্ট বাহ্যিক URL দিয়ে পুনরুত্পাদন করতে পারেন? আমি আপনাকে একটি নতুন প্রশ্ন জিজ্ঞাসা করার পরামর্শ দিচ্ছি (এটি একটি উল্লেখ করে) এবং কী চলছে তা দেখিয়ে।
জন স্কিটি

দেখা যাচ্ছে যে প্রতিক্রিয়ার সামগ্রীর দৈর্ঘ্য শূন্য হলে এটি কেবল এটি করে; এটি এইচটিটিপি স্থিতি কোডের একটি পাঠ্য বিবরণ যুক্ত করে - 400 কেবলমাত্র "খারাপ অনুরোধ" তবে অন্যদের মধ্যে কিছু বর্ণনামূলক।
মার্ক ওয়াটস

যদি কেউ এই শ্রেণীর জন্য একটি ভাল মোড়ক সম্পর্কে জানেন তবে এটির একটি লিঙ্ক এখানে রেখে দিন। System.Net.WebClient ব্যতিক্রম হ্যান্ডলিং সিস্টেমকে অনুরোধ করে একই আচরণ করে।
জন কে

1
@ অঙ্কুশ জাইন: আমি বিশ্বাস করি এটি 2XX এর জন্য সাধারণত ফিরে আসবে; ফেরৎ পারে 3XX কনফিগারেশনের উপর নির্ভর করে ঘটতে - আমি একটি ব্যতিক্রম কারণ অন্য কিছু আশা করতে চাই, যদিও আমি ভুল হতে পারে। (4 এক্সএক্সের জন্য, এটি কেবল সম্ভব যে এটি তারপরে প্রমাণীকরণের তথ্য প্রয়োগ করে তবে ইতিমধ্যে এটি ব্যবহার না করে))
জন স্কিটি

48

আমি জানি এটি ইতিমধ্যে একটি দীর্ঘ সময় আগে উত্তর দেওয়া হয়েছে, কিন্তু আমি আশা করি এই প্রশ্নে আসা অন্যান্য ব্যক্তিদের সহায়তা করার জন্য একটি এক্সটেনশন পদ্ধতি তৈরি করেছি।

কোড:

public static class WebRequestExtensions
{
    public static WebResponse GetResponseWithoutException(this WebRequest request)
    {
        if (request == null)
        {
            throw new ArgumentNullException("request");
        }

        try
        {
            return request.GetResponse();
        }
        catch (WebException e)
        {
            if (e.Response == null)
            {
                throw;
            }

            return e.Response;
        }
    }
}

ব্যবহার:

var request = (HttpWebRequest)WebRequest.CreateHttp("http://invalidurl.com");

//... (initialize more fields)

using (var response = (HttpWebResponse)request.GetResponseWithoutException())
{
    Console.WriteLine("I got Http Status Code: {0}", response.StatusCode);
}

2
WebException.Responseএবং হতে পারে null। যদি এটি হয় তবে আপনার পুনর্বিবেচনা করা উচিত।
ইয়ান কেম্প

@ ডেভিডপি আমি সম্মত, ব্যবহারটি সামান্য জানক, যদিও বেশিরভাগ ক্ষেত্রে আপনার HttpClientপরিবর্তে সম্ভবত ব্যবহার করা উচিত , এটি অনেক বেশি কনফিগারযোগ্য এবং আমি বিশ্বাস করি এটি ভবিষ্যতের পথ।
ম্যাথু

অনুরোধের জন্য পরীক্ষা করা == নাল কি সত্যিই প্রয়োজনীয়? যেহেতু এটি একটি এক্সটেনশন পদ্ধতি, এটি কোনও নাল অবজেক্টে ব্যবহার করার চেষ্টা করে এটি এক্সটেনশন পদ্ধতির কোডটিকে আঘাত করার আগে একটি নাল রেফারেন্স ব্যতিক্রম ছুঁড়ে ফেলা উচিত ...... ঠিক?
kwill

@ কুইল এক্সটেনশন পদ্ধতিগুলি কেবল স্থিতিশীল পদ্ধতি, বিভ্রান্তি এড়াতে যথাযথ ইনপুট বৈধকরণ করা উচিত, বিশেষত যখন তারা এক্সটেনশন পদ্ধতি সিনট্যাক্সের সাথে না থাকে। এছাড়াও, এটি নেট দলগুলি দ্বারা নিয়মিত করা হয়েছে: github.com/dotnet/corefx/blob/…
ম্যাথু

1
দুঃখিত আমি আপনার দ্বিতীয় প্রশ্নটি ভুল বুঝেছি। ((WebRequest) null).GetResponseWithoutException()প্রকৃতপক্ষে NullReferenceExceptionএটির কারণ ঘটবে না , যেহেতু এটি সমপরিমাণে সংকলিত হয়েছে WebRequestExtensions.GetResponseWithoutException(null), যার ফলশ্রুতি a হবে না NullReferenceException, সুতরাং ইনপুট বৈধতার জন্য প্রয়োজন।
ম্যাথু

13

মজার ব্যাপার হচ্ছে, HttpWebResponse.GetResponseStream()আপনি থেকে পাওয়া যে WebException.Responseপ্রতিক্রিয়া প্রবাহ যে আপনার সার্ভার থেকে প্রাপ্ত যেত হিসাবে একই নয়। আমাদের পরিবেশে, যখন 400 টি এইচটিপি স্থিতি কোডটি ক্লায়েন্টকে HttpWebRequest/HttpWebResponseঅবজেক্টগুলি ব্যবহার করে ফিরিয়ে দেওয়া হয় তখন আমরা প্রকৃত সার্ভার প্রতিক্রিয়াগুলি হারাব। আমরা যা দেখেছি, তার সাথে যুক্ত প্রতিক্রিয়া স্ট্রিমটি WebException's HttpWebResponseক্লায়েন্টে উত্পন্ন হয় এবং সার্ভার থেকে প্রাপ্ত প্রতিক্রিয়া সংস্থার কোনওটি অন্তর্ভুক্ত করে না। খুব হতাশাবোধ, আমরা যেমন খারাপ অনুরোধের কারণ ক্লায়েন্টকে ফিরে বার্তা দিতে চাই।


আমি পদ্ধতি হেড ব্যবহার করি এবং এই ব্যতিক্রম ঘটায় তবে জিইটি ব্যবহার করার সময় কোনও সমস্যা নেই। হ্যাড পদ্ধতিতে সমস্যাটি কী?
মোহাম্মদ আফরাশতেহ

12

গুগলের OAuth2 পরিষেবাতে সংযোগ দেওয়ার চেষ্টা করার সময় আমারও একই সমস্যা ছিল।

আমি ওয়েস্ট রিকোয়েস্টটি এভাবে ব্যবহার না করে নিজেই পোস্টটি লিখেছিলাম:

TcpClient client = new TcpClient("accounts.google.com", 443);
Stream netStream = client.GetStream();
SslStream sslStream = new SslStream(netStream);
sslStream.AuthenticateAsClient("accounts.google.com");

{
    byte[] contentAsBytes = Encoding.ASCII.GetBytes(content.ToString());

    StringBuilder msg = new StringBuilder();
    msg.AppendLine("POST /o/oauth2/token HTTP/1.1");
    msg.AppendLine("Host: accounts.google.com");
    msg.AppendLine("Content-Type: application/x-www-form-urlencoded");
    msg.AppendLine("Content-Length: " + contentAsBytes.Length.ToString());
    msg.AppendLine("");
    Debug.WriteLine("Request");
    Debug.WriteLine(msg.ToString());
    Debug.WriteLine(content.ToString());

    byte[] headerAsBytes = Encoding.ASCII.GetBytes(msg.ToString());
    sslStream.Write(headerAsBytes);
    sslStream.Write(contentAsBytes);
}

Debug.WriteLine("Response");

StreamReader reader = new StreamReader(sslStream);
while (true)
{  // Print the response line by line to the debug stream for inspection.
    string line = reader.ReadLine();
    if (line == null) break;
    Debug.WriteLine(line);
}

প্রতিক্রিয়া স্ট্রিমটিতে যে প্রতিক্রিয়া লিখিত হয় সেটিতে আপনার পরে থাকা নির্দিষ্ট ত্রুটির পাঠ্য থাকে।

বিশেষত, আমার সমস্যাটি হ'ল আমি ইউআরএল-এনকোডড ডেটা টুকরোগুলির মধ্যে লাইনগুলি রেখেছিলাম। আমি যখন তাদের বাইরে নিয়ে এসেছি, তখন সমস্ত কিছুই কাজ করেছিল। আপনি আপনার পরিষেবাতে সংযোগ করতে এবং একই প্রতিক্রিয়া ত্রুটির পাঠটি পড়তে অনুরূপ কৌশলটি ব্যবহার করতে সক্ষম হতে পারেন।


2
HttpWebRequest তাই গণ্ডগোল। এমনকি সকেটগুলি সহজ (কোজ তারা আপনার থেকে ত্রুটিগুলি গোপন করে না)।
এজেন্ট_এল

6

এটি চেষ্টা করুন (এটি ভিবি-কোড :-):

Try

Catch exp As WebException
  Dim sResponse As String = New StreamReader(exp.Response.GetResponseStream()).ReadToEnd
End Try

3

এক্সটেনশন ফাংশনের একটি অ্যাসিনক্রোনাস সংস্করণ:

    public static async Task<WebResponse> GetResponseAsyncNoEx(this WebRequest request)
    {
        try
        {
            return await request.GetResponseAsync();
        }
        catch(WebException ex)
        {
            return ex.Response;
        }
    }

0

এটি আমার জন্য এটি সমাধান করেছে:
https://gist.github.com/beccasaurus/929007/a8f820b153a1cfdee3d06a9c0a1d7ebfced8bb77

টি এল; ডিআর:
সমস্যা:
স্থানীয় হোস্টের আয় আশা করা বিষয়বস্তু, দূরবর্তী আইপি গন্ধে পরিবর্তন "খারাপ অনুরোধ" 400 বিষয়বস্তু
সমাধান:
যোগ করার পদ্ধতি <httpErrors existingResponse="PassThrough"></httpErrors>থেকে web.config/configuration/system.webServerআমার জন্য এই মীমাংসিত; এখন সমস্ত সার্ভার (স্থানীয় এবং দূরবর্তী) আইপি ঠিকানা এবং / অথবা এইচটিটিপি কোড আমি ফিরিয়ে না নিয়ে হুবহু একই সামগ্রী (আমার দ্বারা উত্পন্ন) ফিরিয়ে দেয়।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.