I saw it in this blog post, but that doesn't actually say how to "enable" it. And it seems that by default it isn't enabled.
I know it's an extension method, as defined here: http://msdn.microsoft.com/en-us/library/hh835786(v=vs.108).aspx but how do I get access to it? If I type Request.CreateErrorResponse then the compiler doesn't recognize it.
I'm already using System.Net.Http.
I've noticed this in release version as well. And if you don't have the right using statement, it'll error. You need :
using System.Net.Http;
even if you already have this:
using System.Web.Http.Controllers;
Are you still using pre-release or release version? There were a number of extensions that did not appear until just before the release and did not exist in earlier versions of the webapi release. I am unsure if this was one of them, but it may be what is causing your problem.
Request is the public property of the ApiController class and should be available to you in any API actions in that controller.
public abstract class ApiController
{
...
public HttpRequestMessage Request { get; set; }
}
Here is a small code sample that works for me:
using System.Net;
using System.Net.Http;
using System.Web.Http;
public class MyFirstApiController : ApiController
{
// GET
public HttpResponseMessage Get(int id)
{
return Request.CreateErrorResponse(HttpStatusCode.ExpectationFailed, "Some message here");
}
}
Interestingly enough, if I take away using System.Net.Http; statement, Request no longer has a CreateErrorResponse() method.
Although important points have been answered.
One more dumbest possibility is that you might have chosen wrong type of controller.
Make sure you have created an Web API controller, incase of MVC controller you cannot have
Request.CreateErrorResponse()
Just another possibility where you may find this issue.
In .net core, add Microsoft.AspNetCore.Mvc.WebApiCompatShim.dll .
https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httprequestmessageextensions.createerrorresponse?view=aspnetcore-2.0
Use System.Web.Http assembly.
source: CreateErrorResponse Method
you can use from that In block Try-Catch.
[HttpGet]
public HttpResponseMessage DownloadVideo(Guid id, string title)
{
try
{
//Your Code at the end return result
}
catch (Exception ex)
{
return Request.CreateErrorResponse(HttpStatusCode.NotFound, ex.Message);
}
}
Inject and instance of the HttpRequestMessage in your controller constructor or method:
Task<ActionResult<GetOneShopDtoResponse>> GetOne(HttpRequestMessage request,int shopId) {
return request.CreateErrorResponse(.....)
}
My best guess is that it is the third assembly, that you haven't referenced, that is the problem.
Unfortunately I don't have access to my computer, browsing on my phone, so I can't track down the file for you. According to the docs it should be in System.Web.Http.SelfHost.dll, so I guess you could just search for that file to locate it.
Related
My controller for one of my WebAPIs was working perfectly yesterday, but today I made some changes to projects outside of the actual controller code and now the API is not posting correctly. This is my code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Markup;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
namespace SanTool_WebAPI.Controllers
{
[ApiController]
[Route("[controller]")]
public class GeneratorStatusController : ControllerBase
{
static List<string> strings = new List<string>()
{
"value0", "value1", "value2"
};
[HttpGet]
public List<string> GetValues()
{
return strings;
}
[HttpPost("{input}")]
public List<string> Post(string input)
{
strings.Add(input);
return strings;
}
}
}
When I run the code using IIS explorer, and then navigate to https://localhost:44312/GeneratorStatus/, it displays my [HttpGet] correctly (displays the three strings), but when I try to use the post request with, https://localhost:44312/GeneratorStatus/2, it gives me error 405 and doesn't return the string
If you are just changing the URL in chrome this would be the problem. 405 often will mean that you are using the wrong http request type. When just changing the URL browsers issue a GET request to that resource.
You may want to test that same POST method with Postman.
Also see: Asp.Net Core 3.1 405 Method Not Allowed
First thing first.
I could be wrong here, but https://localhost:44312/GeneratorStatus/2, is something I would only use when I am getting things. In my experience, I have never seen a POST URL that looks like that.
Second,
I think, you are doing the Post wrong. First Up, I hope you are using Postman or curl to test your endpoints.
your POST would be something like this.
URL - If I am POSTing, the URL would be
https://localhost:44312/GeneratorStatus
with the Post Body, in your case, is a simple string, would look something like this.
{
input : "some input value"
}
Your Controller should probably look like this.
[HttpPost]
public List<string> Post(string input)
{
strings.Add(input);
return strings;
}
I'm familiar with PHP and JS, as well as MVC methodology, but I'm completely new to C# and have spent time looking for the documentation on this specific error.
I used dotnet new mvc to create a working app on port 5000. Also note, I am working in the Controller, not the model or view:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using ExelonPrime.Models;
namespace OptimusPrime.Controllers{
public class ApiController : Controller
{
public void Help_Pdf()
{
Response.Write("test");
}
}
}
And the error I get (when trying to compile) is:
error CS1061: 'HttpResponse' does not contain a definition for 'Write' and no accessible extension method 'Write' accepting a first argument of type 'HttpResponse' could be found (are you missing a using directive or an assembly reference?)
If I'm missing a using directive, which one is it? I tried System.Web and that didn't work. How do I make this work?
I would recommend following through microsofts tutorial on using asp.net core.
https://learn.microsoft.com/en-us/aspnet/core/tutorials/first-mvc-app/?view=aspnetcore-2.2
As far as this specific instance, rather than using Response.Write, I would do this
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using SampleWeb.Models;
namespace SampleWeb.Controllers
{
public class ApiController : Controller
{
[HttpGet]
public ActionResult<string> Help_Pdf()
{
return "test";
}
}
}
This specific sample might be helpful.
With this class, the url https://localhost:5001/api/Help_Pdf returns "test"
In ASPNET Core, when writing an API, it's more common to return an object, or POCO in stead of directly writing to the response stream (although it indeed is possible)
try changing your
public void Help_Pdf()
{
Response.Write("test");
}
to
[HttpGet()]
public IActionResult Help_Pdf()
{
return Ok();
}
this will return an 204 (no content), you can pass data however, to the OK function, to add a body to the response object.
If your trying to write directly to the response stream like that, you can do this:
public async Task Help_Pdf()
{
await Response.WriteAsync("Test");
}
However, I'd recommend not doing this in your actual app, the method should return an IActionResult. IMO it's not good practice to write directly to the stream in your controller methods (not very test friendly).
My goal is to search by last name within a GET call that will be used on the back-end. I have Get() and Get(int id) working perfectly fine, though I have spent a while tring to get SearchByLastName(string name) working but cannot. Here is the function within my controller
// GET
[Route("api/member/byLastname/{id}")]
public IHttpActionResult SearchByLastName(string id)
{
var member = _context.Members.SingleOrDefault(m => m.LastName == id);
if (member == null)
{
return NotFound();
}
return Ok(member);
}
I can't for the life of me figure out why this doesn't work when the other Get functions do and the routes look correct here.
the call I am making in this situation would look something like this:
http://.../api/Member/byLastName/Smith
Any ideas?
Wow I spent over an hour trying to find an answer and I get one right after I post this question. Sorry for that. Anyways the answer is that it is convention to use the verb Get as prefix within the name. I changed mine to GetLastName(string id) and it works now
Instead of using Route[""] I recommend always using the verb, it's support routing, so instead of
[Route("api/member/byLastname/{id}")]
you can do
[HttpGet("api/member/byLastname/{id}")]
HttpGet attribute is on Microsoft.AspNet.Mvc namespace
Hopefully someone can help me with this, because Sitefinity support appears to be stumped and the community on the G+ page seems stumped also.
I have a dead simple MVC widget:
Controller [~/Mvc/Controllers/TestWidgetController.cs]:
using System.Web.Mvc;
using Telerik.Sitefinity.Mvc;
namespace SitefinityWebApp.Mvc.Controllers
{
[ControllerToolboxItem(Name="TestWidget", Title="Test widget", SectionName="Test section")]
public class TestWidgetController : Controller
{
public ActionResult Index()
{
return View();
}
}
}
Model [~/Mvc/Models/TestWidgetModel.cs]:
namespace SitefinityWebApp.Mvc.Models
{
public class TestWidgetModel
{
}
}
View [~/Mvc/Views/TestWidget/Index.cshtml]:
<p>Test</p>
If I take the controller, the model and the view and drop them into a new Sitefinity project, and then build that project, the widget gets registered automatically without any problems and I can use it right away.
However, I have one specific Sitefinity project that I want to drop this widget into, and that project when built does not register the widget automatically. If I try to register the widget manually I get NullReference exceptions. It's like the project doesn't actually see those files somehow.
Does anyone have any idea what could be going on here? I think the simplicity of the widget and the fact that it works in a new Sitefinity project indicates that it's definitely something wrong with the way this particular project has been configured, but I can't figure out what the problem is.
For what it's worth here's the Solution Explorer for the problematic project:
You need to tell that the controller the page which is returned. Based on the file directory, it is Index.cshtml Therefore:
using System.Web.Mvc;
using Telerik.Sitefinity.Mvc;
namespace SitefinityWebApp.Mvc.Controllers
{
[ControllerToolboxItem(Name="TestWidget", Title="Test widget", SectionName="Test section")]
public class TestWidgetController : Controller
{
public ActionResult Index()
{
return View("Index");
}
}
}
It is now possible to have MVC widget in a separate assembly that automatically registers itself to the toolbox.
Check this doc for more info
Could you try to rename the controller and it toolbox name? Sometime Sitefinity works funny
It seems that you are having an issue regarding the widget registration in the controller store. Since most probably this issue is caused by problems related to this specific project it is highly advisable that you go and open a support ticket to the Sitefinity support system. By doing so your project can be inspected in more details and the most appropriate actions will be recommended.
Apart from that would you please point out the version of your SItefinity project? It will definitely help in the problem investigation.
Also there is an error log file which can be found at ~\App_Data\Sitefinity\Logs. Check and see what is logged there. This can give a clue about what is causing the issue and where to look at for possible solutions.
Regards,
Desislav
I am trying to use Mike Wallace's "RequireHttps" attribute to force certain controllers to require SSL or not.
I have the code below, and it builds fine. But when I actually go to add the attribute to the controller, it fails.
I have other custom attributes that appear, and I have another that doesn't. So it might be a project issue, though I tried a new project and it still failed. The code is in the app_code folder.
using System;
using System.Net.Http;
using System.Web.Http.Filters;
using System.Web.Http.Controllers;
namespace WebAPIService
{
public class RequireHttpsAttribute : AuthorizationFilterAttribute
{
public RequireHttpsAttribute();
public override void OnAuthorization(HttpActionContext actionContext)
{
if (actionContext.Request.RequestUri.Scheme != Uri.UriSchemeHttps)
{
actionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.Forbidden)
{
ReasonPhrase = "HTTPS Required"
};
}
else
{
base.OnAuthorization(actionContext);
}
}
}
}
Any suggestions are welcomed. Thanks.
EDIT:
The error I get on the API Controller is:
The type or namespace name 'RequireHttpsAttribute' could not be found (are you missing a using directive or an assembly reference?)
You can just put your RequireHttpsAttribute.cs file in a different folder than App_Code, which is a special ASP.NET folder. Your namespace import should function correctly, then. If your project is a website project, converting it to a web app might also solve the problem.
If you want to learn more about the issue, I recommend you take a look at Type or namespace could not be found from App_code folder.