0

I have create a WEB API using ASP.NET MVC WEB API 2.0. Web API contain methods like login, register, etc.
I am using AngularJS to call the WEB API methods, But it call twice. For e.g. when I call POST method it first call OPTION (I have not created any OPTION method) and then it call the POST method.
My Code: (for login)
HTML:

<div class="container" ng-controller="UserAccount">
    <form ng-submit="loginNow(user)">
        <input type="email" placeholder="Enter Email" required ng-model="user.email" id="txtEmail" class="form-control" />
        <br />
        <input type="password" placeholder="Enter Password" required ng-model="user.password" id="txtPwd" class="form-control" />
        <br />
        <button type="submit" class="btn btn-primary">Login</button>
    </form>
</div>


AngularJS Controller:

$scope.loginNow = function (user) {
        $http.post(rootURL + "login", { email: user.email, password: user.password })
            .success(function (data) {
                if (data.id > 0) {
                    sessionStorage.setItem('userid', data.id);
                    window.location = '/';
                }
            });
}


WEB API:

public class UsersController : ApiController
    {
        private UserEntities db = new UserEntities();

        // GET: api/Users
        public IQueryable<Users_tbl> GetUsers_tbl()
        {
            return db.Users_tbl;
        }

        [ActionName("login")]
        public IHttpActionResult PostUser_Login(string email, string password)
        {
            int id = db.Users_tbl.Where(a => a.email == email && a.password == password).Select(a => a.id).SingleOrDefault();
            if(id <= 0)
            {
                return NotFound();
            }
            return Ok(id);
        }

        [ActionName("register")]
        public int PostUser_Register(string email, string password)
        {
            int id = db.Users_tbl.Where(a => a.email == email).Select(a => a.id).SingleOrDefault();
            if(id > 0)
            {
                return 1;
            }
            Users_tbl user = new Users_tbl();
            user.email = email;
            user.password = password;
            try
            {
                db.Users_tbl.Add(user);
                db.SaveChanges();
            }
            catch
            {
                return 2;
            }
            return 0;
        }


        // GET: api/Users/5
        [ResponseType(typeof(Users_tbl))]
        public IHttpActionResult GetUsers_tbl(int id)
        {
            Users_tbl users_tbl = db.Users_tbl.Find(id);
            if (users_tbl == null)
            {
                return NotFound();
            }

            return Ok(users_tbl);
        }


        // PUT: api/Users/5
        [ResponseType(typeof(void))]
        public IHttpActionResult PutUsers_tbl(int id, Users_tbl users_tbl)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            if (id != users_tbl.id)
            {
                return BadRequest();
            }

            db.Entry(users_tbl).State = EntityState.Modified;

            try
            {
                db.SaveChanges();
            }
            catch (DbUpdateConcurrencyException)
            {
                if (!Users_tblExists(id))
                {
                    return NotFound();
                }
                else
                {
                    throw;
                }
            }

            return StatusCode(HttpStatusCode.NoContent);
        }

        [ActionName("profile")]
        // POST: api/Users
        [ResponseType(typeof(Users_tbl))]
        public IHttpActionResult PostUsers_tbl(Users_tbl users_tbl)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            db.Users_tbl.Add(users_tbl);
            db.SaveChanges();

            return CreatedAtRoute("DefaultApi", new { id = users_tbl.id }, users_tbl);
        }

        // DELETE: api/Users/5
        [ResponseType(typeof(Users_tbl))]
        public IHttpActionResult DeleteUsers_tbl(int id)
        {
            Users_tbl users_tbl = db.Users_tbl.Find(id);
            if (users_tbl == null)
            {
                return NotFound();
            }

            db.Users_tbl.Remove(users_tbl);
            db.SaveChanges();

            return Ok(users_tbl);
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                db.Dispose();
            }
            base.Dispose(disposing);
        }

        private bool Users_tblExists(int id)
        {
            return db.Users_tbl.Count(e => e.id == id) > 0;
        }
    }
2
  • ActionName is specific to MVC, not to Web API. You should be using Route on your ApiController routes. I do not know what you are talking about though when you say that it should call Option and there is no indication that it should call the login method twice for one call. Commented Oct 7, 2016 at 9:58
  • Which server you are using to host/serve AngualrJS code? Commented Oct 7, 2016 at 10:17

2 Answers 2

8

This is the browser default behavior. Before sending corss-domain AJAX call, browser sends a pre-flight request (OPTION request) Why?

Have a look over here on how you can minimize pre-flight request:

Update

If you really want not to send pre-flight request, you can opt by not violating Same Origin Policy (SOP). Possible solution can be:

JSONP: This is a technique that exploits the HTML script element exception to the same-origin security policy. Script tags can load JavaScript from a different domain and query parameters can be added to the script URI to pass information to the server hosting the script about the resources that you wish to access. The JSONP server will return JavaScript that is evaluated in the browser that calls an agreed upon JavaScript function already on the page to pass server resource data into your page.

Server Side Proxy: An alternative to circumventing the Same-Origin Policy to perform Cross-Domain requests is to simply not make any Cross-Domain requests at all! If you use a proxy that resides in your domain, you can simply use this to access the external service from your back-end code and forward the results to your client code. Because the requesting code and the proxy reside in the same domain, the SOP is not violated.

UPDATE You can respond to OPTIONS request from Web API 2 so that doesn't throw 405 or 404. Have a look over here https://stackoverflow.com/a/37425746/2509344

Sign up to request clarification or add additional context in comments.

Comments

0

This is happening because of , when ever the page is loading, at that time during initialization it is happening once and then when you will press login now it will call again.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.