While Calling Web.api getting 'Method not allowed' error' - asp.net-mvc

While consuming the web.Api i am getting method not allowed(405). i followed all step but issue is still there. But when I test through soapUi it works well. Please help
Web.Api Declaration:
[Route("ForgotPassword")]
[AcceptVerbs( "POST")]
public ForgotPasswordResponse ForgotPassword(string emailId)
{
AccountInfo accountInfo = _manager.GetUserByEmailId(emailId);
if (accountInfo == null)
return new ForgotPasswordResponse
{
Response = "error",
Message = "Email address not found"
};
return new ForgotPasswordResponse
{
Response = "success",
Message = "password reset link set to registered email id"
};
}
Consuming Service call:
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://100.7.11.76");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var response12 = client.GetAsync("test.Api/api/account/ForgotPassword?EmailId=" + email + "").Result;
if (response12.IsSuccessStatusCode)
{
string responseString = response12.Content.ReadAsStringAsync().Result;
}
}

Your WebAPI controller ForgotPasswordResponse accepts the verb "POST" and your WebAPI client is invoking it as GET. Hence you get 406: Method not allowed response. Either make your controller accept GET verb or invoke the WebAPI using PostAsJsonAsync method instead of GetAsync.

Try to use Authentication Filters [AllowAnonymous]
[AllowAnonymous]
[Route("ForgotPassword")]
[AcceptVerbs( "POST")]
public ForgotPasswordResponse ForgotPassword(string emailId)
{
AccountInfo accountInfo = _manager.GetUserByEmailId(emailId);
if (accountInfo == null)
return new ForgotPasswordResponse
{
Response = "error",
Message = "Email address not found"
};
return new ForgotPasswordResponse
{
Response = "success",
Message = "password reset link set to registered email id"
};
}

Change the Route attribute to [Route("api/account/ForgotPassword")], change from POST to GET and test your method from a REST client like PostMan first and then use it in your application.

Related

Failure to getting response from post request in HttpResponseMessage

