c# - गैर-ठीक प्रतिक्रिया के लिए IHttpActionResult के साथ सामग्री लौटें





asp.net-web-api httpresponse (11)


एएसपी.नेट वेब एपीआई 2 में, आप किसी ResponseMessage में किसी भी ResponseMessage संदेश को लपेट सकते हैं:

public IHttpActionResult Get()
{
   HttpResponseMessage responseMessage = ...
   return new ResponseMessageResult(responseMessage);
}

कुछ मामलों में यह वांछित परिणाम प्राप्त करने का सबसे आसान तरीका हो सकता है, हालांकि आमतौर पर https://msdn.microsoft.com/en-us/library/system.web.http.results(v=vs.118).aspx में विभिन्न परिणामों का उपयोग करना बेहतर हो सकता है।

एक वेब एपीआई 2 नियंत्रक से लौटने के लिए, अगर प्रतिक्रिया ठीक है (स्थिति 200) इस तरह की प्रतिक्रिया के साथ सामग्री वापस कर सकते हैं:

    public IHttpActionResult Get()
    {
        string myResult = ...
        return Ok(myResult);
    }

यदि संभव हो, तो मैं यहां संभवतः अंतर्निहित परिणाम प्रकारों का उपयोग करना चाहता हूं: https://msdn.microsoft.com/en-us/library/system.web.http.results(v=vs.118).aspx

मेरा सवाल है, एक और प्रकार की प्रतिक्रिया के लिए (200 नहीं), मैं इसके साथ एक संदेश (स्ट्रिंग) कैसे वापस कर सकता हूं? उदाहरण के लिए, मैं यह कर सकता हूं:

    public IHttpActionResult Get()
    {
       return InternalServerError();
    }

लेकिन यह नहीं:

    public IHttpActionResult Get()
    {
       return InternalServerError("Message describing the error here");
    }

आदर्श रूप से मैं इसे सामान्यीकृत करना चाहता हूं ताकि मैं IHttpActionResult के किसी भी कार्यान्वयन के साथ एक संदेश वापस भेज सकूं।

क्या मुझे ऐसा करने की ज़रूरत है (और अपना खुद का प्रतिक्रिया संदेश बनाएं):

    public IHttpActionResult Get()
    {
       HttpResponseMessage responseMessage = ...
       return ResponseMessage(responseMessage);
    }

या कोई बेहतर तरीका है?




आप इसका उपयोग कर सकते हैं:

return Content(HttpStatusCode.BadRequest, "Any object");



अपवादों के लिए, मैं आमतौर पर करता हूं

 catch (Exception ex)
        {
            return InternalServerError(new ApplicationException("Something went wrong in this request. internal exception: " + ex.Message));
        }



आप HttpRequestMessagesExtensions.CreateErrorResponse ( System.Net.Http नामस्थान) का उपयोग कर सकते हैं, जैसे:

public IHttpActionResult Get()
{
   return ResponseMessage(Request.CreateErrorResponse(HttpStatusCode.InternalServerError, "Message describing the error here"));
}

वेब एपीआई की सामग्री वार्ता का लाभ उठाने के अनुरोध के आधार पर प्रतिक्रियाएं बनाना बेहतर है।




उपरोक्त चीजें वास्तव में सहायक हैं।

