-
-
Notifications
You must be signed in to change notification settings - Fork 746
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refit doesnt allow constant variable from another class ? #263
Comments
try using the following public interface APIService
{
[Post("/index.php?route=mobile%2Flogin")]
Task<string> login([Body(BodySerializationMethod.UrlEncoded)] Dictionary<string, string> userInfo);
[Post("/index.php?route=mobile%2Faccount%2Fregister")]
Task<string> register([Body(BodySerializationMethod.UrlEncoded)] Dictionary<string, string> userInfo);
[Get("/index.php?route=mobile%2Faccount%2FforgotPassword")]
Task<string> forgotPassword(String email);
} |
This is a weird one. Shouldn't the const get inlined at compile time? I'm assuming you get the same error if you redefine the const as a static readonly string? |
@skoon the problem isn´t with the const string but what is in it. what a Refit isn´t handling well is the and
is definately not allowed as reference in Attribute annotations but |
@Cheesebaron correct me if i´m wrong String a = "a";
string b = "b";
var c = a + b;
a.Should().BeOfType<string>();
a.Should().BeOfType<String>();
b.Should().BeOfType<string>();
b.Should().BeOfType<String>();
c.Should().BeOfType<string>();
c.Should().BeOfType<String>();
//i.e
(a is String).Should().BeTrue();
(a is string).Should().BeTrue();
(b is String).Should().BeTrue();
(b is string).Should().BeTrue();
(c is String).Should().BeTrue();
(c is string).Should().BeTrue();
|
@ahmedalejo you are right, I didn't think it through :) As for the issue, why is it that the paths are not valid? Is it a limitation of Refit? Because Uri seems to support it just fine?
But I would guess Refit does some parsing of the URL before making it into something passed to the HttpClient. This logic does not understand the unescaped |
@Cheesebaron you are right, as well :) it seems like a Refit limitation to handle as the following link from Gmail to this issue implies. i trimmed out some personal info from the Url but you get the point. |
It works if I write directly into Post or Get annotations. But when I want to write as a variable it throws the above error. |
Yeah, the ReFit examples show unescaped slashes and I've used unescaped slashes when I've used the library in projects. Which is why I wondered if changing it to static readonly had the same effect. The main difference being that static vars are looked up at runtime while const values are inlined where they are used at compile time. So it could be that there is something going on with the const value NOT getting inlined into the attribute definition at compile time. Which would be weird. |
Also this happens at compile time, not runtime. So a static readonly won't work at all since attributes don't allow them 🤦 |
Since 2.0, Refit generates implementations of the interfaces at build time (mostly for iOS support, IIRC). The reason constants aren't inlined is that the generation is done my interrogating the abstract syntax tree for the interface. We use a few assumptions to verify the method definitions have the correct attributes, and supporting constants in the URL templates would make things difficult (the constant may be defined in another file, for example) which would have meant a significant rewrite of the generator code. (I believe it would need to change to using semantic analysis instead.) Someone is welcome to look into it and submit a PR, but it could be a lot of work for a fairly uncommon use case. (In a couple of years since v2, this is the first time I think it's been raised as an issue). ☺ |
@bennor it's not just for iOS that we do compile-time code gen, it's also for the WinRT/UWP platforms as well. |
It compiles for all platforms Generated in the
|
Yeah, I know how it works 😂 I was referring to why the change was made from runtime method interception in 2.0. Was originally for iOS but then we added support for WinRT. |
I'm happy calling it that we shouldn't support this, constants aren't supported in default variable values in C# signatures, up to and including version 8 (you can't specify a default string value as |
@benjaminhowarth1 The original request was for constant values to work in attribute parameters, which is something .NET supports. The problem is more about how we generate the code from the interfaces. There are a whole class of issues that relate to the fact that we do syntax analysis on the project only, as opposed to semantic analysis factoring in the whole solution. Changing over would be a big change and may have some serious implications for performance. |
Ah, I didn't realise, thanks! Interface inheritance also has issues around this, right? |
Yeah. There are a few others too. I've tagged them with the |
Hi! Why do we need these constants? At a minimum, to avoid code duplication (In my case) public bool HasRefitHttpMethodAttribute(MethodDeclarationSyntax method)
{
// We could also verify that the single argument is a string,
// but what if somebody is dumb and uses a constant?
// Could be turtles all the way down.
return method.AttributeLists.SelectMany(a => a.Attributes)
.Any(a => HttpMethodAttributeNames.Contains(a.Name.ToString().Split('.').Last()) &&
a.ArgumentList.Arguments.Count == 1 //&&
//(
//a.ArgumentList.Arguments[0].Expression.Kind()
//== SyntaxKind.StringLiteralExpression
//)
);
} public const string RestService_ConstString_Path = "/const";
public interface IRestService_ConstString_Api
{
[Get(RestService_ConstString_Path + "/a")]
Task Get();
}
[Fact]
public async Task RestService_ConstString_Test()
{
var mockHttp = new MockHttpMessageHandler();
var settings = new RefitSettings
{
HttpMessageHandlerFactory = () => mockHttp
};
mockHttp.Expect(HttpMethod.Get, "http://httpbin.org" +
RestService_ConstString_Path + "/a")
.Respond(HttpStatusCode.OK);
var fixture = RestService.For<IRestService_ConstString_Api>(
"http://httpbin.org/", settings);
await fixture.Get();
mockHttp.VerifyNoOutstandingExpectation();
} |
Should be implemented in #1029 |
Please try v6.0-preview.84 and file bugs as you come across them. |
This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
How to define a constant variable for path "index.php?route=mobile" ? I defined in another class a constant variable.
Config.cs
APIService.cs
But refit throws an error like this :
System.NotImplementedException: Either this method has no Refit HTTP method attribute or you've used something other than a string literal for the 'path' argument.
Full part of my service interface :
The text was updated successfully, but these errors were encountered: