{"id":117,"date":"2019-10-30T17:18:49","date_gmt":"2019-10-30T17:18:49","guid":{"rendered":"http:\/\/blog.yusufcelik.net\/?p=117"},"modified":"2019-10-30T17:18:51","modified_gmt":"2019-10-30T17:18:51","slug":"net-core-web-api-middlewarede-exception-handler","status":"publish","type":"post","link":"http:\/\/blog.yusufcelik.net\/index.php\/2019\/10\/30\/net-core-web-api-middlewarede-exception-handler\/","title":{"rendered":".Net Core Web API MiddleWare&#8217;de Exception Handler"},"content":{"rendered":"\n<p>Merhaba,<\/p>\n\n\n\n<p>Bug\u00fcn ki makalemizde .Net Core Web API <strong>MiddleWare<\/strong>&#8216;de <strong>Custom exception handler<\/strong> yapaca\u011f\u0131z. <\/p>\n\n\n\n<p>Kullan\u0131c\u0131lar\u0131m\u0131za sundu\u011fumuz bir servis&#8217;te i\u015flem esnas\u0131nda herhangi bir hata olu\u015ftu\u011funda kullan\u0131c\u0131ya e\u011fer bir mesaj d\u00f6ndermessek exception&#8217;\u0131n tamam\u0131n\u0131 servis \u00e7a\u011f\u0131r\u0131ld\u0131\u011f\u0131nda exception detay\u0131na basacakt\u0131r. Ama bu durumun b\u00f6yle olmas\u0131n\u0131 istemeyiz. <\/p>\n\n\n\n<p>\u00d6rnek olarak \u00e7a\u011f\u0131rd\u0131\u011f\u0131m\u0131z servisin ba\u015f\u0131na bir throw yerle\u015ftirdim. Sistem b\u00f6yle bir hata ald\u0131\u011f\u0131nda kullan\u0131c\u0131ya a\u015fa\u011f\u0131daki bir \u00e7\u0131kt\u0131 vermek. Kullan\u0131c\u0131 i\u00e7in bu d\u00f6nen sonu\u00e7 anlams\u0131z olacakt\u0131r. <\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" loading=\"lazy\" width=\"1024\" height=\"387\" src=\"https:\/\/blog.yusufcelik.net\/wp-content\/uploads\/2019\/10\/image-1024x387.png\" alt=\"\" class=\"wp-image-118\" srcset=\"http:\/\/blog.yusufcelik.net\/wp-content\/uploads\/2019\/10\/image-1024x387.png 1024w, http:\/\/blog.yusufcelik.net\/wp-content\/uploads\/2019\/10\/image-300x113.png 300w, http:\/\/blog.yusufcelik.net\/wp-content\/uploads\/2019\/10\/image-768x290.png 768w, http:\/\/blog.yusufcelik.net\/wp-content\/uploads\/2019\/10\/image-1320x500.png 1320w, http:\/\/blog.yusufcelik.net\/wp-content\/uploads\/2019\/10\/image.png 1510w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>B\u00f6yle bir sonu\u00e7 do\u011furmamas\u0131 i\u00e7in kullan\u0131c\u0131ya onunda anlayabilece\u011fi bir sonu\u00e7 d\u00f6nmeliyiz. <\/p>\n\n\n\n<p>Bunun \u00f6n\u00fcne ge\u00e7mek i\u00e7in <strong>Middleware<\/strong>&#8216;de bir <strong>Exception Handler <\/strong>yap\u0131s\u0131 olu\u015fturaca\u011f\u0131m.<\/p>\n\n\n\n<p>\u0130lk olarak Visual Studio ortam\u0131nda bir <strong>.Net Core Web API<\/strong> projesi olu\u015fturuyorum.<\/p>\n\n\n\n<p> Olu\u015fturdu\u011fum projenin katmanlar\u0131n\u0131 basit \u015fekilde a\u015fa\u011f\u0131daki gibi olu\u015fturuyorum.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" loading=\"lazy\" width=\"439\" height=\"175\" src=\"https:\/\/blog.yusufcelik.net\/wp-content\/uploads\/2019\/10\/image-4.png\" alt=\"\" class=\"wp-image-122\" srcset=\"http:\/\/blog.yusufcelik.net\/wp-content\/uploads\/2019\/10\/image-4.png 439w, http:\/\/blog.yusufcelik.net\/wp-content\/uploads\/2019\/10\/image-4-300x120.png 300w\" sizes=\"(max-width: 439px) 100vw, 439px\" \/><\/figure>\n\n\n\n<p>Models katman\u0131n\u0131n i\u00e7erisine servis sonu\u00e7lar\u0131m\u0131z\u0131 d\u00f6nebilece\u011fimiz bir &#8220;OperationResult&#8221; ad\u0131nda bir s\u0131n\u0131f ekliyorum.<\/p>\n\n\n\n<pre class=\"wp-block-syntaxhighlighter-code\">    public class OperationResult\n    {\n        public OperationResult()\n        {\n            IsSuccessful = true;\n            ReturnMessage = \"\u0130\u015flem Ba\u015far\u0131l\u0131\";\n            ReturnCode = 100;\n        }\n        public bool IsSuccessful { get; set; }\n        public int ReturnCode { get; set; }\n        public string ReturnMessage { get; set; }\n\n        public override string ToString()\n        {\n            return JsonConvert.SerializeObject(this);\n        }\n    }<\/pre>\n\n\n\n<p> <\/p>\n\n\n\n<p>Ve bu olu\u015fturdu\u011fumuz s\u0131n\u0131f\u0131 base bir s\u0131n\u0131f\u0131m\u0131za field olarak ekliyorum. Bu sayede t\u00fcm i\u015flemlerde kullanabilme imkan\u0131 bulabilece\u011fim.<\/p>\n\n\n\n<p>Exception s\u0131n\u0131f\u0131ndan t\u00fcreyen bir custom bir exception s\u0131n\u0131f\u0131 olu\u015fturuyoruz.<\/p>\n\n\n\n<pre class=\"wp-block-syntaxhighlighter-code\">    public class CustomException : Exception\n    {\n        public string ReturnMessage { get; set; }\n        public override string Message => ReturnMessage;\n        public CustomException()\n        {\n\n        }\n\n\n        public string Code { get; }\n\n\n        public CustomException(string code)\n        {\n            Code = code;\n        }\n        public CustomException(string code, string message)\n        {\n            Code = code;\n            ReturnMessage = message;\n        }\n\n        public CustomException(string message, params object[] args)\n            : this(string.Empty, message, args)\n        {\n        }\n        public CustomException(string code, string message, params object[] args)\n            : this(null, code, message, args)\n        {\n            ReturnMessage = String.Format(message, args);\n            Code = code;\n        }\n\n        public CustomException(Exception innerException, string message, params object[] args)\n            : this(innerException, string.Empty, message, args)\n        {\n        }\n\n        public CustomException(Exception innerException, string code, string message, params object[] args)\n            : base(string.Format(message, args), innerException)\n        {\n            Code = code;\n        }\n\n    }<\/pre>\n\n\n\n<p>Art\u0131k exception i\u015flemlerimiz i\u00e7in yukar\u0131da olu\u015fturdu\u011fumuz CustomException s\u0131n\u0131f\u0131n\u0131 kullanaca\u011f\u0131z.<\/p>\n\n\n\n<p>Business katman\u0131na BusinessBase ad\u0131nda bir s\u0131n\u0131f ekliyoruz ve  bu s\u0131n\u0131f i\u00e7erisine  business i\u015flemlerinin execute oldu\u011funda kullanaca\u011f\u0131m\u0131z exception handler opeartion methodlar\u0131n\u0131 ekliyoruz. Di\u011fer business s\u0131n\u0131flar\u0131m\u0131z bu s\u0131n\u0131ftan t\u00fcreyece\u011fi i\u00e7in bu methodlar\u0131 kullanabilir hale gelecektir.<\/p>\n\n\n\n<pre class=\"wp-block-syntaxhighlighter-code\">protected T ExecuteWithExceptionHandledOperation&lt;T>(Func&lt;T> func)\n        {\n            try\n            {\n                var result = func.Invoke();\n\n                return result;\n            }\n            catch (CustomException ex)\n            {\n                throw new CustomException(ex.Code, ex.ReturnMessage);\n            }\n            catch (Exception ex)\n            {\n                throw new CustomException(\"500\", ex.Message);\n            }\n        }<\/pre>\n\n\n\n<p>Yukar\u0131da business i\u015flemlerini execute etmekte kullanaca\u011f\u0131m\u0131z method try bloklar\u0131 i\u00e7erisinde herhangi bir hata olmazsa invoke olacak ve i\u015flemlermize ba\u015far\u0131l\u0131 bir \u015fekilde devam edecek. E\u011fer cache blo\u011funa d\u00fc\u015ferse hata yakalama i\u015flemini sa\u011flayacakt\u0131r. Burada ilk olarak kendi CustomException k\u0131sm\u0131n\u0131 kontrol ediyoruz. Asl\u0131nda burda bu \u015fekilde bir kontrol eklememin sebebi kendi i\u015f kesici i\u015flemlerimizide kullan\u0131c\u0131ya throw atarak g\u00f6sterece\u011fim. <\/p>\n\n\n\n<p>\u015euana kadar yapt\u0131\u011f\u0131m\u0131z i\u015flemlerde hatay\u0131 kendi CustomException s\u0131n\u0131f\u0131ndan handle edilmesini sa\u011flad\u0131k. \u015eimdi gerekli konfig\u00fcrasyonlar\u0131m\u0131z\u0131 yaparak yakalanan hataya nas\u0131l i\u015flem yapmam\u0131z gerekti\u011fini belirleyece\u011fiz.<\/p>\n\n\n\n<p>API katman\u0131na CustomExceptionExtension ad\u0131nda bir s\u0131n\u0131f olu\u015fturuyorum.<\/p>\n\n\n\n<pre class=\"wp-block-syntaxhighlighter-code\">    public static class     public static class CustomExceptionExtension\n\n    {\n        public static void ConfigureExceptionHandler(this IApplicationBuilder app)\n        {\n            app.UseExceptionHandler(appError =>\n            {\n                appError.Run(async context =>\n                {\n\n                    context.Response.ContentType = \"application\/json\";\n\n                    var contextFeature = context.Features.Get&lt;IExceptionHandlerFeature>();\n                    CustomException exception = (CustomException)contextFeature.Error;\n                    if (exception.Code == \"500\")\n                    {\n                        context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;\n                    }\n                    else\n                    {\n                        context.Response.StatusCode = (int)HttpStatusCode.OK;\n                    }\n                    if (contextFeature != null)\n                    {\n                        \n                        await context.Response.WriteAsync(new OperationResult()\n                        {\n                            IsSuccessful = false,\n                            ReturnCode = Convert.ToInt32(exception.Code),\n                            ReturnMessage = contextFeature.Error.Message\n\n                        }.ToString());\n                    }\n                });\n            });\n        }\n    }<\/pre>\n\n\n\n<p>Yukar\u0131daki  CustomExceptionExtension s\u0131n\u0131f\u0131nda business katman\u0131nda yakalanan hatay\u0131 kendi CustomException s\u0131n\u0131f\u0131na cast edilmesini sa\u011fl\u0131yoruz. Burada e\u011fer hata kodu &#8220;500&#8221; d\u0131\u015f\u0131nda bir de\u011fer gelerek throw f\u0131rlat\u0131l\u0131rsa kendi i\u015f kesicilerimiz oldu\u011funu anl\u0131yoruz. Response&#8217;nin d\u00f6nece\u011fi modeli yani OperationResult modeline gerekli atamalar\u0131 yaparak. Response edilmesini sa\u011fl\u0131yoruz.<\/p>\n\n\n\n<p>Business katman\u0131na UserBusiness ad\u0131nda bir s\u0131n\u0131f ekliyorum. Ve i\u00e7erisine basit bir Login methodu yaz\u0131yorum.<\/p>\n\n\n\n<pre class=\"wp-block-syntaxhighlighter-code\">    public class UserBusiness :  BusinessBase,IUserBusiness\n    {\n        public UserLoginOutput Login(UserLoginInput input)\n        {\n            return base.ExecuteWithExceptionHandledOperation(() =>\n            {\n                throw new ArgumentNullException();\n                if (input.Email == \"yusufcelik38@gmail.com\" &amp;&amp; input.Password == \"123\")\n                {\n                    return new UserLoginOutput()\n                    {\n                        Id = \"1\",\n                        OperationResult = new OperationResult()\n                    };\n                }\n                else\n                {\n                    throw new CustomException(\"200\", \"Kullan\u0131c\u0131 ad\u0131 veya \u015fifre yanl\u0131\u015f\");\n                }\n\n            });\n\n            }\n    }<\/pre>\n\n\n\n<p>Yukar\u0131da i\u015flemde g\u00f6r\u00fcld\u00fc\u011f\u00fc gibi kendi business katman\u0131m\u0131zdaki i\u015flemler i\u00e7inde olu\u015fturdu\u011fumuz CustomException s\u0131n\u0131f\u0131n\u0131 kulland\u0131m. Burada BusinessBase s\u0131n\u0131f\u0131nda olu\u015fturdu\u011fumuz ExceptionHandler method sayesinde i\u015flem Invoke olacak veya da catch blo\u011funa d\u00fc\u015fecektir. <\/p>\n\n\n\n<p>WebApi katman\u0131ndaki Startup.cs s\u0131n\u0131f\u0131na dependency injection&#8217;\u0131 sa\u011flamak i\u00e7in   a\u015fa\u011f\u0131daki konfig\u00fcrasyonu ekliyoruz. Vede olu\u015fturdu\u011fumuz exception handler konfig\u00fcrasyonunu ekliyoruz.<\/p>\n\n\n\n<pre class=\"wp-block-syntaxhighlighter-code\">        public void ConfigureServices(IServiceCollection services)\n        {\n            ...\n            services.AddScoped&lt;IUserBusiness, UserBusiness>();\n        }\n        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)\n        {\n            ...\n            app.ConfigureExceptionHandler();\n            app.UseRouting();\n            ...\n        }<\/pre>\n\n\n\n<p>\u015eimdi WebApi katman\u0131na bir UserController ad\u0131nda bir controller ekliyorum. Ve i\u00e7erisine Login methodu ekliyorum. <\/p>\n\n\n\n<pre class=\"wp-block-syntaxhighlighter-code\">[Route(\"api\/[controller]\")]\n[ApiController]\npublic class UserController : ControllerBase\n{\n    private readonly IUserBusiness _business;\n    public UserController(IUserBusiness business)\n    {\n        _business = business;\n    }\n    [HttpPost]\n    public UserLoginOutput Login(UserLoginInput userLoginInput)\n    {\n        return _business.Login(userLoginInput);\n    }\n }<\/pre>\n\n\n\n<p>\u0130\u015flemler esnas\u0131nda bizim olu\u015fturdu\u011fumuz hata durumundaki olu\u015fan response  ve i\u015flem ba\u015far\u0131l\u0131 olma durumunda olu\u015fan response a\u015fa\u011f\u0131daki gibidir.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" loading=\"lazy\" width=\"1024\" height=\"300\" src=\"https:\/\/blog.yusufcelik.net\/wp-content\/uploads\/2019\/10\/image-5-1024x300.png\" alt=\"\" class=\"wp-image-130\" srcset=\"http:\/\/blog.yusufcelik.net\/wp-content\/uploads\/2019\/10\/image-5-1024x300.png 1024w, http:\/\/blog.yusufcelik.net\/wp-content\/uploads\/2019\/10\/image-5-300x88.png 300w, http:\/\/blog.yusufcelik.net\/wp-content\/uploads\/2019\/10\/image-5-768x225.png 768w, http:\/\/blog.yusufcelik.net\/wp-content\/uploads\/2019\/10\/image-5.png 1601w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" loading=\"lazy\" width=\"1024\" height=\"364\" src=\"https:\/\/blog.yusufcelik.net\/wp-content\/uploads\/2019\/10\/image-6-1024x364.png\" alt=\"\" class=\"wp-image-131\" srcset=\"http:\/\/blog.yusufcelik.net\/wp-content\/uploads\/2019\/10\/image-6-1024x364.png 1024w, http:\/\/blog.yusufcelik.net\/wp-content\/uploads\/2019\/10\/image-6-300x107.png 300w, http:\/\/blog.yusufcelik.net\/wp-content\/uploads\/2019\/10\/image-6-768x273.png 768w, http:\/\/blog.yusufcelik.net\/wp-content\/uploads\/2019\/10\/image-6.png 1490w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>\u015eimdi de i\u015flem esnas\u0131nda hata olu\u015fturmak i\u00e7in kodun ba\u015f\u0131na throw f\u0131rlatarak nullexception atmas\u0131n\u0131 sa\u011flad\u0131m. \u015eimdi de onun \u00e7\u0131kt\u0131s\u0131n\u0131 g\u00f6relim.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" loading=\"lazy\" width=\"1024\" height=\"113\" src=\"https:\/\/blog.yusufcelik.net\/wp-content\/uploads\/2019\/10\/image-7-1024x113.png\" alt=\"\" class=\"wp-image-132\" srcset=\"http:\/\/blog.yusufcelik.net\/wp-content\/uploads\/2019\/10\/image-7-1024x113.png 1024w, http:\/\/blog.yusufcelik.net\/wp-content\/uploads\/2019\/10\/image-7-300x33.png 300w, http:\/\/blog.yusufcelik.net\/wp-content\/uploads\/2019\/10\/image-7-768x84.png 768w, http:\/\/blog.yusufcelik.net\/wp-content\/uploads\/2019\/10\/image-7.png 1610w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>G\u00f6r\u00fcld\u00fc\u011f\u00fc gibi kendi olu\u015fturdu\u011fumuz i\u015flem hatas\u0131nda status &#8220;200&#8221; yani ba\u015far\u0131l\u0131 gelmi\u015fti. Bizim olu\u015fturdu\u011fumuz i\u015flem d\u0131\u015f\u0131ndaki hatalarda status &#8220;500&#8221; yani internal server error \u015feklinde verdi. <\/p>\n\n\n\n<p>Yapt\u0131\u011f\u0131m\u0131z bu i\u015flemler sayesinde hem ba\u015far\u0131l\u0131 olma durumunu, i\u015f kesici hatalar\u0131m\u0131z\u0131 ve bizim d\u0131\u015f\u0131m\u0131zdan kaynaklanan hatalar\u0131 kullan\u0131c\u0131ya ayn\u0131 formattaki response&#8217;nin d\u00f6nmesini sa\u011flad\u0131k.<\/p>\n\n\n\n<p>Umar\u0131m yarar\u0131 olmu\u015ftur. Makalenin kaynak kodlar\u0131na <strong><a href=\"https:\/\/github.com\/yusufcelik38\/ExceptionHandlerMiddleware\">burdan<\/a><\/strong> eri\u015febilirsiniz.<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Merhaba, Bug\u00fcn ki makalemizde .Net Core Web API MiddleWare&#8216;de Custom exception handler yapaca\u011f\u0131z. Kullan\u0131c\u0131lar\u0131m\u0131za sundu\u011fumuz bir servis&#8217;te i\u015flem esnas\u0131nda herhangi bir hata olu\u015ftu\u011funda kullan\u0131c\u0131ya e\u011fer bir mesaj d\u00f6ndermessek exception&#8217;\u0131n tamam\u0131n\u0131 servis \u00e7a\u011f\u0131r\u0131ld\u0131\u011f\u0131nda exception detay\u0131na&#46;&#46;&#46;<\/p>\n","protected":false},"author":1,"featured_media":136,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[],"tags":[],"_links":{"self":[{"href":"http:\/\/blog.yusufcelik.net\/index.php\/wp-json\/wp\/v2\/posts\/117"}],"collection":[{"href":"http:\/\/blog.yusufcelik.net\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/blog.yusufcelik.net\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/blog.yusufcelik.net\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/blog.yusufcelik.net\/index.php\/wp-json\/wp\/v2\/comments?post=117"}],"version-history":[{"count":12,"href":"http:\/\/blog.yusufcelik.net\/index.php\/wp-json\/wp\/v2\/posts\/117\/revisions"}],"predecessor-version":[{"id":143,"href":"http:\/\/blog.yusufcelik.net\/index.php\/wp-json\/wp\/v2\/posts\/117\/revisions\/143"}],"wp:featuredmedia":[{"embeddable":true,"href":"http:\/\/blog.yusufcelik.net\/index.php\/wp-json\/wp\/v2\/media\/136"}],"wp:attachment":[{"href":"http:\/\/blog.yusufcelik.net\/index.php\/wp-json\/wp\/v2\/media?parent=117"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/blog.yusufcelik.net\/index.php\/wp-json\/wp\/v2\/categories?post=117"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/blog.yusufcelik.net\/index.php\/wp-json\/wp\/v2\/tags?post=117"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}