वेब सेवाओं को बनाते समय, यदि आप सेवाओं के मामले का उपभोग करेंगे उपभोक्ता की सराहना की जाएगी। मैंने आउटपुट की समानता बनाए रखने की कोशिश की। इसके अलावा आप टिप्पणी या वास्तविक त्रुटि संदेश दे सकते हैं। वेब सेवा उपभोक्ता केवल IsSuccess को सही देख सकता है या नहीं, यह सुनिश्चित करेगा कि समस्या है और स्थिति के अनुसार कार्य करें।

  public class Response
    {
        /// <summary>
        /// Gets or sets a value indicating whether this instance is success.
        /// </summary>
        /// <value>
        /// <c>true</c> if this instance is success; otherwise, <c>false</c>.
        /// </value>
        public bool IsSuccess { get; set; } = false;

        /// <summary>
        /// Actual response if succeed 
        /// </summary>
        /// <value>
        /// Actual response if succeed 
        /// </value>
        public object Data { get; set; } = null;

        /// <summary>
        /// Remark if anythig to convey
        /// </summary>
        /// <value>
        /// Remark if anythig to convey
        /// </value>
        public string Remark { get; set; } = string.Empty;
        /// <summary>
        /// Gets or sets the error message.
        /// </summary>
        /// <value>
        /// The error message.
        /// </value>
        public object ErrorMessage { get; set; } = null;


    }  




[HttpGet]
        public IHttpActionResult Employees()
        {
            Response _res = new Response();
            try
            { 
                DalTest objDal = new DalTest(); 
                _res.Data = objDal.GetTestData();
                _res.IsSuccess = true;
                return Ok<Response>(_res);
            }
            catch (Exception ex)
            {
                _res.IsSuccess = false;
                _res.ErrorMessage = ex;
                return ResponseMessage(Request.CreateResponse(HttpStatusCode.InternalServerError, _res )); 
            } 
        }

अगर कोई सुझाव देने के लिए आपका स्वागत है :)




देर से उत्तर के लिए खेद है कि आप सरल उपयोग क्यों नहीं करते हैं

return BadRequest("your message");

मैं इसे अपने सभी IHttpActionResult त्रुटियों के लिए उपयोग करता हूं, यह अच्छी तरह से काम कर रहा है

यहां प्रलेखन है: https://msdn.microsoft.com/en-us/library/system.web.http.apicontroller.badrequest(v=vs.118).aspx




यह उत्तर स्ट्रिंग के बजाय असली वस्तु के साथ, शमील यकुपोव उत्तर पर आधारित है।

using System.Dynamic;

dynamic response = new ExpandoObject();
response.message = "Email address already exist";

return Content<object>(HttpStatusCode.BadRequest, response);



आप यह भी कर सकते हैं:

return InternalServerError(new Exception("SOME CUSTOM MESSAGE"));



मुझे भी यही समस्या थी। मैं अपने एपीआई नियंत्रकों के लिए कस्टम परिणाम बनाना चाहता हूं, उन्हें return Ok("some text"); करने के लिए कॉल करना return Ok("some text");

तब मैंने यह किया: 1) एकल परिणाम के साथ कस्टम परिणाम प्रकार बनाएँ

public sealed class EmptyResult : IHttpActionResult
{
    public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
    {
        return Task.FromResult(new HttpResponseMessage(System.Net.HttpStatusCode.NoContent) { Content = new StringContent("Empty result") });
    }
}

2) नई विधि के साथ कस्टम नियंत्रक बनाएँ:

public class CustomApiController : ApiController
{
    public IHttpActionResult EmptyResult()
    {
        return new EmptyResult();
    }
}

और फिर मैं उन्हें अपने नियंत्रकों में कॉल कर सकता हूं, इस तरह:

public IHttpActionResult SomeMethod()
    {
       return EmptyResult();
    }



@ मायाबेल आप IHttpActionResult कंक्रीट बना सकते हैं और इस तरह के कोड को लपेट सकते हैं:

public class NotFoundPlainTextActionResult : IHttpActionResult
{
    public NotFoundPlainTextActionResult(HttpRequestMessage request, string message)
    {
        Request = request;
        Message = message;
    }

    public string Message { get; private set; }
    public HttpRequestMessage Request { get; private set; }

    public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
    {
        return Task.FromResult(ExecuteResult());
    }

    public HttpResponseMessage ExecuteResult()
    {
        var response = new HttpResponseMessage();

        if (!string.IsNullOrWhiteSpace(Message))
            //response.Content = new StringContent(Message);
            response = Request.CreateErrorResponse(HttpStatusCode.NotFound, new Exception(Message));

        response.RequestMessage = Request;
        return response;
    }
}



