locked
The requested resource does not support http method 'GET' RRS feed

  • Question

  • User-820817604 posted

    Storytime:
    So, im currently implementing my Azure SQL DB with my Xamarin android app, however ive hit a roadblock as i cant post directly to the database from android(from my console project i can read/write to it just fine so its not a problem with the database setup). I then created a simple web api to handle the database calls as suggested by others, by following this guide:
    https://www.c-sharpcorner.com/article/xamarin-android-create-login-with-web-api-using-azure-sql-server-part-one/
    I got the login/get part to work, but when i try to post data to the database trough the web api, it returns the following error: " The requested resource does not support http method 'GET'" which is strange since its a post method. After doing some debugging, i found out that its in the apis database.SaveChanges(); call that breaks the code, but i dont know how to fix it. Ive done alot of reading around and used Postman to test

    My questions:
    Anyone else who have had succes following this guide?
    What can i have done wrong since its trying to convert my Post method into a get method?

    Thanks in advance for any tip or input you might have!

    // My routing configuration
    public static class WebApiConfig
    {
    public static void Register(HttpConfiguration config)
    {
    // Web API configuration and services

    // Web API routes
    config.MapHttpAttributeRoutes();

    config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { id = RouteParameter.Optional }
    );

    var json = config.Formatters.JsonFormatter;

    json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;

    json.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();

    config.Formatters.Remove(config.Formatters.XmlFormatter);
    }
    }

    // The api method
    [ActionName("CreateTest")]
    [Route("api/CreateTest")]
    [HttpPost]
    public HttpResponseMessage CreateTest()
    {
    UserAccount newAccount = new UserAccount();
    newAccount.Name = "Testname";
    newAccount.Password = "password";
    newAccount.Email = "email";

    db.UserAccounts.Add(newAccount);

    db.SaveChanges();
    return Request.CreateResponse(HttpStatusCode.Accepted, "Successfully TestCreate");
    }

    Sunday, August 26, 2018 11:35 AM