I read a lot of questions and tested a lot of code but I couldn't solve my problem.
I want call rest API (that write with php code) in asp controller.
I tested my web service with postman app and get responds correctly from web service . But I can't get the right answer through asp request.
My problem: I get status code 200 for response(in asp controller) But the instructions on the web service are not executed(for example: don't register user). Where can I find the problem and get the data in the answer?
public async Task registerInShop()
{
try
{
ShopUserModel model = new ShopUserModel()
{
user_login = "ff",
user_pass = "v12315",
user_nicename = "",
user_url = "",
user_registered = "",
user_activation_key = "",
user_status = 0,
display_name = "ff",
};
JsonResult json = Json(model, JsonRequestBehavior.AllowGet);
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("domainurl/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
HttpResponseMessage response = await client.PostAsJsonAsync("shopktphp/register.php", json.Data);
response.EnsureSuccessStatusCode();
if (response.IsSuccessStatusCode)
{ // Get the URI of the created resource.
Uri returnUrl = response.Headers.Location;
var res = response.Content;
Console.WriteLine(returnUrl);
}
}
}
catch (Exception ex)
{
Elmah.ErrorLog.GetDefault(null).Log(new Elmah.Error(ex));
}
}
I successful finding answer of my question. I change only URI of base address and set by this: "domainurl/shopktphp/"
and set Post json async by "register.php"
client.BaseAddress = new Uri("domainurl/shopktphp/");
HttpResponseMessage response = await client.PostAsJsonAsync("register.php", json.Data);

Email view not found for 'model' in Postal.MVC

I am using Postal.MVC5 in my ASP MVC5 project. Initially i had my smtp configuration in web.config so this piece of code was working just fine and was able to send email successfully.
public async Task<ActionResult>SendEmail(EmployeeViewModel emailModel)
{
string _errorMessage;
emailModel.To = "john#outlook.com";
emailModel.Subject = "Test Subject";
emailModel.Message = "Test Message";
await emailModel.SendAsync();
return Json(new {ErrorMessage = _errorMessage});
}
Now, i need to setup Smtpclient during runtime and followed steps shown in this stackoverflow post: How to Set SMTP Client in POSTAL MVC not in WEB.Config
public async Task<ActionResult>SendEmail(EmployeeEmailViewModel emailModel)
{
string _errorMessage;
emailModel.To = "john#outlook.com";
emailModel.Subject = "Test Subject";
emailModel.Message = "Test Message";
//new code
SmtpClient client = new SmtpClient("smtp.test.com");
client.UseDefaultCredentials = false;
client.Credentials = new NetworkCredential("secretId", "notSecretPassword");
client.DeliveryMethod = SmtpDeliveryMethod.Network;
client.Port = 111;
client.EnableSsl = true;
Postal.EmailService emailService = new EmailService(new ViewEngineCollection(), () => client);
await emailService.SendAsync(emailModel);
return Json(new {ErrorMessage = _errorMessage});
}
Now this code throws an error something like this:
System.Exception: Email view not found for EmployeeEmailViewModel. Locations searched:
at Postal.EmailViewRenderer.CreateView(String viewName, ControllerContext controllerContext)
at Postal.EmailViewRenderer.Render(Email email, String viewName)
I do have 'EmployeeEmailViewModel' view in ~/Views/Emails/EmployeeEmailViewModel.cshtml .
Any idea why i am getting this error message or how i can resolve it?
Thanks
Sanjeev

How to keep response body when MVC action returns error status?

I want to return BadRequest status and error message from my MVC controller:
public class TestController : System.Web.Mvc.Controller
{
public ActionResult Bad()
{
Response.StatusCode = 400;
return new JsonResult()
{
Data = new { Message = "Request is bad!" },
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
}
It works when I launch application in IISExpress, the method returns response body:
{"Message":"Request is bad!"}
But when I deploy same site to IIS (ver. 8.5) the response body changed to:
Bad Request
Why this happen? Is there some settings that allows to keep response body when status is not 200?
I found two solutions:
Set Response.TrySkipIisCustomErrors to true.
Set existingResponse to PassThrough in httpErrors

Unable to send data from actionResult to asyn mothod in mvc

This is my controller actionReslt
[ValidateAntiForgeryToken()]
public ActionResult PaymentDetails(PaymentViewModel payment)
{
PaymentModel paymentModel = new PaymentModel();
// AutoMapper.Mapper.CreateMap<PaymentModel, PaymentViewModel>();
if (ModelState.IsValid)
{
CreditCardDetailsModel creditCardDetailsModel = new CreditCardDetailsModel();
creditCardDetailsModel.SecurityId = payment.SecurityId;
creditCardDetailsModel.ExpiryDate = payment.Month + payment.Year;
creditCardDetailsModel.CardNumber = payment.CardNumber;
paymentModel.CreditCardDetails = creditCardDetailsModel;
return RedirectToAction("Payment",paymentModel);
}
return View("FlightBooking");
}
and this is my async method
public async Task<JsonResult> Payment(PaymentModel model)
{
CreateFormOfPaymentReplyModel response = new CreateFormOfPaymentReplyModel();
resource = Constants.Payment;
response = await Post<CreateFormOfPaymentReplyModel>(model);
resource = Constants.PnrConfirm;
var pnrConformStatus = await Get<PNRConfirmResponseModel>();
return new JsonResult { Data = new { status = false, message = response } };
}
and i want to return to Payment method with paymentObject if it is valid but PaymentModel is returning null data and it is showing the error as
This request has been blocked because sensitive information could be disclosed to third party web sites when this is used in a GET request. To allow GET requests, set JsonRequestBehavior to AllowGet
Have you tried passing allowget to your return variable?
i.e:
return Json( new { status = false, message = response }, JsonRequestBehavior.AllowGet);
Hope this helps.

RestSharp calling WebAPI with Thinktecture AuthenticationConfiguration

I am using Restsharp within an MVC app, trying to call a backend MVC WebAPI protected by Thinktecture IdentityModel AuthenticationConfiguration.
MVC API Setup
My MVC API test is setup with the below:
private static void ConfigureAuth(HttpConfiguration config)
{
var authConfig = new AuthenticationConfiguration
{
DefaultAuthenticationScheme = "Basic",
EnableSessionToken = true,
SendWwwAuthenticateResponseHeader = true,
RequireSsl = false,
ClaimsAuthenticationManager = new AddCustomClaims(),
SessionToken = new SessionTokenConfiguration
{
EndpointAddress = "/token",
SigningKey = Convert.ToBase64String(CryptoRandom.CreateRandomKey(32)),
DefaultTokenLifetime = new TimeSpan(1, 0, 0)
}
};
authConfig.AddBasicAuthentication((username, password) =>
{
return username == "admin" && password == "password";
});
config.MessageHandlers.Add(new AuthenticationHandler(authConfig));
}
private static void ConfigureCors(HttpConfiguration config)
{
var corsConfig = new WebApiCorsConfiguration();
config.MessageHandlers.Add(new CorsMessageHandler(corsConfig, config));
corsConfig
.ForAllOrigins()
.AllowAllMethods()
.AllowAllRequestHeaders();
}
Javascript works OK
I know 100% the token I am sending with Restsharp is correct and working with equivalent json calls (the token used in the javascript is the same used in the Web MVC controller as its stored in the Session array):
var authToken = config.authToken,
baseUri = config.baseUri,
configureRequest = function (xhr) {
xhr.setRequestHeader("Authorization", "Session " + authToken);
},
errorHandler = function (xhr, status, error) {
if (xhr.status === 401 && config.onAuthFail) {
config.onAuthFail(xhr, status, error);
}
};
Calling the API from my MVC web front end client app - Authorization has been denied for this request
Then in my MVC app controller action i use RestSharp as follows:
public ActionResult Test()
{
var token = Session[Constants.SessionTokenKey] as string;
var client = new RestClient(new Uri("http://localhost:65104/"));
var request = new RestRequest("contacts", Method.GET);
string authHeader = System.Net.HttpRequestHeader.Authorization.ToString();
request.AddHeader(authHeader, string.Format("Authorization Session {0}", token));
var json = client.Execute(request);
// break point here checking the status it has been denied
return View("Index");
}
Checking the status, it returns "{\"message\":\"Authorization has been denied for this request.\"}".
I have tried adding the token with Restsharp request methods with request.AddHeader(authHeader, string.Format("Authorization Session {0}", token)); and also with request.AddHeader(authHeader, string.Format("JWT {0}", token));, but get the same access denied for both ways.
What am I doing wrong please or any recommendations on where to look?
Looks like your JavaScript code and RestSharp request code doesn't match.
In JS you set a header with name Authorization and give it a value Session sometoken:
xhr.setRequestHeader("Authorization", "Session " + authToken);
In RestSharp you assign a header with name Authorization a value Authorization Session sometoken
request.AddHeader(authHeader, string.Format("Authorization Session {0}", token));
So I would suggest changing your RestSharp AddHeader code to this:
request.AddHeader(authHeader, string.Format("Session {0}", token));

Resources