मैं इस समस्या का समाधान ढूंढ रहा था और पहले यहां आया था। कुछ और शोध के बाद मैंने निम्नलिखित समाधान को महसूस किया है:

आप मेरे समाधान का उपयोग कैसे करते हैं? आप इसे विश्व स्तर पर पंजीकृत कर सकते हैं:

config.Filters.Add(new ValidateModelStateAttribute());

या कक्षा के लिए मांग पर इसका इस्तेमाल करें

[ValidateModelState]
public class UsersController : ApiController
{...

या एक मेथोड के लिए

[ValidateModelState]
public IHttpActionResult Create([Required] UserModel data)
{...

जैसा कि आप देख सकते हैं, एक विधि [System.ComponentModel.DataAnnotations.Required] एट्रिब्यूट विधि पैरामीटर में रखा गया है। यह इंगित करता है कि मॉडल की आवश्यकता है और null नहीं हो सकता है।

आप एक कस्टम संदेश के साथ भी उपयोग कर सकते हैं:

[ValidateModelState]
public IHttpActionResult Create([Required(ErrorMessage = "Custom message")] UserModel data)
{...

मेरा कोड यहाँ है:

using System;
using System.Collections.Concurrent;
using System.ComponentModel.DataAnnotations;
using System.Net;
using System.Net.Http;
using System.Reflection;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;

namespace your_base_namespace.Web.Http.Filters
{
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true)]
    public class ValidateModelStateAttribute : ActionFilterAttribute
    {
        private delegate void ValidateHandler(HttpActionContext actionContext);

        private static readonly ConcurrentDictionary<HttpActionBinding, ValidateHandler> _validateActionByActionBinding;

        static ValidateModelStateAttribute()
        {
            _validateActionByActionBinding = new ConcurrentDictionary<HttpActionBinding, ValidateHandler>();
        }

        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            GetValidateHandler(actionContext.ActionDescriptor.ActionBinding)(actionContext);

            if (actionContext.ModelState.IsValid)
                return;

            actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, actionContext.ModelState);
        }

        private ValidateHandler GetValidateHandler(HttpActionBinding actionBinding)
        {
            ValidateHandler validateAction;

            if (!_validateActionByActionBinding.TryGetValue(actionBinding, out validateAction))
                _validateActionByActionBinding.TryAdd(actionBinding, validateAction = CreateValidateHandler(actionBinding));

            return validateAction;
        }

        private ValidateHandler CreateValidateHandler(HttpActionBinding actionBinding)
        {
            ValidateHandler handler = new ValidateHandler(c => { });

            var parameters = actionBinding.ParameterBindings;

            for (int i = 0; i < parameters.Length; i++)
            {
                var parameterDescriptor = (ReflectedHttpParameterDescriptor)parameters[i].Descriptor;
                var attribute = parameterDescriptor.ParameterInfo.GetCustomAttribute<RequiredAttribute>(true);

                if (attribute != null)
                    handler += CreateValidateHandler(attribute, parameterDescriptor.ParameterName);
            }

            return handler;
        }

        private static ValidateHandler CreateValidateHandler(ValidationAttribute attribute, string name)
        {            
            return CreateValidateHandler(attribute, new ValidationContext(new object()) { MemberName = name });
        }

        private static ValidateHandler CreateValidateHandler(ValidationAttribute attribute, ValidationContext context)
        {
            return new ValidateHandler(actionContext =>
            {
                object value;
                actionContext.ActionArguments.TryGetValue(context.MemberName, out value);

                var validationResult = attribute.GetValidationResult(value, context);
                if (validationResult != null)
                    actionContext.ModelState.AddModelError(context.MemberName, validationResult.ErrorMessage);
            });
        }
    }
}




c# asp.net-web-api httpresponse