All replies

  • User1120430333 posted

    You could make the API call a classlib project call it a DAL where the CRUD is actually done and see what happens.

    The code is using the DAO pattern in the DAL and both projects are using  the DTO pattern with the DTO in the Entities classlib project and bot projects has reference to Entities.

     https://www.tutorialspoint.com/design_pattern/data_access_object_pattern.htm

    https://www.codeproject.com/Articles/1050468/Data-Transfer-Object-Design-Pattern-in-Csharp

    using System.Collections.Generic;
    using DAL;
    using Entities;
    using Microsoft.AspNetCore.Mvc;
    
    namespace ProgMgmntCore2Api.Controllers
    {
        [Produces("application/json")]
        [Route("api/[controller]")]
        [ApiController]
    
        public class ProjectController : ControllerBase, IProjectController
        {
            private readonly IDaoProject _daoProject;
    
            public ProjectController(IDaoProject daoProject)
            {
                _daoProject = daoProject;
            }
    
            [HttpGet]
            [Route("GetProjById")]
            public DtoProject GetProjectById(int id)
            {
                return  _daoProject.GetProjectById(id);
            }
            
            [HttpGet]
            [Route("GetProjsByUserId")]
            public List<DtoProject> GetProjectsByUserId(string userid)
            {
                return _daoProject.GetProjectsByUserId(userid);
            }
    
            [HttpPost]
            [Route("CreateProject")]
            public void Post_CreateProject(DtoProject dto)
            {
                _daoProject.CreateProject(dto);
            }
    
            [HttpPost]
            [Route("DeleteProject")]
            public void Post_DeleteProject(DtoId dto)
            {
                _daoProject.DeleteProject(dto.Id);
            }
    
            [HttpPost]
            [Route("UpdateProject")]
            public void Post_UpdateProject(DtoProject dto)
            {
                _daoProject.UpdateProject(dto);
            }
        }
    }
    ==========================================================
    using System.Collections.Generic;
    using System.Linq;
    using System.Transactions;
    using DAL.Models.DB;
    using Entities;
    using Microsoft.EntityFrameworkCore;
    using Microsoft.Extensions.Options;
    
    namespace DAL
    {
        public class DaoProject :IDaoProject
        {
            private readonly IOptions<ConnectionStrings> _options;
            
            public DaoProject(IOptions<ConnectionStrings> options)
            {
                _options = options;
            }
            public DtoProject GetProjectById(int id)
            {
                var dto = new DtoProject();
    
                using (var context = new ProjectManagementContext(_options))
                {
                    var project = (context.Projects.Where(a => a.ProjectId == id)).SingleOrDefault();
    
                    if (project == null) return dto;
                    dto.ProjectId = project.ProjectId;
                    dto.ClientName = project.ClientName;
                    dto.ProjectName = project.ProjectName;
                    dto.Technology = project.Technology;
                    dto.ProjectType = project.ProjectType;
                    dto.UserId = project.UserId;
                    dto.StartDate = project.StartDate;
                    dto.EndDate = project.EndDate;
                    dto.Cost = project.Cost;
                }
    
                return dto;
            }
    
            public List<DtoProject> GetProjectsByUserId(string userid)
            {
                var dtos = new List<DtoProject>();
    
                using (var context = new ProjectManagementContext(_options))
                {
                    
                    dtos = (from a in context.Projects.Where(a => a.UserId.Contains(userid))
                        select new DtoProject
                        {
                            ProjectId = a.ProjectId,
                            ClientName = a.ClientName,
                            ProjectName = a.ProjectName,
                            Technology = a.Technology,
                            ProjectType = a.ProjectType,
                            UserId = a.UserId,
                            StartDate = a.StartDate,
                            EndDate = a.EndDate,
                            Cost = a.Cost
                        }).ToList();
                }
    
                return dtos;
            }
    
            public void CreateProject(DtoProject dto)
            {
                using (var context = new ProjectManagementContext(_options))
                {
                    var project = new Projects
                    {
                        ClientName = dto.ClientName,
                        ProjectName = dto.ProjectName,
                        Technology = dto.Technology,
                        ProjectType = dto.ProjectType,
                        UserId = dto.UserId,
                        StartDate = dto.StartDate,
                        EndDate = dto.EndDate,
                        Cost = dto.Cost
                    };
    
                    context.Projects.Add(project);
                    context.SaveChanges();
               }
            }
    
            public void UpdateProject(DtoProject dto)
            {
                var project = new Projects();
                
                using (var context = new ProjectManagementContext(_options))
                {
                   project = (context.Projects.Where(a => a.ProjectId == dto.ProjectId)).SingleOrDefault();
                }
    
                if (project != null)
                {
                    project.ClientName = dto.ClientName;
                    project.ProjectName = dto.ProjectName;
                    project.Technology = dto.Technology;
                    project.ProjectType = dto.ProjectType;
                    project.UserId = dto.UserId;
                    project.StartDate = dto.StartDate;
                    project.EndDate = dto.EndDate;
                    project.Cost = dto.Cost;
                }
    
                using (var dbcontext = new ProjectManagementContext(_options))
                {
                    if (project == null) return;
                    dbcontext.Entry(project).State = EntityState.Modified;
                    dbcontext.SaveChanges();
                }
            }
    
            public void DeleteProject(int id)
            {
                Projects project;
    
                using (var context = new ProjectManagementContext(_options))
                {
                   project = (context.Projects.Where(a => a.ProjectId == id)).SingleOrDefault();
                }
    
                if (project == null) return;
    
                using (var newContext = new ProjectManagementContext(_options))
                {
                   
                    var tasks = new DaoTask(_options).GetTasksByProjectId(project.ProjectId);
                    using (TransactionScope scope = new TransactionScope())
                    {
                        foreach (var task in tasks)
                        {
                            new DaoTask(_options).DeleteTask(task.TaskId);
                        }
    
                        newContext.Entry(project).State = EntityState.Deleted;
                        newContext.SaveChanges();
    
                        scope.Complete();
                    }
                }
            }
        }
    }
    =================================================
    using System;
    
    namespace Entities
    {
        public class DtoProject
        {
            public int ProjectId { get; set; }
            public string ClientName { get; set; }
            public string ProjectName { get; set; }
            public string Technology { get; set; }
            public string ProjectType { get; set; }
            public string UserId { get; set; }
            public DateTime StartDate { get; set; }
            public DateTime EndDate { get; set; }
            public decimal Cost { get; set; }
        }
    }
    

    Sunday, August 26, 2018 12:39 PM
  • User475983607 posted

    Maybe the code is throwing an exception and the error message is related to redirecting to an error page.  I noticed the email address is not a valid email address string.  

    Try setting a breakpoint and debugging the code.

    Sunday, August 26, 2018 2:28 PM
  • User-820817604 posted

    Maybe the code is throwing an exception and the error message is related to redirecting to an error page.  I noticed the email address is not a valid email address string.  

    Try setting a breakpoint and debugging the code.


    It was a good suggestion that i could have missed, however at the moment the email field in my sql database is just taking any string so its not requred to be formatted as a valid email :) 

    About the breakpoints, i tried, and for the working methods like Login the webapi enters the method, however for my Create it doesnt, it just instantly returns the error that the requested resource does not support http method "GET". :/ 

    Monday, August 27, 2018 5:31 AM
  • User-820817604 posted

    Reply: DA924

    Thanks for your great post, i can tell you put effort into it! However you mention a couple of technoligies ive never heard about before, and i fear it will just make it even harder for myself to debug it if i start to complicate things further.

    I also feel like there shouldnt be needed such extensive solutions to just POST something to my Azure sql database from my Xamarin app via my web api. Im gonna keep trying to see if i cant get this to work somehow, i feel like i should be able to :) If not, i might try out your suggestion!

    Monday, August 27, 2018 5:41 AM
  • User1120430333 posted

    KalleN

    Reply: DA924

    Thanks for your great post, i can tell you put effort into it! However you mention a couple of technoligies ive never heard about before, and i fear it will just make it even harder for myself to debug it if i start to complicate things further.

    I also feel like there shouldnt be needed such extensive solutions to just POST something to my Azure sql database from my Xamarin app via my web api. Im gonna keep trying to see if i cant get this to work somehow, i feel like i should be able to :) If not, i might try out your suggestion!

    Think about it….. If you're going to do it, then do it right learn how to architect.

    https://en.wikipedia.org/wiki/Separation_of_concerns

    I am just using a DAO pattern with a Data Access Layer instead of the Repository pattern,  and I am usinf the DTO pattern a Layered design

    https://docs.microsoft.com/en-us/previous-versions/msp-n-p/ee658117(v=pandp.10)

    https://docs.microsoft.com/en-us/aspnet/core/fundamentals/repository-pattern?view=aspnetcore-2.1

    https://programmingwithmosh.com/entity-framework/common-mistakes-with-the-repository-pattern/

    ASP.NET MVC client to ASP.NET WebAPI server, client/server style, ASP.NET WebAPI using DAL a Layered style with both sides using the same DTO(s).

    It's just design patterns no more or no less and the interactions of objects.

    https://www.dofactory.com/net/design-patterns

    <copied>

    Design patterns are solutions to software design problems you find again and again in real-world application development. Patterns are about reusable designs and interactions of objects.

    <end>

    Monday, August 27, 2018 8:59 AM
  • User475983607 posted

    it just instantly returns the error that the requested resource does not support http method "GET". :/ 

    Keep in mind that you originally stated the error happened on database.SaveChanges() which indicates the action was invoked.

    This new information indicates a routing or client bug.  Verify the request is properly formatted.  The community can provide accurate assistance if all the relevant code is posted.

    Monday, August 27, 2018 10:56 AM
  • User753101303 posted

    Hi,

    So it seems database.SaveChanges();  is throwing an exception. What happens for now when an exception happens? You could even explicitely throw an exception to test for this and to handle this properly on both sides.

    For now you perhaps redirect to page ? By default the post should return an http 500 status and the exception should be written to the Windows event log.

    Monday, August 27, 2018 11:27 AM
  • User-820817604 posted

    Sorry everyone for wasting your time, i just found it the error, and its... Embarrasing... Here goes... 3...2...1...

    My post method was trying to add with a primary key id that already existed..... How i did not notice that, or get some kind of tip of it while debugging baffles me still....

    Anyway problem solved, and thanks for all of your inputs, it has tought me more about how these technologies work even if they werent needed to solve the issue :) Cheers!

    Monday, August 27, 2018 6:53 PM
  • User1120430333 posted

    Sorry everyone for wasting your time, i just found it the error, and its... Embarrasing... Here goes... 3...2...1...

    My post method was trying to add with a primary key id that already existed..... How i did not notice that, or get some kind of tip of it while debugging baffles me still....

    Anyway problem solved, and thanks for all of your inputs, it has tought me more about how these technologies work even if they werent needed to solve the issue :) Cheers!

    It would have been caught if you had global exception handling on the WebAPI, becuase an exception truly had to have been thrown on a duplicate key exception thrown by the database.

    https://stackify.com/csharp-catch-all-exceptions/

    Imports System.Net
    Imports System.Net.Http
    Imports System.Web.Http.Filters
    Imports log4net
    
    Public Class CustomExceptionFilter
        Inherits ExceptionFilterAttribute
    
        private ReadOnly _logger As ILog
    
        public sub New()
            _logger = LogManager.GetLogger(GetType(CustomExceptionFilter))
        End sub
    
        Public Overrides Sub OnException(actionExecutedContext As HttpActionExecutedContext)
            MyBase.OnException(actionExecutedContext)
    
            Dim exceptionMessage as String = String.Empty
    
            If IsNothing(actionExecutedContext.Exception.InnerException ) Then
                exceptionMessage = actionExecutedContext.Exception.Message _
                                   & " " & actionExecutedContext.Exception.StackTrace
            Else 
                exceptionMessage =  actionExecutedContext.Exception.Message _
                                    & " " & actionExecutedContext.Exception.InnerException.Message _
                                    & " " & actionExecutedContext.Exception.StackTrace
            End If
    
            _logger.Error(exceptionMessage)
    
            dim response =  New HttpResponseMessage(HttpStatusCode.InternalServerError)With {.Content = New StringContent(“An unhandled exception was thrown by service.”),
                    .ReasonPhrase = "Internal Server Error.Please Contact your Administrator."}
    
            actionExecutedContext.Response = response
    
        End Sub
    End Class
    
    =================================================================
    
    Imports System.Web.Http
    Imports DAL
    Imports Entities
    
    Namespace Controllers
    
        <CustomExceptionFilter>
        Public Class ProjectController
            Inherits ApiController
    
            Private ReadOnly _daoproject As IDaoProject
    
            public sub New (daoproject As IDaoProject)
                _daoproject = daoproject
            End sub
    
            <HttpGet>
            <ActionName("GetProjectById")>
            public Function GetProjectById(ByVal id As Int32) As DtoProject
                return _daoproject.GetProjectById(id)
            End Function
    
    
            <HttpGet>
            <ActionName("GetProjectsByUserId")>
            public Function GetProjectsByUserId(ByVal userid As String) As List(Of DtoProject)
                return _daoproject.GetProjectsByUserId(userid)
            End Function
    
            <HttpPost>
            <ActionName("CreateProject")>
            public sub CreateProject(ByVal dto As DtoProject)
                Call _daoproject.CreateProject(dto)
            End sub
            
            <HttpPost>
            <ActionName("UpdateProject")>
            public sub UpdateProject(ByVal dto As DtoProject)
                Call _daoproject.UpdateProject(dto)
            End sub
    
            <HttpPost>
            <ActionName("DeleteProject")>
            public sub  DeleteProject(ByVal dto As DtoId)
                Call _daoproject.DeleteProject(dto.Id)
            End sub
            
        End Class
    End Namespace


     

    Monday, August 27, 2018 7:20 PM